上一篇【第77篇】Istio——服务网格的入门与实践,给每个服务配个“私人保镖“
下一篇【第79篇】Gateway API——Ingress的"接班人"


摘要

传统部署流程:代码推上Git → CI打镜像 → 用脚本SSH到服务器kubectl apply。这条链路有几个毛病:集群状态不透明(谁知道现在跑的是哪个版本)、不可审计(没记录谁改了啥)、容易漂移(手动改了集群但Git没同步)。

GitOps换个根本思路:把"期望的集群状态"存在Git仓库,以Git为唯一真相源。ArgoCD是GitOps的事实标准实现——它持续对比Git里的期望状态和集群里的实际状态,不一致就自动拉齐(同步)。

这篇文章讲清GitOps原则、ArgoCD架构、自动/手动同步、多集群管理,以及从Git Push到自动部署的完整链路。


一、GitOps核心原则

1.1 一切以Git为准

【传统部署 vs GitOps】

  传统:
  dev → push代码 → CI → 脚本 kubectl apply 到集群
        ⚠️ 集群是"终点",状态散落各处,不可追溯

  GitOps:
  dev → push到Git(存期望状态) → ArgoCD → 同步到集群
        ✅ Git是"唯一真相源"
        ✅ 集群只是Git状态的"投影"
        ✅ 任何变更都走Git(PR/MR),可审计、可回滚

要点:GitOps的精髓是**“声明期望状态在Git,集群自动向Git靠拢”**。这和K8s的声明式哲学(第062篇)一脉相承——只不过把"期望状态"从etcd扩展到了Git。好处爆炸:所有变更有Git历史(谁、何时、改了啥)、回滚就是git revert、集群状态永远可重建(Git在就不怕集群崩)。


二、ArgoCD架构

2.1 核心概念

【ArgoCD 架构】

  Git Repository (期望状态)
        ▲
        │ ArgoCD 持续对比(difference)
        │
  ┌─────────────────────────────────┐
  │ ArgoCD (控制面, 跑在集群里)      │
  │   • API Server / UI             │
  │   • Application Controller       │
  │     - 对比Git和集群             │
  │     - 发现drift(漂移)就同步      │
  │   • Repository Server           │
  │     - 拉取Git/Helm仓库           │
  └─────────────────────────────────┘
        │ 执行 kubectl apply (通过K8s API)
        ▼
  K8s Cluster (实际状态) —— 可多集群!

2.2 Application 和 AppProject

【ArgoCD 的两个核心CRD】

  Application (应用):
    • 连接 "一个Git路径" 和 "一个集群+namespace"
    • 定义: 去哪个Git仓库的哪个path、用哪种工具(helm/kustomize/plain)
    • 同步策略(自动/手动)
    例: "prod环境的web应用 = git@example/web.git//prod + cluster-A"

  AppProject (项目):
    • 对Application分组+权限控制
    • 限制: 这个project的App能部署到哪些集群/namespace
    • 多团队隔离用

三、自动 vs 手动同步

3.1 两种模式

【同步模式】

  Manual (手动):
    • ArgoCD检测到Git和集群不一致 → 标红"OutOfSync"
    • 人工点"Sync"按钮才生效
    • 适合: 生产环境要审批的场景

  Automatic (自动):
    • Git一变 → ArgoCD自动同步到集群
    • 可设 prune(删除Git里没了但集群还有的资源)
    • 可设 selfHeal(集群被手动改了→自动改回Git状态)
    • 适合: 测试/预发,或信任Git的自动化生产
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/me/web.git
    path: k8s/prod          # Git里的manifest路径
    targetRevision: HEAD     # 跟Git主线
  destination:
    server: https://kubernetes.default.svc  # 目标集群
    namespace: prod
  syncPolicy:
    automated:
      prune: true           # Git删了→集群也删
      selfHeal: true         # 集群被改→自动改回Git状态

四、实战:从Git Push到自动部署

4.1 完整链路

【一次GitOps部署的时间线】

  1. 开发者改了 web 的 image 版本
     git commit -m "bump web to v1.2"
     git push origin main

  2. ArgoCD 轮询Git(或Git webhook通知)
     → 发现 main 分支变了

  3. ArgoCD 拉取最新 manifest
     → 对比集群当前状态
     → 发现 image 版本不一致 → 标记 OutOfSync

  4. (自动模式) ArgoCD 同步
     → 调K8s API apply新manifest
     → Deployment滚动更新(第013篇)
     → Pod变成新版本

  5. ArgoCD 再对比 → Synced ✅ (Git和集群一致)

  整个过程开发者只碰了Git,没碰集群!
# 看ArgoCD状态(CLI或UI)
argocd app get web-prod
# NAME      CLUSTER  NAMESPACE  STATUS  HEALTH
# web-prod  in-cluster prod       Synced  Healthy

# 回滚? 直接 git revert + push, ArgoCD自动同步回去
# 或: argocd app rollback web-prod 3

要点:GitOps的闭环是"开发者只改Git,集群自动追平"。ArgoCD的selfHeal能抵御"有人手动kubectl改了集群"——它会把集群改回Git定义的状态,保证集群永不漂移。回滚就是git revert,比传统"找旧yaml重apply"优雅一万倍。多集群时,一个ArgoCD能管多个集群的多个Application,是多云部署的利器。


五、GitOps vs 传统CI/CD

维度传统CI/CDGitOps(ArgoCD)
真相源CI脚本/流水线Git仓库
部署触发CI主动push到集群ArgoCD拉取+同步
集群状态不透明/易漂移Git即状态,可比对
回滚重跑旧流水线git revert
审计靠CI日志靠Git历史
多集群脚本逐个部署一个ArgoCD统一管理

六、和CI的关系

【GitOps 不取代CI,只接管CD】

  CI (如GitHub Actions/Jenkins):
    • 编译代码 → 跑测试 → 打镜像 → 推镜像仓库
    • 改Git里的image tag

  CD (ArgoCD, GitOps):
    • 看Git里的manifest变了 → 同步到集群

  分工: CI管"构建出什么",GitOps管"部署成什么样"

本篇小结

GitOps把Git作为集群唯一真相源——期望状态存Git,ArgoCD持续对比Git与集群、不一致就自动拉齐。核心是Application(连接一个Git路径和一个集群namespace)和AppProject(分组权限)。自动同步+prune+selfHeal保证集群永不漂移、永不丢失Git定义的状态。

开发者只需改Git,回滚就是git revert,多集群一个ArgoCD统一管。GitOps不取代CI——CI管"构建出什么"(打镜像),ArgoCD管"部署成什么样"(同步manifest)。下篇讲Gateway API——Ingress的"接班人"。


上一篇【第77篇】Istio——服务网格的入门与实践,给每个服务配个“私人保镖“
下一篇【第79篇】Gateway API——Ingress的"接班人"


更多推荐