6.7 GitOps 入门——ArgoCD 与 Flux

预计阅读时间:10 分钟

📖 目录

学习目标

完成本章后,你将能够:

  • 阐述 GitOps 五大原则(声明式、Git 真相源、自动同步、漂移修正、审计回滚)
  • 在 K8s 集群上安装 ArgoCD 并创建 Application 对接 Git 仓库
  • 用 ApplicationSet 的 List / Git / Cluster 生成器实现多环境/多集群部署
  • 用 Flux Kustomization + HelmRelease 管理应用交付
  • 对比 ArgoCD 与 Flux 的架构选型差异
  • 配置 Dex/OIDC 为 GitOps 工具接入 SSO 登录

核心知识

概念一句话对应工具
GitOps 拉模型Operator 从 Git 拉取期望状态并自动同步到集群ArgoCD / Flux
Application CRDArgoCD 中定义“Git 源 → 目标集群”的映射ArgoCD
ApplicationSet通过生成器模板批量创建 ApplicationArgoCD
KustomizationFlux 的核心 CRD,对应 ArgoCD 的 ApplicationFlux
HelmReleaseFlux 的 Helm 发布 CRD,精细控制 Helm 部署Flux
SSO / Dex通过 OIDC/LDAP 统一登录 ArgoCD WebUIArgoCD + Dex

知识关联

  • 前置知识6.2:Kubernetes 入门 Kubernetes 入门(K8s 集群操作基础)、4.18:Git 进阶 Git 进阶(Git 工作流理解)、2.9:Git 版本控制 Git 版本控制
  • 后续影响4.9:CI/CD 持续部署 CI/CD 持续部署(GitOps 是 CD 的进化形态,Pull 模型替代 Push 模型)
  • 配套技术:ArgoCD + Flux 双雄并立,ApplicationSet 实现多环境/多集群管理,Dex/OIDC 集成 SSO 统一登录

原理讲解

GitOps 拉模型:传统 CI/CD 是推模型——CI 系统持有集群凭据,构建后直接推送部署。GitOps 反转了这个方向:集群内的 Operator 主动从 Git 仓库拉取期望状态,与集群实际状态持续比较(reconciliation loop),发现差异即自动或手动同步。凭据始终留在集群内部,CI 系统只需要写 Git 仓库的权限。

ArgoCD 调和循环:Application Controller 每 3 分钟(默认)或收到 Webhook 时,将 Git 中的 manifest 与集群实时状态做 diff。差异通过 sync 操作收敛。支持 prune: true(删除 Git 中已移除的资源)和 selfHeal: true(覆盖手动热修复)。Repo Server 负责克隆仓库并渲染 Helm / Kustomize 模板,Application Controller 只比较渲染后的纯 YAML。

Flux 分层架构:Flux 将 ArgoCD 的 Application 拆为两个 CRD——GitRepository(定义源)和 Kustomization(定义如何 apply)。source-controller 负责拉取和缓存 Git/Helm/OCI 源,kustomize-controller 从缓存中读取源并 apply 到集群。HelmRelease 则通过 helm-controller 实现完整的 Helm 生命周期管理。这种分层让源管理和部署逻辑解耦。

SSO 集成原理:ArgoCD 通过 Dex 作为 OIDC 代理,对接 GitHub / Google / LDAP 等外部身份提供商。用户访问 ArgoCD WebUI 时被重定向到 Dex,Dex 完成外部认证后返回 OIDC token,ArgoCD 用该 token 映射 RBAC 角色和项目权限。

GitOps 五大原则(OpenGitOps 标准)

  1. 声明式(Declarative)——期望状态用描述性清单(YAML)表达,而不是命令序列。机器可读、可 diff、可评审
  2. 版本化与不可变(Versioned & Immutable)——所有状态变化都产生 Git 提交,每个提交都是不可变的"事实快照"
  3. 自动拉取(Pulled)——Agent(ArgoCD/Flux)主动拉取期望状态并应用,反向于传统 CI 的推送(Pushed)
  4. 持续调和(Reconciled)——Agent 持续比较"期望状态 vs 实际状态",发现漂移(漂移=有人绕过 Git 直接改了集群)立即修正
  5. 可审计与可回滚(Auditable & Recoverable)——每一次变更都对应一个 commit;回滚 = revert 一个 commit 或 checkout 一个旧版本,几秒钟完成

