LabHub
学习 学习路径 课程

CCA — Cilium 认证助理

在扩集群之前必须做完的设计

在 LabHub 中继续学习

一句话总结

ClusterMesh 通过同步多个集群的 identity 与 service,维持与单集群相同的策略模型。但 CIDR 与 CA 设计日后几乎无法更改,因此必须在一开始就确定。

概念图: 与单集群相同的策略模型 · 不在 dataplane 增加额外 hop · 每个集群都需要唯一名称和 ID(1~255) · PodCIDR 与节点 IP 网段不能重叠。

为什么需要它

当集群数量达到两个以上,问题会立刻出现:区域故障时能否切换到其他集群?跨集群调用能否应用相同的安全策略?也可以通过 service mesh 解决,但这样会再增加一层 proxy。

ClusterMesh 采用不同的方法:它不在 dataplane 增加额外 hop,只连接 control plane。每个集群通过 clustermesh-apiserver 暴露自己的 service、identity 和 endpoint,对端集群的 agent 则 watch 这些信息。同步完成后,packet 仍按现有路由模式直接传输,既没有中央 gateway,也没有单点故障。

工作原理

前提条件本身就是设计决策。

同步对象包括 service(标记为 global 的服务)、identity 和 ipcache。关键在于identity 跨越边界后仍保持相同含义。集群 B 中 app=backend Pod 的 identity 也会传播到集群 A 的 ipcache,因此 multi-cluster 策略能够使用与单集群完全相同的 label 语法。

Global service 通过 annotation 创建。

annotation 行为
service.cilium.io/global "true" 汇总跨集群 backend
service.cilium.io/affinity local 优先本地 backend,本地全部失效时使用远程
service.cilium.io/affinity remote 优先远程(drain、canary)
service.cilium.io/affinity none 在所有集群间均匀分配

实际工作的标准选择是 affinity: local。正常情况下在集群内部处理以降低 latency,当本地 backend 全部 unhealthy 时再切换至远程。但这里有一项隐藏依赖:“unhealthy 判定”基于 readiness。 如果 readinessProbe 设计粗糙,例如只要进程存活就判定为 Ready,那么实际已经故障的 backend 会一直保持 Ready,failover 也不会发生。粗糙的 readinessProbe 只会得到粗糙的 failover。

策略方面也有一项陷阱。在 ClusterMesh 环境中,如果 label selector 省略 io.cilium.k8s.policy.cluster两个集群中具有相同 label 的 Pod 都会被匹配。 原本希望“DB 只能由本集群的应用访问”,结果却连远程集群的同名工作负载也一并开放,这类事故就源于此。

还有几项运维规则。互联集群间的 Cilium version skew 最多只支持相差一个 minor 版本,因此原则是“逐个集群升级,在所有集群达到同一版本前,不进入下一个 minor 版本”。移除集群时,应先清理 global service 依赖。如果某个服务通过 affinity: none 依赖远程 backend,disconnect 的瞬间 backend 数量就会减少。此外,即使 clustermesh-apiserver 故障,流量仍会继续使用已经同步的 service 与 identity。 停止的只是新变更的传播。

External Workloads 功能会在 VM 或 bare metal 上安装 agent,使其加入集群。这些工作负载也会获得 identity,因此可以应用同一套基于 label 的策略。

现场会遇到的情况

作者的家庭实验室目前仍是单集群,但从 3 个节点扩展到 7 个节点时,获得了完全同类的教训

控制平面扩展到三台、拥有三个 etcd member 后,原以为已经实现 HA,实际却并非如此。kubeadm-config 中的 controlPlaneEndpoint 不是 VIP 或 DNS,而是 cp-1 的物理 IP 10.0.0.120。该地址写入了 7 个节点的 kubelet 配置、所有 kubeconfig,以及 apiserver 证书 SAN。一旦 cp-1 故障,etcd quorum 仍是正常的 2/3,其他 apiserver 进程也正常运行,却会陷入无人能找到入口的状态。

这个案例与 ClusterMesh 设计完全对应:control plane 的数据可用性与访问可用性是两个不同问题;endpoint、CIDR、CA 等值,是少数几项在集群创建后极难更改的设置。因此,即使当前只计划使用一个集群,预先确保 PodCIDR 不重叠并完成 CA 设计,也是在帮助未来的自己。同一家庭实验室中的 WireGuard 加密显示 Peers: 2,节点间 tunnel 使用端口 51871;这种传输加密层也能以相同方式扩展到集群之外。

下一项测验要确认什么

ClusterMesh 至少需要两个集群才能实验,因此本模块以概念与测验结束。请检查集群 ID 范围、CIDR 与 CA 前提、global service affinity 对 readiness 的依赖,以及策略遗漏 cluster label 时的陷阱。