GitOps 实战:用 ArgoCD/Flux 把 K8s 部署交给 Git 做到可回退可重建


用 Kubernetes 跑自托管后,很多人的做法还是"改 YAML → apply 一下 → 靠记忆同步"。K8s 的资源一变多、一分散,就会出现"谁改过什么、现在线上到底是谁的状态、哪天改的、出问题回退到哪"的混沌——部署像一场没有版本控制的冒险。GitOps 的思路是把"部署的期望状态"放进 Git 做单一可信来源(source of truth),让一个"同步工具"盯着仓库,发现仓库与集群有差异就自动拉平。工具里最主流的是 ArgoCD 与 Flux。这篇讲清 GitOps 解决什么、ArgoCD 与 Flux 怎么选、怎么把应用部署交给 Git,以及常见坑与边界。

一、GitOps 解决什么:把"部署的真相"从集群搬进 Git,可追溯可回退

K8s 部署的痛往往不在失败,而在"不可见、不可回溯、不可重建":某天线上被手动 apply 改过什么、当前 running 的状态和仓库里的 YAML 是否一致、出问题要回退到哪个版本——全靠记忆和现场翻。GitOps 把两件事定死:一是"Git 仓库是唯一可信的期望状态"(部署的 YAML、Helm values、版本声明都在仓库、可 review、有历史);二是"同步由工具自动执行"——工具对比仓库与集群,有差异就拉平(要么自动,要么需审批)。于是部署变成"改仓库 → 提 PR → 合并 → 工具自动同步",可追溯(Git 历史)、可回退(切回旧 commit)、可重建(从仓库从头拉)也就顺理成章了。

它与"CI/CD"不是一回事而是协作:CI 负责"构建产物"(编译、出镜像、写进仓库),GitOps 工具负责"把产物按要求同步到集群"(CD 的"部署"部分由 Git 驱动)。简单说,GitOps 把 CD 的"期望状态"版本化、自动化、可回退——部署从"操作行为"变成"仓库内容的持续同步"。

二、ArgoCD 与 Flux 怎么选:架构、同步方式与成熟度

两个主流工具定位相近,都有"声明式 + 自动同步 + 漂移修复",取舍在细节。ArgoCD:以"Application"为单位管理,自带 Web UI 与 CLI,能可视化应用与同步状态、支持多集群/项目维度 RBAC,普及度和资料多;通过 pull 或 push 同步,集成好多种源(Git/Helm/Kustomize)。Flux:更"Operator 化、All-in-Git",把自己也声明成 Git 资源,原生集成 Helm/Kustomize、支持 OCI、配合 Flagger 做渐进交付,社区与 CNCF 背书强、组件更细。选型判断:想有现成 UI、项目粒度、资料多看 ArgoCD;想"一切都是 Git 声明、深度 Cloud Native 原生"、配 Flagger 做灰度走 Flux。

# ArgoCD:argocd 的 Application 示意(声明我"期望"集群里跑什么)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://git.example.com/myorg/deploy
    path: apps/myapp
    targetRevision: main
    helm: { valuesFiles: ["values.yaml"] }
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true        # 仓库里删掉的资源,集群里也删
      selfHeal: true     # 集群被手动改掉,自动纠正回 Git 状态

不论选哪个,核心红线一致:"Git 是唯一真相" + "集群漂移会被修回"(selfHeal/自动同步)。正因为多了"自动拉平",GitOps 尤其要求仓库质量高——PR review、不可变 tag 锁 digest、改前先在非 prod 验证,否则"自动同步"会把错误也自动铺到集群。选型定下来后,把"自动同步 + PR 门禁 + 回退演练"养成流程,才是 GitOps 真正好用的前提。

三、把应用部署交给 Git:仓库结构、Helm/Kustomize 与措置

要上 GitOps,先把"部署仓库"组织好:用 Helm 或 Kustomize 把"可变环境差异"与"模板"分离,一个应用一个目录、不同环境(dev/prod)各自 values;镜像版本用清单写清楚(锁定 digest,别用 latest);对安全敏感项(镜像仓库凭据、数据库密码)通过 Sealed Secrets/SOPS 加密后进仓库,而不是明文存 Git。工具同步后,集群状态即仓库状态,任何人(含工具)都能从仓库推导"该是什么样"。

# 部署仓库结构示意(ArgoCD 视角):
# deploy/
#   apps/myapp/
#     kustomization.yaml        # 用 Kustomize 组合
#     base/  .../               # 基础清单
#     overlays/
#       prod/    values.enc.yaml  # 密文加密
#       staging/ values.yaml
#   apps/other/
# 凭据加密示例(SOPS + age/galaxy):
#   sops --encrypt values.prod.yaml > values.prod.enc.yaml

