20-ArgoCD
ArgoCD 是 CNCF 毕业的 GitOps 持续交付工具,目前是企业 K8s CD 的事实标准。它的核心思想是:Git 仓库是唯一真源,集群状态持续向 Git 收敛。本章覆盖 ArgoCD 的核心概念、同步策略、ApplicationSet 批量管理、Sync Waves 顺序控制、多集群部署与 PR 预览环境,以及 Argo Rollouts 渐进式交付的集成。
GitOps 四条公理#
评判 ArgoCD 之前,先明确 GitOps 的核心原则:
- 声明式:系统期望状态全部以声明式配置描述。
- 版本化且不可变:所有状态在 Git 里有版本,任何绕过 Git 直接改集群的行为都是反模式。
- 自动拉取与持续 reconcile:控制器主动从 Git 拉取配置,持续比较实际状态与期望状态。这是 GitOps 与传统 CI/CD 的分水岭——CI 不连集群、不拿 kubeconfig、不做 helm upgrade。
- 可审计且自愈:能检测漂移并按需收敛或告警。
判别方法:看谁持有 kubeconfig。如果是 Jenkins/GitLab Runner 拿着集群 admin token 执行 kubectl apply——这是 CIOps;如果是集群内 controller 主动去 Git 拉配置——这才是 GitOps。
核心概念#
Application#
Application 是 ArgoCD 的核心 CRD,描述"把 Git 仓库某个路径的配置同步到目标集群的某个 namespace":
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend
namespace: argocd
spec:
project: team-alpha
source:
repoURL: https://github.com/myorg/gitops
path: apps/frontend/overlays/production
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: team-alpha
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=trueAppProject#
AppProject 是多租户隔离的关键,限制 source repo、destination cluster/namespace、允许的资源类型:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: commerce-team
namespace: argocd
spec:
sourceRepos:
- https://github.com/myorg/gitops
destinations:
- server: https://us-prod.k8s.example.com
namespace: commerce-*
clusterResourceBlacklist:
- group: ""
kind: Namespace # 禁止创建 Namespace
roles:
- name: developer
policies:
- p, proj:commerce-team:developer, applications, get, commerce-team/*, allow
- p, proj:commerce-team:developer, applications, sync, commerce-team/*, allow
groups:
- commerce-developers # 对应 SSO 组同步策略#
Auto Sync vs Manual Sync#
| 环境 | 策略 | 理由 |
|---|---|---|
| QA | Auto Sync + Self-Heal + Prune | 快速迭代,合并即部署 |
| Staging | Auto Sync + Self-Heal,关 Prune | 自动同步但保留手动清理权 |
| Prod | Manual Sync | 生产变更必须有人工确认 |
规则:生产环境永远不开 Auto Sync。
Self-Heal#
检测到集群实际状态与 Git 不一致时自动修复(有人手动 kubectl edit 改了线上配置 → Self-Heal 改回 Git 状态):
syncPolicy:
automated:
selfHeal: true
prune: falsePrune#
控制是否自动删除 Git 中已移除的资源。QA 可以开(快速清理废弃资源),Prod 关闭或配合 PruneLast=true。
ignoreDifferences#
某些字段由集群控制器动态修改(如 HPA 修改 replicas、Istio 注入 annotation),需要忽略差异避免持续 OutOfSync:
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # HPA 管的字段
- group: apps
kind: Deployment
jqPathExpressions:
- .spec.template.metadata.annotations."sidecar.istio.io/status"ApplicationSet:批量管理#
ApplicationSet 是 ArgoCD 的"模板引擎",用一个 CR 生成多个 Application。核心概念是 Generator——产生参数列表,模板渲染出 Application。
List Generator(固定集群列表)#
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-service
spec:
generators:
- list:
elements:
- cluster: us-prod
url: https://us-prod.k8s.example.com
env: prod
- cluster: cn-prod
url: https://cn-prod.k8s.example.com
env: prod
template:
metadata:
name: 'my-service-{{cluster}}'
spec:
project: my-team
source:
repoURL: https://github.com/myorg/gitops
path: 'apps/my-service/overlays/{{env}}'
destination:
server: '{{url}}'
namespace: my-service
syncPolicy:
automated:
prune: true
selfHeal: trueCluster Generator(动态发现)#
从 ArgoCD 已注册集群中动态筛选,用 label 区分环境:
generators:
- clusters:
selector:
matchLabels:
env: prod新集群接入后只要打了 env=prod 标签,ApplicationSet 自动生成 Application,不需要改配置。
Git Generator(目录结构即部署配置)#
generators:
- git:
repoURL: https://github.com/myorg/gitops
revision: HEAD
directories:
- path: apps/*/overlays/prod # 匹配所有服务的 prod overlay新增服务只需创建对应目录,无需手动创建 Application。
Matrix Generator(组合生成)#
把两个 Generator 的输出做笛卡尔积——所有服务 × 所有集群:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/myorg/gitops
files:
- path: services/*/config.json
- clusters:
selector:
matchLabels:
env: prod注意:服务数 × 集群数 > 100 时,ArgoCD controller 压力显著增大,需调 --status-processors 和 --operation-processors。
Sync Waves:精确控制部署顺序#
默认 ArgoCD 尽可能并行应用所有资源。但有些场景需要严格顺序——CRD 必须先于使用它的资源,数据库迁移 Job 必须在 Deployment 之前完成。
通过 annotation 指定波次编号,从小到大逐波部署,每波等所有资源 healthy 后再进行下一波:
# Wave -2:先部署 CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
argocd.argoproj.io/sync-wave: "-2"
---
# Wave -1:创建 Namespace 和 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
# Wave 0:数据库迁移 Job(默认值)
apiVersion: batch/v1
kind: Job
metadata:
annotations:
argocd.argoproj.io/sync-wave: "0"
---
# Wave 1:主应用部署(等迁移完成)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"Sync Hooks:生命周期控制#
Hook 资源在特定同步阶段执行:
| Hook | 时机 | 典型用途 |
|---|---|---|
| PreSync | 同步前 | 数据库备份、前置检查 |
| Sync | 同步时 | 和主资源一起部署 |
| PostSync | 同步成功后 | 冒烟测试、发送通知 |
| SyncFail | 同步失败时 | 告警、回滚触发 |
apiVersion: batch/v1
kind: Job
metadata:
name: pre-sync-backup
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
template:
spec:
containers:
- name: backup
image: postgres:15
command: ["sh", "-c", "pg_dump $DATABASE_URL > /backup/$(date +%Y%m%d).sql"]
restartPolicy: Never多集群管理#
ArgoCD 的经典模式是中心化:一个 argocd 实例管理 N 个集群。
# 添加远程集群
argocd cluster add my-cluster --name my-cluster --label env=prod
# 查看已注册集群
argocd cluster list注意事项:
- argocd-server 需要能从网络层面访问所有被管集群的 apiserver。跨 region/跨 VPC 需打通专线或 VPN。
- 不同集群的 StorageClass、IngressClass 可能不同,用 Kustomize patch 覆盖。
- CN 集群镜像仓库地址不同,需要在 overlay 中替换 image registry。
PR 预览环境#
ApplicationSet 的 Pull Request Generator 可以为每个 PR 自动创建 preview 环境:
generators:
- pullRequest:
gitlab:
project: myorg/my-service
api: https://gitlab.com
tokenRef:
secretName: gitlab-token
key: token
template:
metadata:
name: 'preview-{{branch_slug}}-{{number}}'
spec:
source:
repoURL: https://gitlab.com/myorg/my-service.git
targetRevision: '{{head_sha}}'
path: overlays/preview
destination:
server: https://kubernetes.default.svc
namespace: 'preview-{{number}}'
syncPolicy:
automated:
prune: truePR 创建时自动部署 preview,PR 关闭时自动清理。这对前端/微服务联调非常有用。
Argo Rollouts:渐进式交付#
ArgoCD + Argo Rollouts 组合实现 GitOps 驱动的渐进式交付。Rollouts 引入 Rollout CRD 替代 Deployment,内嵌金丝雀/蓝绿策略,配合 Prometheus 指标自动晋级或回滚。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-svc
spec:
replicas: 5
strategy:
canary:
canaryService: my-svc-canary
stableService: my-svc-stable
trafficRouting:
istio:
virtualService: { name: my-svc }
steps:
- setWeight: 5
- pause: { duration: 5m }
- analysis:
templates: [{ templateName: success-rate }]
- setWeight: 25
- pause: { duration: 5m }
- analysis:
templates: [{ templateName: success-rate }]
- setWeight: 50
- analysis:
templates: [{ templateName: success-rate }]
- setWeight: 100任一 analysis Failed → 自动 setWeight 0 回滚(秒级切流量)。argocd-rollouts-extension 能在 Argo UI 里显示 rollout 状态条,集成紧密。
Image Updater:镜像自动更新#
ArgoCD Image Updater 监听镜像仓库,发现新 tag 后自动更新 GitOps 仓库里的镜像版本:
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: >
myapp=123456789.dkr.ecr.us-west-2.amazonaws.com/my-service
argocd-image-updater.argoproj.io/myapp.update-strategy: semver
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main流程:CI 构建推送镜像 → Image Updater 轮询发现 → 提交 Git → ArgoCD 同步 → 集群更新。生产环境必须用 write-back-method: git,默认的改 Application CR 模式违反 GitOps 原则。
回滚#
方式一:Git Revert(推荐)
git revert <commit-hash>
git push
argocd app get <app-name> # 确认同步状态方式二:ArgoCD History 回滚
argocd app history <app-name>
argocd app rollback <app-name> <history-id>注意:ArgoCD 回滚后,下次 sync 会把状态改回 Git HEAD。所以必须同时在 Git 做 revert。
方式三:紧急回滚(Prod)
argocd app set <app-name> --sync-policy none # 暂停自动同步
kubectl rollout undo deployment/<name> -n <namespace>
# 确认恢复后,Git revert 然后恢复同步策略大集群性能调优#
管理 100+ Application 时,默认配置会成为瓶颈:
# application-controller
--status-processors 20 # 并发处理 Application 状态(默认 20)
--operation-processors 10 # 并发执行同步操作(默认 10)
--app-resync-period 180 # reconcile 间隔(秒,默认 180)
# repo-server(无状态,可水平扩展)
--parallelismlimit 10 # 并发 manifest 生成数量
# application-controller sharding
env:
- name: ARGOCD_CONTROLLER_REPLICAS
value: "3" # 3 个副本分片管理所有 Application小结#
ArgoCD 的企业级成熟标志不是会用,而是能在几十个团队、几百个应用规模下稳定运行。Application + AppProject 是基础单元,ApplicationSet 是规模化利器(List/Cluster/Git/Matrix Generator 覆盖绝大多数批量场景),Sync Waves + Hooks 控制部署顺序和生命周期。生产环境永远 Manual Sync、必配 ignoreDifferences 避免 OutOfSync 误判。PR Generator 给每个 PR 开 preview 环境是开发体验的加分项。配合 Argo Rollouts 实现 GitOps 驱动的渐进式交付,是 Argo 全家桶的完整形态。