website

Mohuishou

所属分类:技术博客与个人站

持续整理 Go 工程实践、Kubernetes 与 Operator 开发系列

Mohuishou 是一个以 Go 工程实践与 Kubernetes 为主题的中文技术博客,提供 Go 系列、Kubernetes 系列、归档和关于等入口。站内 kubebuilder 专题覆盖 Operator 概念、开发环境、资源增删改查、状态与事件、测试、Webhook 和源码分析。本文围绕《如何实现支持多集群的 Kubernetes Operator?》介绍其讨论的问题模型:主集群中的自定义资源如何驱动控制器在多个集群中协调工作。

Mohuishou:从单集群控制器走向多集群 Kubernetes Operator(lailin-multicluster-operator)

发布于 2026年10月21日更新于 2026年10月27日

为什么需要多集群控制器

Operator 通常围绕 Kubernetes 自定义资源构建控制循环。用户提交一个资源对象,控制器观察期望状态并执行必要操作,让集群实际状态逐步接近声明目标。在单集群环境中,控制器和被管理资源位于同一个 API Server,开发者可以围绕一个客户端和一套权限关系设计逻辑。

当组织将应用拆分到多个 Kubernetes 集群后,控制面会复杂一些。集群可能因为权限、规模、环境隔离或管理边界而分开。一个中心化的自定义资源仍可能表达希望多个集群共同执行的任务,因此需要确定由哪个集群保存期望状态、控制器如何连接其他集群,以及每个目标集群中的执行结果如何被观察。

Mohuishou 的文章用 main 和 sub 两个集群作为示例:main 集群中保存一个自定义资源,该资源表达创建 Job 的意图;控制器观察到资源后,要在 main 与 sub 集群中分别创建相应 Job。这个简化模型能帮助读者把讨论聚焦在控制器如何连接多套 Kubernetes API,而不是被更完整的多集群治理系统的其他能力分散注意力。

Mohuishou 博客首页展示 Kubernetes 与 Go 工程系列文章

先明确资源的归属

实现前需要明确自定义资源放在哪个集群,以及哪个控制器负责协调。示例采用主集群保存 CRD 与期望状态,控制器从主集群读取对象,并将对应任务投递到主集群和子集群。这样做形成一个清晰的控制入口:用户修改一个对象,控制器将意图传播到多个目标环境。

资源归属决定了权限和故障处理设计。主集群承担期望状态的存储责任,子集群则是工作负载实际运行的位置。控制器需要拥有读取主集群自定义资源的权限,也要在目标集群创建或更新对应 Job。连接信息、凭证和访问范围应按部署环境安全管理,不能假设每个集群使用相同身份或权限。

还要决定如何表示目标集群集合。示例通过两个命名集群说明基本机制;真实系统可能需要用户选择目标集群,或者由平台规则决定。无论采用哪种方式,都应让目标范围明确、可审计,并在集群加入或移除时更新控制器连接和期望状态。

Reconcile 循环与多个客户端

Kubernetes 控制器通常通过 reconcile 函数处理资源变更。每次收到事件后,控制器读取当前对象和关联状态,再对比期望与实际状态,执行创建、更新或删除操作。多集群场景下,这个过程仍然遵循协调思路,只是操作目标可能来自不同客户端。

文章以 controller-runtime 为开发背景,重点在于让控制器可以使用主集群以及子集群的 client。控制器读出主集群中的 CRD 后,为每个指定目标集群构造或同步 Job。不同客户端代表不同 API Server 的访问入口,因此需要确保请求确实发送到了预期集群,避免把子集群资源错误创建到主集群。

执行多次写入时,控制器还需要面对部分成功的情况。例如主集群创建成功而子集群请求失败,下一轮 reconcile 应能够识别已经完成的部分,安全重试未完成的目标。通过幂等的创建或更新逻辑,重复收到事件时不会产生无法控制的重复工作负载。控制器还应把目标集群的处理状态反馈到自定义资源状态或日志中,便于运维人员判断进展。

多集群 Kubernetes Operator 文章详情展示资源模型与 controller-runtime 实现

连接与故障边界

每个集群都可能独立不可用、网络延迟或凭证过期。一个集群暂时无法访问,不应让控制器丢失主集群中的期望状态。系统可以记录某个目标的同步错误,在连接恢复后重新协调。对于反复失败的目标,需要提供清楚的错误状态和观测信息,方便区分权限问题、网络故障和资源校验失败。

删除操作同样需要定义。若用户删除主集群中的自定义资源,控制器是否应删除所有目标集群中的 Job,取决于产品语义和垃圾回收策略。若目标集群失联,控制器可能无法立即执行清理,因此需要决定后续重连时如何收敛。明确这些生命周期规则,可以避免资源残留或误删其他系统创建的对象。

权限配置是另一条重要边界。主集群与子集群的访问凭证应仅授予控制器完成目标操作所需的权限,并按集群分别管理。控制器的部署位置、凭证轮换和审计也需要纳入设计。技术示例能展示 client 的使用路径,但真实环境仍要依据组织的安全要求搭建认证和授权机制。

多集群框架与直接控制的取舍

文章提及已有多集群方案,也讨论在某些权限或复杂度限制下,由 Operator 直接监听多个集群的需求。引入完整多集群框架可能带来更丰富的管理能力,但也意味着部署与运维组件增加。直接使用多个客户端则更轻量,却要求项目自行处理集群连接、错误重试、状态呈现和凭证管理。

选择方案时,团队可以先列出实际需要:控制多少集群、目标集群是否经常变化、是否需要统一服务发现、故障域如何划分,以及平台是否已有多集群管理层。对于少量、固定且由同一团队维护的集群,直接控制可能足够;当集群规模和组织边界扩大时,专门的多集群控制面可能更合适。这里不存在脱离场景的唯一答案。

用测试验证协调行为

多集群逻辑应针对各类状态组合测试。除了主子集群均可访问的成功路径,还要验证目标客户端错误、资源已经存在、创建权限不足、某一集群短暂失联以及资源被删除后的处理。测试应检查控制器能否重复执行而保持结果一致,也要确认一个目标失败时其他目标的状态仍可追踪。

Mohuishou 的博客提供了从 Operator 基础到测试和源码分析的连续学习入口。多集群文章附带示例代码仓库,读者可以沿着具体实现理解 controller-runtime 如何组织客户端和 reconcile 逻辑。由于文章发布于 2022 年,工具接口和依赖版本可能已经变化;实践前应对照当前版本文档,并在隔离的测试集群中验证设计。

整体来看,这篇文章将多集群需求具体化为一个主集群 CRD 驱动多个集群 Job 的问题,便于从资源归属、客户端组织、状态协调和权限边界逐步推导实现方案。对正在学习 Go Operator 或 Kubernetes 控制器开发的读者,Mohuishou 的系列文章提供了从概念、工具到工程实现的中文阅读路径。