GitOps 持续交付与 Kubernetes 发布治理工具
一次线上修复刚用 kubectl edit 改完,几分钟后又被恢复成旧值。值班同学以为 Kubernetes 丢了配置,平台同学却看到 GitOps 控制器正在忠实地纠正漂移。真正的问题不是“谁改回去了”,而是团队从未声明 Git、CI、Helm、控制器和人工应急之间谁拥有最终写入权,紧急变更也没有回写期望状态。
GitOps 的价值不是把 kubectl apply 搬进集群,而是让声明、版本、渲染、调谐、资源清单、健康与真实业务结果形成可验证闭环。仓库提交只是起点;控制器绿色、对象 Ready、流量切换和数据正确分别需要独立证据。架构师还要回答权限放在哪里、自动删除能否停止、多集群怎样限流、管理集群丢失后怎样重建,以及工具退出时谁接管已有资源。
先认识一条持续调谐链
一条发布链至少包含九个状态:作者修改声明、评审候选、固定制品、渲染对象、目标 API 校验、控制器调谐、资源健康、业务验证和环境晋级。OpenGitOps 把声明式、版本化且不可变、自动拉取、持续调谐列为核心原则;这些原则没有承诺某个控制器的 Synced 就等于业务成功,反而要求团队持续比较期望与现实。OpenGitOps Principles
控制器状态只回答链上的局部问题。仓库可达不代表 artifact 是新版本,渲染成功不代表目标集群接受对象,apply 成功不代表 Deployment 已就绪,资源 Healthy 也不代表请求、数据迁移或 SLO 正确。第一次建立 GitOps 时,先把这些状态拆开记录,再讨论自动同步速度。
先判断团队是否已经适合持续调谐
GitOps 会持续执行已经存在的工程规则,不会替团队补齐这些规则。若制品仍用可变 tag、生产清单无法在仓库中复现、CI 和人工脚本同时写集群、紧急变更没有回写机制,控制器只会把模糊责任变成更高频的写入冲突。此时先固定制品 digest、确定唯一期望状态入口、声明对象与字段 owner,并让人工发布也产出相同证据链。
并非所有动作都适合交给持续调谐。需要交互确认的一次性数据修复、没有幂等与补偿的外部系统变更、无法声明化表达的硬件操作,以及必须在断网现场完成的应急动作,应由受控 runbook 执行,再把可持久化结果回写仓库。判断标准不是“能否写成 YAML”,而是动作能否重复执行、能否观察完成事实、能否停止和恢复,以及失败后谁承担补偿责任。
开始选产品前,用一个隔离 namespace 做最小闭环:提交一份固定 digest 的测试工作负载,保存 source revision、渲染对象 hash、控制器 observed revision、live 镜像 digest 和一次真实请求响应;随后让仓库暂时不可达,确认旧工作负载不会被误删;再制造一处人工漂移,观察 diff 与写入 owner;最后暂停调谐并撤销测试凭证。只有这四步都能解释,自动 sync、自愈和 prune 才有逐项开放的基础。
选择入口前先看团队的控制模型
进入状态证据模型与选型时,先盘点四件事:谁产生不可变制品,谁批准环境期望状态,控制器从哪里拉取,谁验证运行结果。若团队仍在生产环境重新构建源码,或者 CI 与控制器都会直接写同一对象,先收敛发布责任,再引入更多自动化。
产品选择不应从 UI 或功能数量开始:
集中管理多个集群、需要强 AppProject 边界和丰富应用视图时,进入 Argo CD 与 ApplicationSet、多集群扇出。希望每个集群自行拉取、按 Source、Kustomization、HelmRelease 拆分控制器职责时,进入 Flux CD。镜像发现和提交另看 Flux 镜像自动化。
已使用 Rancher 管理大量下游集群并需要 Bundle/target 分发时,进入 Rancher Fleet。OpenShift 团队应从 Red Hat OpenShift GitOps 的 Operator channel、平台支持矩阵和下游 Argo CD 版本链出发,不能直接套用上游安装命令。
渐进发布是另一条状态机
GitOps 控制器让期望状态持续收敛,渐进发布控制器决定新旧版本怎样同时存在、流量怎样移动、指标怎样判定。两者可以协作,但不能同时争写同一 Deployment、Service 或 Route。需要 Kubernetes 工作负载级 canary/blue-green 时,分别学习 Argo Rollouts 和 Flagger。
渐进发布至少关联五类证据:新旧 ReplicaSet、实际路由权重、请求样本、指标查询窗口、晋级或中止动作。副本比例不是流量比例,指标查询无数据不是成功,控制器自动回滚也不能修复已经执行的非幂等数据库变更。服务网格和 API 网关只提供路由执行点;发布控制器负责状态机;业务团队仍负责数据兼容与业务不变量。
仓库晋级不能复制运行态
仓库与环境晋级处理的是同一不可变制品怎样经过开发、测试和生产,而不是把测试集群 kubectl get -o yaml 的结果复制到生产。环境差异应进入显式 overlay 或 values;制品身份使用 digest 或不可变版本;晋级 PR 只改变经过验证的身份和必要环境参数。
渲染、Diff 与发布前验证把本机 Helm/Kustomize 输出、结构校验、策略检查、目标 API dry-run 和 live diff 分开。控制器内置的渲染器、插件、默认值与 admission 都可能改变结果。升级 GitOps 平台也可能同时升级渲染语义,所以 golden render、对象清单和字段级差异属于升级证据,不是开发机上的一次临时命令。
权限、密钥和同步作业最容易扩大事故
身份、密钥与访问治理拆分仓库读取、制品校验、集群写入、解密和租户管理身份。把 SOPS 密文放进 Git 不等于没有明文:控制器内存、临时文件、插件、API Server、事件和日志都可能接触解密结果。组织级仓库 Token、跨集群管理员 kubeconfig 和共享解密私钥不能成为默认配置。
同步顺序、Hook 与 Job处理 CRD/controller、迁移 Job、应用和验证 Job 的依赖。YAML 文件顺序不构成完成门禁,wave 和 dependsOn 也不能替代幂等性。数据库迁移、外部 API 和消息发送必须拥有业务幂等键、deadline、完成事实、补偿动作和审计保留;删除 Job 不能顺便删除唯一故障证据。
漂移与删除必须能解释所有权
漂移、Prune 与资源所有权区分四层事实:GitOps inventory、SSA 字段所有权、Kubernetes owner reference/finalizer、组织 owner。看到 OutOfSync 就强制同步,常常会把两个控制器争写、webhook 变异、非确定渲染或应急手改放大成 API 写风暴。
自动 prune 是高风险写操作。仓库目录暂时为空、generator 集合缩小、集群标签误改或对象身份变化,都可能扩大删除面。关键对象需要删除预览、owner 确认、批次上限和停止条件;退出某个平台时还要决定保留业务资源、转交新 manager,还是由旧控制器完成受控清理。
排障从 source 开始,不从工作负载猜
GitOps 可观测与分层排障沿 source fetch、artifact、render、queue/reconcile、API apply、inventory/health 和业务请求逐层定位。常见症状“仓库已合并但集群没变化”至少可能来自旧缓存、认证、错误 path、渲染失败、依赖未 Ready、API 拒绝、队列积压或目标集群离线。
证据必须携带 source revision、对象 generation、目标集群、控制器组件和时间窗。日志中不记录 Secret diff、完整渲染输出或真实集群凭证;指标标签也不应直接使用任意仓库 URL、租户名和对象 UID,避免敏感信息与基数同时失控。
多集群首先是故障域与恢复问题
多集群、容量与灾备比较中央 push、每集群 pull 和 Fleet 两阶段 pull 的网络与凭证边界。集群数不是唯一容量变量;Application/Kustomization/Bundle 数、每单元对象数、渲染耗时、目标 API latency、drift 比例、健康等待和网络恢复后的积压共同决定容量。
只备份 Git 无法重建全部系统。恢复还需要控制器 CRD/配置、AppProject 或租户边界、repo/cluster credential、SOPS/External Secrets 身份、集群登记、插件版本和外部 Registry。灾备演练应从空管理集群 bootstrap,证明不会因旧 inventory、缺失凭证或恢复顺序错误触发误 prune。
升级和退出都要归还写入权
升级、迁移、弃用与退出把 CRD、控制器、内嵌渲染器、插件、API 版本、inventory、凭证和资源所有权视为一笔事务。新旧控制器双跑只能在对象或字段写入面互斥时成立;两个调谐器同时“帮助”同一对象,只会制造持续漂移。
退出完成的证据不是 Pod 消失,而是调谐已暂停、业务对象已保留或受控删除、finalizer/webhook/CRD 已处理、repo/cluster credential 已撤销、外部 Secret 和通知已解绑、缓存与审计按策略保留、负载均衡与云资源已核销。无法回答这些问题时,工具仍然拥有系统的一部分。
团队落地检查
每个环境只有一个可审计期望状态入口,每个运行对象和关键字段只有一个明确写入 owner。发布记录能够关联 source revision、artifact digest、renderer 版本、目标集群、inventory、health 与真实业务结果。自动 sync、self-heal、prune、generator 缩容和镜像自动提交分别有权限、批次、停止条件与回滚。
仓库、集群、解密和租户管理身份分离,凭证可轮换、撤销且不进入 Git、日志、截图和长期 artifact。Hook/Job 的副作用幂等,超时、重试、补偿、完成事实和证据保留明确。多集群容量覆盖断网恢复与调谐洪峰,管理控制面、Git、Registry、目标 API 和遥测后端都有预算。
升级前完成旧新渲染和 API 差异,退出前演练资源归还、凭证撤销与从零恢复。