GitOps 与 CI/CD 的分工:两者不是替代关系,而是接力关系——CI 负责"从代码到制品"(构建、测试、推送镜像),GitOps 负责"从制品到生产"(把新镜像版本提交进部署仓库,由 Operator 部署到集群):

开发者提交代码
  └─ CI(Jenkins/GitHub Actions)构建镜像 + 跑测试
       └─ 推送镜像到镜像仓库(如 Harbor)
            └─ 更新部署仓库的 image tag(提交到 Git)★ 交接点
                 └─ ArgoCD 检测到 Git 变化 → 拉取 → 滚动更新集群

关键变化:CI 系统不再需要集群凭据(传统 CD 的 Jenkins 持有 kubeconfig,一旦 Jenkins 被攻破集群沦陷)。GitOps 模式下 CI 只写 Git,集群凭据由集群内的 ArgoCD 自己持有,安全边界大幅收窄。

回滚与事故处理流程:GitOps 的回滚分三个层次,按事故严重程度选择:

  1. 应用级回滚kubectl rollout undo 只对单次 Deployment 生效,但漂移会被 ArgoCD 修正回去——所以 GitOps 环境必须回滚 Git 而不是回滚集群
  2. 提交级回滚git revert 生成反向提交,ArgoCD 自动同步,历史完整保留(推荐)
  3. 仓库级回滚git checkout <上次稳定 tag> + force push 到受保护分支,用于连续多个坏提交的紧急回退

示例代码

ArgoCD 安装与第一个 Application

# 安装 ArgoCD
kubectl create namespace argocd
# 输出: namespace/argocd created
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# (stable 分支始终指向当前稳定版;需要固定版本时用 vX.Y.Z 标签)
# 输出: customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
# 输出: serviceaccount/argocd-application-controller created
# 输出: ... (20+ resources created)

# 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# 输出: xxxxxxxxxxxxxx

# 创建第一个 Application
cat <<'EOF' | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-production
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/myapp-deploy.git
    targetRevision: main
    path: production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
EOF

ApplicationSet 多环境模板

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-multienv
spec:
  generators:
    - list:
        elements:
          - env: dev
            namespace: dev
            valuesFile: values-dev.yaml
          - env: prod
            namespace: prod
            valuesFile: values-prod.yaml
  template:
    metadata:
      name: 'myapp-{{ env }}'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/myapp-deploy.git
        targetRevision: main
        path: helm
        helm:
          valueFiles:
            - '{{ valuesFile }}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{ namespace }}'
      syncPolicy:
        automated: {}

Flux Kustomization + HelmRelease

# === GitRepository:定义源(从哪里拉取配置)===
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 1m                    # 每 1 分钟轮询 Git 仓库检查变化
  url: https://github.com/my-org/fleet-infra
  ref:
    branch: main

# === Kustomization:定义部署(如何 apply 到集群)===
# 对应 ArgoCD 的 Application,但职责更单一
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 5m                    # 每 5 分钟调和一次(与 ArgoCD 默认 3 分钟类似)
  sourceRef:                      # 引用上面定义的 GitRepository
    kind: GitRepository
    name: flux-system
  path: ./apps/production         # 仓库内的目录路径
  prune: true                     # 删除 Git 中已移除的资源(等同 ArgoCD 的 prune)

# === HelmRelease:管理 Helm Chart 的完整生命周期===
# 比 ArgoCD 内嵌 Helm 更精细:支持 valuesFrom、升级策略、回滚等
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: nginx
  namespace: flux-system
spec:
  interval: 5m                    # 检查 Helm 仓库是否有新版本
  chart:
    spec:
      chart: nginx                # Chart 名称
      sourceRef:                  # Helm 仓库来源
        kind: HelmRepository
        name: bitnami
        namespace: flux-system
  values:                         # 覆盖 values.yaml 中的默认值
    replicaCount: 3

ArgoCD SSO 配置(Dex + GitHub)

# argocd-cm ConfigMap 追加
data:
  dex.config: |
    connectors:
      - type: github
        id: github
        name: GitHub
        config:
          clientID: $GITHUB_CLIENT_ID
          clientSecret: $GITHUB_CLIENT_SECRET
          orgs:
            - name: my-org
  url: https://argocd.example.com
  oidc.config: |
    name: Dex
    issuer: https://argocd.example.com/api/dex
    clientID: argocd
    clientSecret: $DEX_CLIENT_SECRET

ArgoCD CLI 常用操作

# 登录(服务器地址 + admin 密码)
argocd login argocd.example.com --username admin --password xxxxxx

