编程 Cilium Cluster Mesh 多集群实操:启用流程、Global Service 与 Native Routing 注意点

2026-09-09 00:04:23

Cilium Cluster Mesh 多集群实操:启用流程、Global Service 与 Native Routing 注意点

Cilium Cluster Mesh 把多个以 Cilium 为 CNI 的 Kubernetes 集群在网络上组成统一网格,跨集群 Pod 可以像同集群内一样直接通信。相比 Istio 多集群方案,它工作在更底层的网络层,基于 eBPF 转发,性能开销更低。

工作方式与故障域边界

每个集群仍然维护自己的 etcd,状态不混。集群通过 clustermesh-apiserver 对外提供配置,该组件内部包含两个容器:apiserver 负责写入集群信息,etcd 容器作为代理暴露给其它集群。对端集群的 Cilium Agent 连接这个 etcd 代理来监听本集群的变化。

关键点是跨集群访问始终是只读的,所以一个集群的故障不会通过状态同步扩散到其它集群。

启用 Cluster Mesh

以 kind 两个集群 kind-c1kind-c2 为例:

cilium clustermesh enable --create-ca --context kind-c1 --service-type LoadBalancer
cilium clustermesh enable --context kind-c2 --service-type LoadBalancer
cilium clustermesh connect --context kind-c1 --destination-context kind-c2

--create-ca 只在第一个集群上执行。两个集群必须共享同一组 CA 证书,否则 mTLS 建立不起来。

启用前需要满足几个条件:

  • 每个集群分配唯一的 cluster.id(范围 1-255)和 cluster.name
  • Cilium 使用 etcd 作为 KV 存储
  • 集群之间的网络必须互通

全局 Service 与本地优先

要让 Service 在 Cluster Mesh 内做跨集群负载均衡,给它加上注解:

apiVersion: v1
kind: Service
metadata:
  name: demo
  namespace: default
  annotations:
    io.cilium/global-service: "true"
    service.cilium.io/affinity: local
spec:
  selector:
    app: demo
  ports:
    - port: 80

前提是两个集群中 Service 的名称和命名空间必须完全一致。加注解后,从任一集群访问该 Service,流量会自动分发到两边集群的后端 Pod。

如果希望跨集群场景下的流量尽量留在本地,用另一个注解控制亲和性:

service.cilium.io/affinity: local|remote|none

设为 local 时,全局 Service 优先在健康的本地后端之间负载均衡;只有当本地后端全部不可用时,才会把请求转发给远程端点。这个策略主要用来避免跨集群远程调用带来的额外延迟。

跨集群网络策略

Cluster Mesh 场景下的跨集群访问控制需要用 CiliumNetworkPolicy。它支持通过集群标签精确选择来源和目标,例如只允许 cluster1 中带 x-wing 标签的 Pod 访问 cluster2 中带 rebel-base 标签的 Pod。这类策略使用 io.cilium.k8s.policy.cluster: cluster1 之类的标签来匹配流量来自哪个集群。

这里有两点容易踩:

  • Kubernetes 原生 NetworkPolicy 不会自动同步到所有集群,必须在每个集群都部署相同的策略
  • 如果策略没有放行 DNS 流量,跨集群通过 Service 域名访问会直接失败

数据路径与 Native Routing 的代价

跨集群流量在数据包进入 Pod 网络接口时就开始处理。在 veth-pair 的 tc ingress hook 上,Cilium 直接把 Global Service 的 IP 转换为最终目标 Pod 的 IP。

数据路径支持隧道(Tunneling)和原生路由(Native Routing)两种模式。如果选择 Native Routing,先决条件比较严格:

  • 各成员集群内部网络模式必须是 Native Routing
  • 所有集群的 PodCIDR 必须被 ipv4NativeRoutingCIDR 覆盖
  • 任何目标地址不在该 CIDR 范围内的流量,会被 Cilium 做 SNAT,伪装成节点 IP 发出

大规模流量下,SNAT 涉及 conntrack 表维护和地址转换,会带来明显的性能损耗,这是原生路由模式下最需要关注的取舍。

另外,底层网络必须具备直接处理 Pod 到 Pod 流量的能力。如果需要跨集群路由,可以将各集群的 Cilium Agent 作为 BGP Speaker,向路由反射器宣告各自集群的 PodCIDR。

参考

  • 项目:https://github.com/cilium/cilium
  • 文档:https://docs.cilium.io/en/stable/network/clustermesh/
复制全文 生成海报 cluster mesh cilium kubernetes 多集群 eBPF

推荐文章

程序员茄子在线接单