DR 产品化 · etcd-sync 动态规则治理

从集中式 sync-key-cm 迁到产品自管 ConfigMap

这份页面面向两类读者:要做迁移的产品,以及要读取契约、编排自动化、生成规则模板的规则提供方与 Agent。 页面把迁移路径、治理模型、优先级语义、状态机、示例和排障矩阵放进同一份视觉化文档。

启用标签 enabled etcd-sync.cpaas.io/enabled: "true"
优先级 weight etcd-sync.cpaas.io/weight
共享快照 snapshot etcd-sync-rule-snapshot
默认来源 baseline etcd-sync-ignore-text
默认规则来源 + 产品规则来源
            |
            v
      统一发现与排序
            |
            v
        snapshot.json
         /         \
        v           v
    mirror      monitor
Overview

迁移结果一页读懂

变更前

  • 所有产品规则集中维护在默认规则来源
  • 新增和删除规则要修改 chart,再跟随 etcd-sync 发版
  • 产品侧缺少独立回滚和独立排障入口

变更后

  • 每个产品维护自己的 ConfigMap
  • 规则通过动态发现和排序进入统一快照
  • 状态 annotation 直接回写到源 ConfigMap
问题 当前答案 文档位置
迁移主体是谁 产品 迁移手册
契约面对谁 规则提供方 接入规范
谁决定覆盖顺序 weightnamespace/name 优先级与判定
规则状态从哪里看 源 ConfigMap annotation 状态机
Visual Map

治理地图

默认规则来源 etcd-sync-ignore-text chart 渲染,weight=0 产品规则来源 任意 namespace 的 enabled ConfigMap 产品自管,动态更新 发现与排序层 跨命名空间监听 ConfigMap 筛选 enabled label 按 weight 降序排序 同权重按 namespace/name 升序 生成 RuleSnapshot 回写 accepted / rejected / hash / processed-at 共享快照 etcd-sync-rule-snapshot snapshot.json mirror 执行同步 monitor 执行检查
Migration Playbook

迁移手册

01

盘点默认规则来源中的产品条目

先从 etcd-sync-ignore-text 或仓库内的 sync-key-cm.yaml 抽出属于本产品的条目,再按规则类型分组。

kubectl -n cpaas-system get configmap etcd-sync-ignore-text -o yaml
02

建立产品 ConfigMap

保留原有 data key,加入启用标签。普通产品规则先从 weight=0 开始,覆盖场景再提升权重。

03

观察状态 annotation

状态、消息、权重、哈希和处理时间都回写在源 ConfigMap 上。先看状态,再看功能结果。

kubectl -n <namespace> get configmap <name> -o yaml
04

做顺序验证和功能验证

顺序由 weightnamespace/name 决定。功能验证要覆盖同步命中、忽略命中、覆盖基线三类路径。

05

清理集中规则

新来源稳定处于 accepted 后,再从默认来源移除对应条目,再做一轮回归验证。

适合迁出的规则

  • 长期由产品维护
  • 变更节奏高于 etcd-sync 发版节奏
  • 和单个项目、环境、租户强相关

继续留在基线中的规则

  • 平台级公共基线
  • 所有 DR 集群都需要的默认前缀
  • 和 etcd-sync 版本一起交付的保底规则

回滚顺序

  1. 删除产品 ConfigMap
  2. 移除 enabled label
  3. 恢复上一版内容
Example Library

示例库

示例 A · 普通 prefix 同步

适合产品首次迁移,先把一组基础 prefix 从默认来源迁到自管 ConfigMap。

apiVersion: v1
kind: ConfigMap
metadata:
  name: project-a-rules
  namespace: project-a-system
  labels:
    etcd-sync.cpaas.io/enabled: "true"
data:
  sync-prefix-file.txt: |
    /registry/project.a.io

示例 B · 覆盖默认基线

适合产品需要压过默认基线时使用。重点是更高的 weight