# Application 操作
argocd app list
# 输出: NAME             CLUSTER                         NAMESPACE  STATUS  HEALTH
#       myapp-production  https://kubernetes.default.svc  production Synced  Healthy

argocd app sync myapp-production --prune     # 手动触发同步(Webhook 故障时用)
argocd app get myapp-production              # 查看同步状态与资源列表
argocd app diff myapp-production             # 查看 Git 与集群的差异
argocd app history myapp-production          # 查看部署历史
# 输出: ID  REVISION  UPDATED                  STATUS
#       0   abc1234   2026-07-29 10:00:01     Synced
#       1   def5678   2026-07-30 09:30:22     Synced

# 多集群注册(把测试集群加入 ArgoCD)
argocd cluster add context-test-cluster

回滚演练——30 秒回到上一个稳定版本

# 演练:模拟一次事故——同事误提交了错误的 image tag
git log --oneline -3
# 8f3a2b1 (HEAD) feat: bump app image to v2.3.1   ← 引入 bug 的提交
# c4d5e6f fix: increase replica count
# a1b2c3d feat: add retry logic

# 回滚(方式一:revert 生成反向提交,保留事故历史)
git revert 8f3a2b1
git push origin main
# ArgoCD 自动检测到新提交并同步,应用回到 v2.3.0
# 验证:argocd app sync-status 或 kubectl get deploy -o wide 确认镜像版本

# 回滚(方式二:临时回退到旧提交,适合连续多个坏提交)
git checkout a1b2c3d -- production/deploy.yaml
git commit -m "hotfix: rollback to a1b2c3d deploy state"
git push origin main

# 事故复盘记录(写入仓库 ADR 文档,GitOps 仓库即文档)
# docs/incidents/2026-07-30-bad-image.md

多环境管理——推荐仓库结构

# 单仓库多目录(mono-repo 模式,推荐小团队)
myapp-deploy/
├── base/                    # 公共基础配置(Kustomize)
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
├── overlays/
│   ├── dev/                 # 开发环境(replicas=1)
│   ├── staging/             # 预发布环境(replicas=2)
│   └── prod/                # 生产环境(replicas=5 + HPA)
├── helm/                    # 或 Helm Chart 模式
│   ├── Chart.yaml
│   └── values-dev.yaml / values-prod.yaml
├── apps/                    # ApplicationSet 的 Git 生成器遍历这里
│   ├── team-billing/app.yaml
│   └── team-billing/kustomization.yaml
└── docs/                    # 环境说明与运维手册

# 环境隔离原则:
# dev  → 任何人 push 即部署(快速迭代)
# staging → PR 合入 main 后部署(验收环境)
# prod → 仅 release tag(v*.*.*)触发 + 人工审批(ArgoCD 支持 sync windows)

常见错误

错误后果解决
prune: true 在未验证的仓库上启用一次错误 git push 可能删除生产资源先从 staging 环境验证;用 ApplicationSet 逐步推广
忘记配置 Webhook 依赖 3 分钟轮询部署延迟最多 3 分钟配置 GitHub/GitLab Webhook 指向 ArgoCD
Flux bootstrap 后目录结构不匹配Kustomization 找不到 path 报错确保 --path 后的目录内含 kustomization.yaml
ArgoCD 中自签名 Git 仓库证书Repo Server 无法 clone 仓库在 argocd-secret 中配置 known_hoststlsClientConfig
SSO 回调 URL 未配 HTTPSOIDC 登录失败(浏览器拒绝 insecure redirect)ArgoCD 必须通过 HTTPS 访问;TLS 终止在 Ingress 上

最佳实践

  • prune + selfHeal 始终开启:手动热修会被自动覆盖,迫使团队走 Git 流程
  • 环境隔离:每个环境独立的 Application / Kustomization,从 dev → staging → prod 逐步灰度
  • Webhook 替代轮询:配置 Git 仓库 Webhook 触发即时同步,减少延迟
  • PR 驱动部署:production 路径只接受 merge 到 main 后的部署,不允许直接 push
  • 监控 Application 健康度:ArgoCD 提供 .status.health.status,Flux 提供 kstatus,接入告警
  • SSO 先行:团队超过 3 人时配置 Dex/OIDC,避免共享 admin 密码
  • Git 仓库即文档:在仓库 README 中标明每个目录对应的环境和部署方式

