4. 多集群 Service 暴露:Global Service 概念、ClusterIP 与 Headless Service 的跨集群访问、ExternalName 与 Multi-Cluster Service

在 Cilium ClusterMesh 的多集群拓扑中,Pod 网络已通过 Overlay 或 Native-Routing 实现互通,但 Kubernetes Service 的默认行为仍被限制在单个集群内。本章将深入剖析如何通过 Global Service 将 Service 边界扩展到多集群,并详细对比 ClusterIP、Headless Service、ExternalName 以及 Multi-Cluster Service API 在跨集群场景下的适用性与实现机制。

4.1 Global Service 概念与工作原理

Global Service 是 Cilium ClusterMesh 提供的核心抽象,它允许将一个 Kubernetes Service 的端点集合扩展到多个集群。其本质是在每个集群中创建一个同名的 Service,并通过 Cilium 的控制面同步机制,将远端集群的端点信息注入到本地集群的 EndpointSlice 中。

核心机制: Global Service 不依赖 DNS 重定向或全局负载均衡器,而是通过 Cilium Agent 在节点层面直接操作 eBPF 映射表,实现跨集群的 Service IP 可达性与负载均衡。

Global Service 的生效需要满足以下条件:

  • 同名同命名空间: 参与 Global Service 的 Service 必须在所有集群中具有相同的名称和命名空间。
  • ClusterMesh 已连接: 集群间必须通过 ClusterMesh 完成控制面与数据面的互联。
  • Service 注解: 需要在 Service 上添加注解 io.cilium/global-service: "true"。
最佳实践: 建议在 Global Service 上同时设置 io.cilium/shared-service: "true" 注解,以允许本地集群的 Pod 通过 Service IP 访问本地端点,避免不必要的跨集群流量。
Global Service 跨集群流量路径 集群 A (北京) 集群 B (上海) Service A (ClusterIP) Pod A1 (10.0.1.5) Pod A2 (10.0.1.6) Service B (ClusterIP) Pod B1 (10.1.2.7) Pod B2 (10.1.2.8) Cilium Agent Cilium Agent ClusterMesh 控制面同步 eBPF 负载均衡 跨集群隧道封装 关键点:Global Service 通过 Cilium Agent 同步远端端点,客户端访问本地 Service IP 即可被负载均衡到远端 Pod

4.2 ClusterIP 的跨集群访问

在启用 Global Service 后,ClusterIP 类型的 Service 可以跨集群访问。客户端 Pod 只需访问本地集群的 Service ClusterIP,Cilium 的 eBPF 程序会根据后端端点列表(包含本地和远端)进行负载均衡。

特性 单集群 ClusterIP Global ClusterIP
端点来源 仅本地 EndpointSlice 本地 + 远端 EndpointSlice
负载均衡范围 本地 Pod 所有集群的 Pod
流量路径 节点内或节点间 可能经过跨集群隧道
DNS 解析 返回本地 ClusterIP 返回本地 ClusterIP(不变)
故障转移 仅本地健康检查 跨集群健康检查与自动摘除
注意: 跨集群访问 ClusterIP 时,源 IP 会经过 NAT 转换(通常为隧道端点 IP)。如果应用需要保留客户端真实源 IP,需要配置 externalTrafficPolicy: Local,但这会限制跨集群负载均衡的效果。

4.2.1 配置示例

apiVersion: v1
kind: Service
metadata:
  name: my-global-svc
  namespace: production
  annotations:
    io.cilium/global-service: "true"
    io.cilium/shared-service: "true"
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080

在集群 A 和集群 B 中分别应用此 YAML,确保两个集群中都有匹配 app: my-app 的 Pod 运行。Cilium 会自动合并端点。

4.3 Headless Service 的跨集群访问

Headless Service(clusterIP: None)在跨集群场景下具有特殊价值。它不提供 ClusterIP 和负载均衡,而是直接返回所有后端 Pod 的 IP 列表(DNS 记录)。在 Global Service 模式下,Headless Service 的 DNS 记录会包含来自所有集群的 Pod IP。