一个常见通病是"镜像用 latest/随便改 tag",这让"回退到旧 commit"失去意义——因为 tag 指向的内容早就变了。上 GitOps 前先改成"不可变 tag 或 digest"(如 `image@sha256:...` 或带 commit 的 tag),回退才真能回到"当时跑的那一份"。仓库结构规范 + 状态不外泄 + 版本可回退,三样到位 GitOps 才立得住。

四、常见坑:自动同步把错铺开、漂移无观察、凭据泄漏、权限过大

GitOps 跑起来,四个坑要尤其防。一是"自动同步放大错误":仓库合并了一个有问题清单,selfHeal/自动同步会把它自动铺到全集群——所以必须在仓库侧设 PR 门禁、拉取前校验、并用不可变版本,别让 1 秒的 merge 毁了整个 prod。二是"漂移没有人看":手动 kubectl apply、某脚本改了资源,客户端显示"已同步"却已漂移——要有"漂移检查/告警",把不一致当事件而非忽略。三是"凭据泄漏":仓库里一旦有明文密钥被 push,等同泄露——用 SOPS/Sealed Secrets,且加密密钥与集群分开保管。四是"权限过大":GitOps 工具往往被授予集群宽权限,构建/CI 权限要最小化,别让一个被攻破的仓库/CI 直接控制整条链路。

# 漂移与一致性检查(ArgoCD CLI 示例):
#   argocd app get myapp            # 看 sync status
#   argocd app diff myapp           # 看仓库声明的 vs 集群实际的差异
# Flux 侧:flux get kustomization   # 看是否有未应用的差异

把这当排障 SOP:同步"变了"要看 Git 里最近改了什么、是不是意外合并;"没变但集群不对"要查有没有手动漂移把状态带偏;回退就切 Git 到上一可信 commit 让工具拉平。GitOps 的前提是"仓库可信、门禁生效、解密可控",这几样守好,自动同步才是助力而非事故源头。

五、边界:GitOps 管"部署的期望状态",不替代测试与备份,也有它的复杂度

GitOps 的边界要认清:它把"期望状态"版本化与自动拉平,但不保证"这个状态是正确的业务逻辑"——有 bug 的镜像照样会通过 GitOps 被自动部署,门禁与测试仍在 Git 侧。其次它增加了一套工具层(ArgoCD/Flux、仓库、加密、RBAC)要维护,对"就几个应用、一个人、一台小集群"的场景,它的复杂度收益未必回本——要评估值不值得。最后,Git——它让"从仓库重建"容易,但 Kubernetes 上数据(PV 里的真实数据、有状态应用)仍需专门的备份与容灾,GitOps 管理的是"清单/期望状态"而非数据、也不替代测试。

把 GitOps 放回自托管整体:它把 Kubernetes 部署从"手工 apply 的不可追溯"升级为"Git 驱动的可追溯、可回退、可重建",是自托管"把配置当资产管理"这一哲学在 K8s 层的落地。落地要点:先想清楚值不值得(应用多、要规范部署才上);把部署仓库组织好(Helm/Kustomize、digest 锁版本、SOPS 管密钥);用 ArgoCD 或 Flux 做"Git 唯一真相 + 自动同步 + 漂移修复";防住自动同步放大错误、漂移无观察、凭据泄漏、权限过大四坑,并认清它不替代测试与数据备份。当你把部署的"期望状态"稳稳托付给 Git,K8s 自托管才能做到"改仓库即上线、出问题可回退、整仓库可重建"。

结语

GitOps 的价值,是把 Kubernetes 部署的"期望状态"放进 Git 作为唯一可信来源,再由 ArgoCD/Flux 持续同步并修正漂移,让部署可追溯、可回退、可重建。落地要点:评估值不值得;用 Helm/Kustomize 组织部署仓库、锁 digest、用 SOPS/Sealed Secrets 管密钥;在 ArgoCD 与 Flux 间按"是否要 UI/项目粒度 vs 全 Git 原生 + Flagger"选择并配好自动同步与漂移修复;防住自动同步放大错误、漂移无观察、凭据泄漏、权限过大四坑。认清它管理的是"清单/期望状态"而非数据、也不替代测试——当部署的真相唯一且可回退,K8s 自托管才从"靠记忆跑"升级为"以 Git 为准、可重构"的稳定阵地。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Kubernetes 网络模型与 CNI 实战:把 Pod 网络的通与受控整明白

Keycloak 统一身份认证实战:用 OIDC/SSO 把散落账号收拢成一个身份中心

评 论
更换验证码