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 CRD | ArgoCD 中定义“Git 源 → 目标集群”的映射 | ArgoCD |
| ApplicationSet | 通过生成器模板批量创建 Application | ArgoCD |
| Kustomization | Flux 的核心 CRD,对应 ArgoCD 的 Application | Flux |
| HelmRelease | Flux 的 Helm 发布 CRD,精细控制 Helm 部署 | Flux |
| SSO / Dex | 通过 OIDC/LDAP 统一登录 ArgoCD WebUI | ArgoCD + 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 标准):
- 声明式(Declarative)——期望状态用描述性清单(YAML)表达,而不是命令序列。机器可读、可 diff、可评审
- 版本化与不可变(Versioned & Immutable)——所有状态变化都产生 Git 提交,每个提交都是不可变的"事实快照"
- 自动拉取(Pulled)——Agent(ArgoCD/Flux)主动拉取期望状态并应用,反向于传统 CI 的推送(Pushed)
- 持续调和(Reconciled)——Agent 持续比较"期望状态 vs 实际状态",发现漂移(漂移=有人绕过 Git 直接改了集群)立即修正
- 可审计与可回滚(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 的回滚分三个层次,按事故严重程度选择:
- 应用级回滚:
kubectl rollout undo只对单次 Deployment 生效,但漂移会被 ArgoCD 修正回去——所以 GitOps 环境必须回滚 Git 而不是回滚集群 - 提交级回滚:
git revert生成反向提交,ArgoCD 自动同步,历史完整保留(推荐) - 仓库级回滚:
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_hosts 或 tlsClientConfig |
| SSO 回调 URL 未配 HTTPS | OIDC 登录失败(浏览器拒绝 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 中标明每个目录对应的环境和部署方式
练习题
- 安装 ArgoCD 到本地 Kind 集群,创建一个 Application 指向
https://github.com/argoproj/argocd-example-apps.git的guestbook目录,观察自动同步过程 - 编写一个 ApplicationSet 使用 Git 生成器,遍历
apps/team-*目录自动为每个 team 创建 Application - 用
flux bootstrap初始化一个 Git 仓库,并创建 Kustomization 部署 Nginx - 创建 HelmRelease 部署 Redis(使用 bitnami chart),通过 values 自定义 replicaCount
- 对比 ArgoCD 的 Application 与 Flux 的 Kustomization + GitRepository 组合——从架构设计角度列出各自的优劣
点击查看答案
- 安装 ArgoCD 后
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default,argocd app sync guestbook触发同步。 - ApplicationSet 用
generators: - git: { repoURL: ..., directories: [{ path: 'apps/team-*' }] },模板中{{ path.basename }}做 Application 名。 flux bootstrap github --owner=myorg --repository=fleet --path=./clusters/prod --personal。创建 Kustomization 引用 deploy/nginx.yaml。- HelmRelease:
spec.chart.spec.chart: redis+values: { replicaCount: 3 }。Flux 自动检测 values 变更并升级。 - 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
速查表
| 概念 | ArgoCD | Flux |
|---|---|---|
| 核心 CRD | Application | GitRepository + Kustomization |
| 多环境模板 | ApplicationSet | Kustomize overlay |
| Helm 支持 | Application 内嵌 Helm | HelmRelease CRD |
| WebUI | 内置(含 SSO) | 无(需第三方) |
| 同步策略 | 自动/手动/Prune | 自动 reconcile |