ArgoCD 是 CNCF 毕业项目中最受欢迎的 GitOps 持续交付工具,在 2025 年 Kubernetes 终端用户调查中,其采用率高达 60%。它将 Git 仓库作为唯一真相来源(Single Source of Truth),通过持续拉取(Pull-Based)模型实现声明式部署。本文将从架构设计出发,深入剖析 ArgoCD 的每个核心组件、同步机制、多集群管理,以及企业级最佳实践。
核心理念:什么是 GitOps?
GitOps 的核心是用 Git 来驱动整个运维。四个基本原则:
- 声明式(Declarative):系统期望状态用代码描述,而非命令序列
- 版本控制(Versioned):所有配置存储在 Git 中,具有完整变更历史
- 自动化(Automated):工具持续确保实际状态与 Git 中声明的期望状态一致
- 持续协调(Continuously Reconciled):偏差(drift)被自动检测和修复
ArgoCD 的 Pull-Based 模型与传统 Push-Based CI/CD 的根本区别:
1 2 3 4 5 6 7
| 传统 Push 模型(Jenkins/GitLab CI): Git 变更 → CI Pipeline → kubectl apply → 集群 (CI 系统需要集群访问权限,安全风险高)
ArgoCD Pull 模型: Git 变更 → ArgoCD 拉取 → 对比差异 → 自动同步 (集群内运行,只需要拉取 Git,权限模型更安全)
|
整体架构:微服务设计
ArgoCD 采用微服务架构,各组件通过 gRPC/REST 通信,共享 Kubernetes CRD 和 Redis 缓存作为状态存储。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ┌─────────────────────────────────────────────────────────────────┐ │ ArgoCD 组件架构 │ │ │ │ 外部访问层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ Web UI │ │ CLI │ │ CI/CD API │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ └─────────────┼───────────────┘ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ API Server │ │ │ │ (gRPC/REST, JWT 认证, RBAC 策略) │ │ │ └───────┬──────────────────────────────┘ │ │ │ │ │ ┌─────┴──────────┬─────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │ │ Redis │ │ Repo Server │ │ Application │ │ │ │ (缓存层) │ │ (渲染清单) │ │ Controller │ │ │ └──────────┘ └──────────────┘ │ (核心协调引擎) │ │ │ └──────────────────────┘ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ Dex │ │ Notification │ │ │ │ (SSO) │ │ Controller │ │ │ └──────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────┘
|
API Server
接收来自 Web UI、CLI 和 CI/CD 系统的所有请求:
- 验证 JWT Token 并检查 RBAC 策略
- 不负责实际的同步或清单生成,只做路由分发
- 暴露 gRPC 和 REST 两套接口
Repository Server
清单生成的核心:
- 克隆 Git 仓库到本地缓存
- 支持多种模板工具:Helm、Kustomize、Jsonnet、纯 YAML,以及 Config Management Plugin(CMP)
- 渲染生成最终的 Kubernetes 清单
- 对相同 commit 的结果进行缓存,避免重复渲染
Application Controller
最核心的组件,以 StatefulSet 形式部署(与其他 Deployment 不同):
1 2 3 4
| 协调循环(每隔数秒执行): 1. Observe:从 Git(通过 Repo Server)获取期望状态 2. Diff:对比期望状态与 Kubernetes 实际资源状态 3. Act:若存在偏差且策略允许,执行 kubectl apply
|
- 管理所有 Application CRD 的生命周期
- 支持多集群:通过 kubeconfig 或 Cluster CRD 连接多个目标集群
- 规模化时通过分片(Sharding)横向扩展
Redis
纯缓存层,存储:
- Application 状态缓存(避免频繁查询 K8s API)
- Git 仓库缓存条目
- Revision 缓存
注意:Redis 是 ArgoCD 中唯一的缓存,实际配置数据都以原生 Kubernetes 对象存储,Redis 故障不会导致数据丢失。
Dex
SSO 集成提供者,支持 OpenID Connect:
- 对接 Keycloak、Okta、Azure AD、GitHub OAuth 等
- 为 ArgoCD API Server 提供统一认证入口
Application CRD:声明式部署单元
ArgoCD 使用 Application CRD 描述”把哪个 Git 仓库的哪个路径,部署到哪个集群的哪个命名空间”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app namespace: argocd spec: project: default
source: repoURL: https://github.com/myorg/my-app-config.git targetRevision: main path: k8s/overlays/production
destination: server: https://kubernetes.default.svc namespace: production
syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true - PruneLast=true - RespectIgnoreDifferences=true retry: limit: 5 backoff: duration: 5s maxDuration: 3m factor: 2
|
四大同步策略详解
| 策略 |
说明 |
风险 |
automated: false(默认) |
手动触发同步 |
无,最安全 |
automated.prune: false |
自动同步但不删除资源 |
低 |
automated.prune: true |
自动同步 + 删除 Git 中移除的资源 |
中,建议按 app 开启而非全局 |
automated.selfHeal: true |
自动撤销对集群的手动修改 |
中,开发/测试环境谨慎开启 |
Sync Waves 和 Hooks:精细化部署编排
在复杂部署中,资源之间存在依赖关系(如 CRD 必须在 Operator 之前创建)。ArgoCD 通过 Sync Waves 和 Hooks 解决这个问题。
Sync Waves:波次排序
通过 annotation 为资源指定整数波次,数字越小越先部署:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: foos.example.com annotations: argocd.argoproj.io/sync-wave: "0"
---
apiVersion: apps/v1 kind: Deployment metadata: name: foo-operator annotations: argocd.argoproj.io/sync-wave: "1"
---
apiVersion: foo.example.com/v1 kind: Foo metadata: name: my-foo annotations: argocd.argoproj.io/sync-wave: "2"
|
Sync Hooks:生命周期钩子
1
| 同步阶段顺序:PreSync → Sync → PostSync(成功)或 SyncFail(失败)
|
| Hook 类型 |
执行时机 |
典型用途 |
PreSync |
任何资源被应用之前 |
数据库 Schema 迁移、备份 |
Sync |
与普通资源同时应用 |
特定顺序的部署 |
PostSync |
所有资源健康后 |
冒烟测试、发送通知 |
SyncFail |
同步失败时 |
回滚清理、告警 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: batch/v1 kind: Job metadata: name: db-migrate annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/hook-delete-policy: HookSucceeded argocd.argoproj.io/sync-wave: "0" spec: template: spec: containers: - name: migrate image: myapp:latest command: ["python", "manage.py", "migrate"] restartPolicy: Never
|
完整执行顺序示例:
1 2 3 4 5 6 7
| 1. PreSync wave -1 → 数据库备份 2. PreSync wave 0 → Schema 迁移 3. Sync wave 0 → CRD 部署 4. Sync wave 1 → Operator 部署 5. Sync wave 2 → 应用部署 6. PostSync wave 0 → 冒烟测试 7. PostSync wave 1 → 发送 Slack 通知
|
ApplicationSet:大规模自动化管理
ApplicationSet CRD 是 ArgoCD 对 Application 的自动化封装,解决”为每个集群/环境手动复制 Application YAML”的痛点。
五种生成器(Generators)
1. List Generator:固定列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook spec: generators: - list: elements: - cluster: staging url: https://staging.k8s.example.com - cluster: production url: https://production.k8s.example.com template: metadata: name: 'guestbook-{{cluster}}' spec: source: repoURL: https://github.com/argoproj/argo-cd.git targetRevision: HEAD path: applicationset/examples/list-generator/guestbook/{{cluster}} destination: server: '{{url}}' namespace: guestbook
|
2. Cluster Generator:自动发现集群
1 2 3 4 5
| generators: - clusters: selector: matchLabels: env: production
|
3. Git Generator:基于仓库目录结构
1 2 3 4 5 6
| generators: - git: repoURL: https://github.com/myorg/apps.git revision: HEAD directories: - path: apps/*
|
4. Matrix Generator:两维笛卡尔积
1 2 3 4 5 6 7 8 9 10
| generators: - matrix: generators: - clusters: {} - list: elements: - app: frontend - app: backend - app: database
|
5. Merge Generator:多源合并
1 2 3 4 5 6 7 8 9
| generators: - merge: mergeKeys: [cluster] generators: - clusters: {} - list: elements: - cluster: prod-us memory: 8Gi
|
App of Apps 模式 vs ApplicationSet
| 维度 |
App of Apps |
ApplicationSet |
| 概念复杂度 |
简单,易理解 |
需要理解 Generator 概念 |
| 手动维护量 |
增加应用/集群时需手动添加 YAML |
自动按规则生成 |
| 细粒度控制 |
每个子 App 独立配置 sync 策略 |
统一模板,差异通过参数化 |
| 适用规模 |
数十个应用 |
数百个应用跨多集群 |
| 适合场景 |
单集群,手工管控 |
多集群、多团队、多环境 |
RBAC:项目级访问控制
ArgoCD 使用 AppProject 实现多租户隔离:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: team-backend namespace: argocd spec: description: Backend team's project
sourceRepos: - 'https://github.com/myorg/backend-*'
destinations: - namespace: backend-* server: https://kubernetes.default.svc
clusterResourceWhitelist: []
namespaceResourceWhitelist: - group: 'apps' kind: Deployment - group: '' kind: Service
roles: - name: developer description: 开发者角色:可以 sync,不能删除 policies: - p, proj:team-backend:developer, applications, get, team-backend/*, allow - p, proj:team-backend:developer, applications, sync, team-backend/*, allow groups: - backend-developers
|
全局 RBAC(argocd-rbac-cm ConfigMap):
1 2 3 4 5 6 7
| policy.default: role:readonly policy.csv: | # 管理员拥有所有权限 g, admin-group, role:admin # 开发者只能同步和获取 p, role:developer, applications, sync, */*, allow p, role:developer, applications, get, */*, allow
|
优先级规则:拒绝(deny)策略高于允许(allow),全局策略与项目策略同时评估。
Health Check:健康状态体系
ArgoCD 对所有资源评估健康状态,并汇总为 Application 健康状态。
六种健康状态
| 状态 |
含义 |
Healthy |
资源就绪,运行正常 |
Progressing |
正在部署/更新中 |
Degraded |
存在问题但未完全宕机 |
Suspended |
部署被暂停 |
Missing |
资源不存在 |
Unknown |
无法确定状态 |
自定义健康检查(Lua 脚本)
CRD 资源不遵循标准 K8s status 格式,需要自定义 Health Check:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| data: resource.customizations.health.myorg.io_MyApp: | hs = {} if obj.status ~= nil then if obj.status.phase == "Running" then hs.status = "Healthy" hs.message = "MyApp is running" elseif obj.status.phase == "Pending" then hs.status = "Progressing" hs.message = "MyApp is starting up" elseif obj.status.phase == "Failed" then hs.status = "Degraded" hs.message = obj.status.message else hs.status = "Unknown" end end return hs
|
多集群管理
ArgoCD 的一大优势是从单一控制面管理多个目标集群。
集群注册
1 2 3 4 5 6 7
| argocd cluster add production-context \ --name production \ --label env=production \ --label region=us-east-1
|
多集群架构模式
集中式(Centralized Hub):
1 2 3 4 5
| 管理集群 └── ArgoCD 实例 ├── 管理 → dev-cluster ├── 管理 → staging-cluster └── 管理 → prod-cluster (× n)
|
适合:< 15 个集群,中心化治理,可见性好
去中心化(Per-Cluster ArgoCD):
1 2 3 4
| Meta-ArgoCD(管理 ArgoCD 实例本身) ├── 管理 → ArgoCD@team-a-cluster ├── 管理 → ArgoCD@team-b-cluster └── 管理 → ArgoCD@team-c-cluster
|
适合:> 20 个集群,团队完全自治,网络隔离严格
Agent 架构(argocd-agent 项目):
1 2 3 4
| ArgoCD Hub(无需主动连接各集群) ↑ ↑ ↑ 轻量 Agent 主动回连 Hub (适合网络受限、防火墙严格的环境)
|
Notifications:事件告警
ArgoCD Notifications 通过 Trigger + Template 实现灵活告警:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| data: trigger.on-sync-failed: | - when: app.status.operationState.phase in ['Error', 'Failed'] send: [app-sync-failed]
trigger.on-health-degraded: | - when: app.status.health.status == 'Degraded' send: [app-health-degraded]
template.app-sync-failed: | message: | 应用 {{.app.metadata.name}} 同步失败! 错误信息:{{.app.status.operationState.message}} 详情:{{.context.argocdUrl}}/applications/{{.app.metadata.name}}
service.slack: | token: $slack-token
|
1 2 3 4 5
| metadata: annotations: notifications.argoproj.io/subscribe.on-sync-failed.slack: ops-alerts notifications.argoproj.io/subscribe.on-health-degraded.slack: ops-alerts
|
Image Updater:自动镜像更新
ArgoCD Image Updater 自动监控容器 Registry,发现新镜像时更新 Application:
1 2 3 4 5 6 7 8 9 10
| metadata: annotations: argocd-image-updater.argoproj.io/image-list: | myapp=docker.io/myorg/myapp argocd-image-updater.argoproj.io/myapp.update-strategy: semver argocd-image-updater.argoproj.io/myapp.allow-tags: regexp:^v[0-9]+\.[0-9]+\.[0-9]+$ argocd-image-updater.argoproj.io/write-back-method: git argocd-image-updater.argoproj.io/git-branch: main
|
三种更新策略:
| 策略 |
说明 |
semver |
按语义化版本选最新(推荐) |
latest |
按推送时间选最新 |
alphabetical |
按字母排序选最后 |
ArgoCD vs Flux CD
| 维度 |
ArgoCD |
Flux CD |
| 社区采用率 |
~60%(2025 CNCF 调查) |
较小 |
| UI |
内置 Web UI |
官方 UI(v2.8 起,Flux Operator 提供) |
| 架构 |
集中式单体 Controller |
模块化微服务(source/kustomize/helm controller 分离) |
| 学习曲线 |
低(Web UI 友好) |
中(CLI 优先) |
| 多集群 |
ApplicationSet 原生支持 |
多实例或 Flux Cluster API |
| Secrets |
需外部工具(Vault, External Secrets) |
原生 SOPS/Vault 集成更自然 |
| Sync 粒度 |
支持 diff(不全量同步) |
总是全量同步 |
| 适合 |
开发体验、团队协作、GitOps 入门 |
平台工程、精细化控制、CLI 深度用户 |
企业级最佳实践
1. 仓库结构
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 推荐:独立的配置仓库(与源码分离) infra-gitops/ ├── apps/ # Application 清单 │ ├── production/ │ │ ├── frontend.yaml │ │ └── backend.yaml │ └── staging/ ├── clusters/ # 集群级配置 │ ├── production/ │ └── staging/ └── platform/ # 平台组件(Prometheus, Cert-Manager...) ├── monitoring/ └── security/
|
原则:应用代码和部署配置分仓库,用 PR 审核机制保障配置质量。
2. 安全
- 生产环境使用 Commit SHA 精确 pin 版本(不使用 branch 名)
- Auto-prune 按 app 开启,绝不全局启用(防止 LabelSelector 误配删除生产 namespace)
- 通过 Project + RBAC 限制团队权限,最小化 blast radius
- ArgoCD API Server 不暴露公网,通过 VPN 或 SSO 控制访问
3. 高可用部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: replicas: 3 autoscaling: enabled: true
repoServer: replicas: 2
controller: replicas: 1
redis-ha: enabled: true
|
4. Sync Window(变更窗口控制)
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: argoproj.io/v1alpha1 kind: AppProject spec: syncWindows: - kind: allow schedule: "0 10 * * 1-5" duration: 8h applications: ["*"] manualSync: true - kind: deny schedule: "0 0 * * 5" duration: 72h applications: ["*"]
|
小结
ArgoCD 将 GitOps 理念落地为可操作的生产系统:
- Application CRD 是部署意图的声明载体
- Sync Waves + Hooks 解决复杂依赖排序问题
- ApplicationSet 实现大规模多集群自动化
- AppProject + RBAC 提供企业级多租户隔离
- Image Updater + Notifications 构建完整的自动化闭环
其核心价值在于:把 Git 变成生产环境的控制平面,一切变更通过 PR → Review → Merge → Auto-sync 走一遍,人工操作风险降到最低,审计追踪自然完备。