练习题

  1. 安装 ArgoCD 到本地 Kind 集群,创建一个 Application 指向 https://github.com/argoproj/argocd-example-apps.gitguestbook 目录,观察自动同步过程
  2. 编写一个 ApplicationSet 使用 Git 生成器,遍历 apps/team-* 目录自动为每个 team 创建 Application
  3. flux bootstrap 初始化一个 Git 仓库,并创建 Kustomization 部署 Nginx
  4. 创建 HelmRelease 部署 Redis(使用 bitnami chart),通过 values 自定义 replicaCount
  5. 对比 ArgoCD 的 Application 与 Flux 的 Kustomization + GitRepository 组合——从架构设计角度列出各自的优劣
点击查看答案
  1. 安装 ArgoCD 后 argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace defaultargocd app sync guestbook 触发同步。
  2. ApplicationSet 用 generators: - git: { repoURL: ..., directories: [{ path: 'apps/team-*' }] },模板中 {{ path.basename }} 做 Application 名。
  3. flux bootstrap github --owner=myorg --repository=fleet --path=./clusters/prod --personal。创建 Kustomization 引用 deploy/nginx.yaml。
  4. HelmRelease: spec.chart.spec.chart: redis + values: { replicaCount: 3 }。Flux 自动检测 values 变更并升级。
  5. ArgoCD 优势:WebUI+SSO 完善、ApplicationSet 多集群管理、Sync waves 精细控制。Flux 优势:更 K8s 原生 CRD 分层、无额外组件依赖、Kustomization + HelmRelease 分离清晰。劣势:ArgoCD 胖二进制,Flux 无内置 UI。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 GitOps 的核心原则和声明式管理尝试向他人讲解
命令操作能不查文档完成 ArgoCD/Flux 的安装和应用部署在终端实际执行
原理掌握能说出 GitOps 的 Git 仓库作为唯一事实来源的原理画出流程图
故障排查能独立排查 GitOps 同步失败或应用状态不一致的问题模拟故障并修复
最佳实践能说明为什么需要为 GitOps 配置 RBAC 和审计日志对比不同方案

本章总结

  • GitOps 核心:Git 是唯一真相源,Operator 自动拉取同步,拒绝配置漂移
  • ArgoCD:Application CRD 映射 Git→K8s,ApplicationSet 实现批量模板管理,自带 WebUI 和 SSO
  • Flux:分层 CRD 设计(Source→Kustomization→HelmRelease),更 K8s 原生,无内置 UI
  • SSO:ArgoCD 通过 Dex 代理对接外部 IdP,Flux 需依赖外部 Gateway/Ingress 实现
  • 选型:需要可视化 + 多团队协作用 ArgoCD;偏好纯 CRD 声明式 + Helm 精细控制用 Flux

速查表

概念ArgoCDFlux
核心 CRDApplicationGitRepository + Kustomization
多环境模板ApplicationSetKustomize overlay
Helm 支持Application 内嵌 HelmHelmRelease CRD
WebUI内置(含 SSO)无(需第三方)
同步策略自动/手动/Prune自动 reconcile

延伸阅读

常见问题

GitOps 的核心原则是什么?
GitOps 三原则:① 声明式(Declarative):系统期望状态用代码描述(YAML),非脚本流程;② 版本化(Versioned):所有变更通过 Git 提交,提供完整变更历史;③ 自动同步(Automated Synchronization):Operator(如 ArgoCD、Flux)自动将集群状态对齐到 Git 中声明的状态,偏离时自动纠正。Git 成为唯一 truth source。
ArgoCD Application 怎么配置自动同步?
配置 spec.syncPolicy: { automated: { prune: true, selfHeal: true } }。prune: true 允许删除 Git 中已移除的资源。selfHeal: true 当集群手动修改资源时自动回退到 Git 状态。还可以配置 syncOptions: { Validate: true, PruneLast: false }。生产环境建议先禁用自动同步,手动审核后再 Enable。
GitOps 和传统 CI/CD 在生产中怎么配合?
最佳实践:CI + CD(GitOps)= 完整流水线。CI(如 GitHub Actions)负责构建镜像、运行测试、推送镜像仓库、更新 Git 仓库中的部署清单(修改镜像 tag)。CD(ArgoCD/Flux)检测到 Git 仓库变更后自动同步到集群。分离职责:CI 管"构建和验证",GitOps 管"部署和同步"。变更链路:代码 → CI → Git 仓库 → Flux/ArgoCD → K8s 集群。
↑ 回到顶部