适用场景: 有状态应用(如数据库、消息队列)需要直接发现所有集群中的实例,并自行实现客户端侧负载均衡或分片逻辑。

跨集群 Headless Service 的 DNS 解析行为:

  • A 记录: 返回所有集群中匹配 Pod 的 IP 地址。
  • SRV 记录: 返回包含端口和优先级的服务发现信息。
  • Pod 就绪状态: 只有就绪的 Pod 才会被包含在 DNS 记录中。
apiVersion: v1
kind: Service
metadata:
  name: my-statefulset-svc
  namespace: production
  annotations:
    io.cilium/global-service: "true"
spec:
  clusterIP: None
  selector:
    app: my-stateful-app
  ports:
  - port: 3306
    targetPort: 3306
性能提示: 对于大规模跨集群部署(每个集群数百个 Pod),Headless Service 的 DNS 记录可能变得非常庞大。建议使用 publishNotReadyAddresses: true 谨慎控制,或结合应用层的服务发现机制(如 Consul、etcd)进行分流。

4.4 ExternalName Service 与 Multi-Cluster Service

4.4.1 ExternalName Service 的跨集群局限

ExternalName Service 本质上是 DNS 级别的 CNAME 重定向,它不经过 Cilium 的 eBPF 数据面。在跨集群场景中,ExternalName 只能将流量引向一个外部的 DNS 名称,无法感知集群拓扑变化或实现负载均衡。

对比维度 ExternalName Global ClusterIP Headless Global
数据面参与 否(仅 DNS) 是(eBPF) 是(DNS + 直连)
跨集群端点感知 无 自动同步 自动同步
负载均衡 依赖外部 DNS Cilium 原生 客户端自行实现
典型用途 指向外部托管服务 无状态应用 有状态应用

4.4.2 Multi-Cluster Service API(MCS API)

Kubernetes 社区推出的 Multi-Cluster Service API(简称 MCS API)旨在标准化跨集群服务发现。Cilium ClusterMesh 原生支持 MCS API,提供了与 Global Service 互补的另一种抽象方式。

MCS API 的核心资源:

  • ServiceExport: 标记一个 Service 需要被导出到其他集群。
  • ServiceImport: 在其他集群中创建一个虚拟 Service,代表远端导出的服务。
MCS API 与 Global Service 对比 Global Service(Cilium 原生) Service 注解 端点自动合并 eBPF 负载均衡 MCS API(社区标准) ServiceExport CR ServiceImport CR 派生 ClusterIP Global Service 更简洁(仅需注解),MCS API 更标准化(CRD 驱动) Cilium 同时支持两种方式,推荐新项目使用 MCS API

4.4.3 使用 MCS API 的配置示例

在导出端集群创建 ServiceExport:

apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
  name: my-app-svc
  namespace: production
spec: {}
# 无需 spec,只需声明导出即可

在导入端集群创建 ServiceImport:

apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceImport
metadata:
  name: my-app-svc
  namespace: production
spec:
  type: ClusterSetIP
  ports:
  - port: 80
    protocol: TCP
MCS API 优势: 提供厂商中立的跨集群服务抽象,不绑定特定 CNI 实现。Cilium 作为 MCS API 的参考实现之一,提供了完整的支持。

4.5 跨集群 Service 选型决策

根据不同的应用场景,选择合适的跨集群 Service 暴露方式:

应用类型 推荐方式 理由
无状态 Web 服务 Global ClusterIP 自动负载均衡,无需修改应用代码
有状态数据库集群 Global Headless 客户端直接发现所有实例,自行实现读写分离
需要标准化跨云 MCS API + ClusterSetIP 厂商中立,便于多云迁移
指向外部系统 ExternalName 仅 DNS 重定向,不涉及跨集群数据面
需要保留客户端源 IP Global ClusterIP + Local 牺牲部分负载均衡能力,换取源 IP 透传
运维提醒: 跨集群 Service 的故障排查比单集群复杂。建议在 Global Service 上配置 io.cilium/global-service: "true" 的同时,开启 Cilium 的监控指标(cilium monitor 或 Hubble),实时观察跨集群流量的分布与健康状态。