apiVersion: v1
kind: ConfigMap
metadata:
  name: project-a-override
  namespace: project-a-system
  labels:
    etcd-sync.cpaas.io/enabled: "true"
  annotations:
    etcd-sync.cpaas.io/weight: "20"
data:
  ignore-prefix-file.txt: |
    /registry/project.a.io/tmp/
  sync-prefix-file.txt: |
    /registry/project.a.io/critical/

示例 C · 带删除语义的来源

适合某些前缀需要同步删除,同时为保留对象留出豁免通道。

apiVersion: v1
kind: ConfigMap
metadata:
  name: project-a-delete-rules
  namespace: project-a-system
  labels:
    etcd-sync.cpaas.io/enabled: "true"
data:
  sync-delete-prefix-file.txt: |
    /registry/project.a.io/releases/
  sync-delete-ignore.txt: |
    /registry/project.a.io/releases/pinned/
Contract

接入规范

发现契约

发现范围
所有命名空间
启用标签
etcd-sync.cpaas.io/enabled: "true"
优先级 annotation
etcd-sync.cpaas.io/weight
合法 weight
非负整数

状态回写

status
accepted / rejected
message
最近一次处理结果
observed-weight
实际读取到的权重
observed-hash
data 内容哈希
processed-at
处理时间

同步类

  • sync-equal-file.txt
  • sync-prefix-file.txt
  • sync-glob-file.txt
  • sync-regexp-file.txt
  • sync-kvs-file.txt

忽略类

  • ignore-equal.txt
  • ignore-prefix-file.txt
  • ignore-kvs-file.txt

删除类

  • sync-delete-prefix-file.txt
  • sync-delete-ignore.txt

预同步类

  • pre-sync-prefix-file.txt
Precedence

优先级与判定模型

跨规则层排序

weight 20 product-a/override
weight 10 product-a/common
weight 0 cpaas-system/etcd-sync-ignore-text

先按 weight 降序,再按 namespace/name 升序。首个给出明确结论的规则层直接生效。

单层判定重点

规则语义
ignore-equal.txt单层最高优先级的精确忽略
ignore-kvs-file.txt同步候选后的二次过滤
sync-delete-prefix-file.txt只影响删除事件
pre-sync-prefix-file.txt影响预同步范围,不参与单条 key 的常规判定

PUT 路径

ignore-equal sync-equal ignore-prefix sync-prefix sync-glob sync-regexp sync-kvs ignore-kvs 二次过滤 final sync / ignore

DELETE 路径

ignore-equal sync-equal ignore-prefix sync-prefix sync-delete-prefix sync-delete-ignore final delete / ignore
Lifecycle

状态机与失败语义

未选择
enabled + parse ok
accepted
update failed
rejected
later update ok
accepted
delete / remove label
卸载

失败后会发生什么

  • 未知 data key -> 当前版本 rejected
  • 非法 weight -> 当前版本 rejected
  • 非法 regexp -> 当前版本 rejected
  • 当前版本 rejected 时,上一版成功内容继续生效

内部对象的角色

  • 源 ConfigMap 是公开输入接口
  • annotation 是公开状态反馈接口
  • etcd-sync-rule-snapshot 是运行时内部对象
  • mirror 和 monitor 都从 snapshot.json 读取统一快照
Troubleshooting

排障矩阵

现象 高概率原因 先看哪里 建议动作
status=rejected data key 非法、weight 非法、regexp 非法 源 ConfigMap annotation 修正内容后重新 apply
status=accepted 但行为不符 排序顺序和预期不同 weight 与 namespace/name 先验证规则层顺序,再验证命中路径
完全看不到状态 annotation 平台侧 watcher / RBAC 问题 etcd-sync 日志 检查 ConfigMap 访问权限与日志报错
删除 ConfigMap 后旧效果短时间仍存在 informer 收敛中 运行时日志与后续状态 等待收敛后再复查
常用命令
kubectl -n cpaas-system logs deploy/etcd-sync
kubectl -n cpaas-system logs deploy/etcd-sync-monitor
kubectl -n <ns> get configmap <name> -o yaml