DR 容灾Active / Standby Controller 协同
Active / Standby 上的 Controller 协同
主备协同主题入口
Active / Standby 上的 Controller 协同
在 ACP 的 Global + 业务集群(行业里常说的 Hub-Spoke)形态上叠加 Active + Standby 容灾后,Global 集群上的 Controller / Operator 同时存在两个角色:
- Active Global:正常下发,写入 Global 自己的 etcd
- Standby Global:本质是 Active 的镜像副本,其 etcd 内容由 etcd-sync 单向覆盖
如果 Standby Global 上的 Controller 仍按平时那样 reconcile,写入会被 Active 同步过来的状态覆盖,造成抖动甚至循环冲突。本主题给出在自己写的 Controller / Operator 里如何"在 Standby 期间安全停手、Active 期间正常工作"的标准做法,以及哪些资源需要 Active→Standby 单向同步。
总体架构
要点:
- Active Global 上 Controller 正常工作;Standby Global 上 Controller 通过 drsyncgate 主动短路,让出对象给 etcd-sync
- 角色信号是
kube-public/etcd-syncConfigMap,与 encryption 主题 共用 - 业务集群的 reconcile 只在 Active 一侧发生,避免双写
文档地图
| 角色 | 该读哪一篇 |
|---|---|
| 维护或新写 Global 集群上的 Controller / Operator | controller-integration-handbook.md |
| 设计自己 CRD 的同步策略 | sync-resource-spec.md |
适用判定
逐条问自己;任意一条命中就需要接入:
| 问题 | 命中含义 |
|---|---|
| 我的 Controller 是否运行在 Global 集群上 | 进入 DR 视野,需要判断角色 |
| 我的 Controller 是否会写入 Global 集群自身的 etcd 资源 | Standby 期间这些写入会被 etcd-sync 盖掉 |
| 写入对象是否在 etcd-sync 的同步集合内 | 落在同步集合内的资源,必须按 Active 单边写入 |
| 我的 Controller 是否依赖某个对象状态做长链路决策 | Standby 期间该对象正在被覆盖,决策不可靠 |
不满足任何一条的(例如:纯查询型、只读 metric、只写 spoke 集群)通常不需要 gate。
一页速查
| 项目 | 取值 |
|---|---|
| 角色信号 | kube-public/etcd-sync ConfigMap |
| 信号语义 | 存在 ⇒ 当前为 Standby,etcd-sync 正在写入;不存在 ⇒ Active |
| 推荐库 | astrolabe/pkg/drsyncgate |
| 入口函数 | drsyncgate.IsRunning(ctx, reader) (bool, error) |
| Grace period | 60 秒(marker 消失后 60 秒内仍按 Standby 处理) |
| 推荐 requeue | 30 秒 |
| 推荐豁免 | Global 集群自身的 cluster-scoped 资源(例如 cluster name 等于 global 的对象) |
完整字段见 etcd-sync-dynamic-configmap-migration/provider-spec.md 中的"发现契约"与"状态回写"。
与其他主题的关系
- 与 etcd-encryption-deterministic-key 共享同一个 marker;加密层做角色判定时也读
kube-public/etcd-sync,行为一致 - 本主题不重复 etcd-sync 的接入规范;规则字段、状态 annotation、失败语义都参考
etcd-sync-dynamic-configmap-migration/provider-spec.md