起因
K8s 部署演化:
kubectl apply -f手动(不知道现在集群什么状态)- CI script
kubectl apply自动化(但 git 跟 cluster 不一致仍可能) - GitOps:git 是 source of truth,controller 自动同步到 cluster
ArgoCD 是 GitOps controller。修改 yaml + push git → cluster 自动 apply。
diff / rollback / approval flow 全自动化。
装
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# https://localhost:8080
# 默认密码:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
第一个 Application
# argocd-apps/web.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: web
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: main
path: apps/web
destination:
server: https://kubernetes.default.svc
namespace: web
syncPolicy:
automated:
prune: true # git 删了 yaml → cluster 也删
selfHeal: true # 手动改 cluster → 自动 revert 回 git 状态
syncOptions:
- CreateNamespace=true
kubectl apply -f argocd-apps/web.yaml
argocd 会:
- clone git repo
- apply
apps/web/*.yaml到webnamespace - 持续监听 git → 有 change pull + apply
- 持续监听 cluster → drift 自动修复
UI
ArgoCD UI 显示:
- 所有 Application 健康状态
- 每 Application 的 K8s resource 图(service → deploy → pod)
- 跟 git desired state 的 diff
- sync 历史 + commit message
┌─ Application: web ──────────────────────────────────┐
│ Status: Synced Healthy │
│ Last sync: 2 min ago (commit abc123) │
│ ┌─Service──┐ ┌─Deployment──┐ ┌─Pod ×3─┐ │
│ │ web │ → │ web (3/3) │ → │ ... │ │
│ └──────────┘ └─────────────┘ └────────┘ │
└─────────────────────────────────────────────────────┘
kustomize / helm 支持
# Application 用 helm
spec:
source:
repoURL: https://github.com/myorg/charts
path: charts/web
helm:
values: |
replicaCount: 3
image:
tag: v1.2.3
或者 kustomize:
spec:
source:
path: overlays/production
kustomize:
images:
- myorg/web:v1.2.3
ApplicationSet(多 cluster / 多 env)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: web-multi-env
spec:
generators:
- list:
elements:
- cluster: prod
url: https://prod.k8s
values: values-prod.yaml
- cluster: staging
url: https://staging.k8s
values: values-staging.yaml
template:
metadata:
name: 'web-{{cluster}}'
spec:
destination:
server: '{{url}}'
namespace: web
source:
repoURL: ...
helm:
valueFiles:
- '{{values}}'
一份 template → 给 prod / staging 生成两个 Application。
git 改 → 两个 env 同步。
部署流程
1. dev 提 PR 改 image tag (v1.2.3 → v1.2.4)
2. PR review + merge to main
3. ArgoCD 检测 main 改动 (default 3 min polling 或 webhook 即时)
4. ArgoCD diff: deployment image change
5. ArgoCD apply: rolling update deployment
6. 健康 check 通过 → Sync success
整个过程 git 是源 + UI 可见。
错了 git revert → ArgoCD 自动 revert cluster。
image automation (argocd-image-updater)
不想手改 image tag → image-updater 监听 registry,新 tag 自动 commit
git:
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: web=myorg/web
argocd-image-updater.argoproj.io/web.update-strategy: semver
argocd-image-updater.argoproj.io/write-back-method: git
dev 推 image → image-updater 改 git → ArgoCD 同步 cluster。
全流程自动。
sync wave
metadata:
annotations:
argoproj.io/sync-wave: "1" # 先 apply(如 namespace / CRD)
metadata:
annotations:
argoproj.io/sync-wave: "2" # 后 apply(如 deployment)
控制 apply 顺序:CRD 先 → operator 后 → custom resource 最后。
sync hook
metadata:
annotations:
argoproj.io/hook: PreSync # apply 之前跑
argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myorg/migrate
command: ['./migrate.sh']
PreSync = 部署前跑 db migrate。
PostSync = 部署后跑 smoke test。
SyncFail = 失败时通知。
类似 helm hook。
与 FluxCD 对比
| ArgoCD | FluxCD | |
|---|---|---|
| 哲学 | UI + CLI first | CLI + GitOps Toolkit |
| UI | 强 | 弱(无官方 UI) |
| 配置 | Application CRD | Kustomization / HelmRelease |
| 多 cluster | ApplicationSet | 不擅长 |
| 学习 | 简单 UI 上手 | CLI 思维 |
| CNCF | graduated | graduated |
ArgoCD 适合 visual ops + 多 cluster。
Flux 适合 git-pure / 自动化 first。
我们用 ArgoCD(UI 让 dev 也能看部署状态,减少 ops 沟通)。
安全 / RBAC
# AppProject 限制
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: dev-team
spec:
sourceRepos:
- https://github.com/myorg/dev-manifests.git
destinations:
- namespace: 'dev-*'
server: '*'
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceWhitelist:
- group: 'apps'
kind: Deployment
dev team 只能从特定 git repo 部署到 dev-* namespace,不能改 cluster-wide 资源。
SSO 集成
ArgoCD 接 OIDC(Okta / Google / GitHub)→ 用 SSO 登录 UI + CLI。
# argocd-cm ConfigMap
data:
oidc.config: |
name: GitHub
issuer: https://github.com/login/oauth
clientID: ...
clientSecret: ...
真实部署 case
我们 prod + staging + 多个 dev cluster:
- 1 个 manifest repo(gitops/)
- 每 env 一个 ApplicationSet
- 每 app 在 manifest repo 下 apps//{base,overlays/{prod,staging}}/
- image-updater 自动 promotion staging(main branch tag)
- prod promotion 手动(PR + approval)
ops 改东西 = PR 改 yaml。dev 看 ArgoCD UI 知道部署进度。
不需要 dev 学 kubectl。
缺点
- Application CRD 增加学习
- ArgoCD 自身要运维(HA setup)
- bug:自动 sync 时偶有 race condition
踩过的坑
-
selfHeal 改不动 cluster:dev 手 kubectl edit 救火 → 5 秒被
ArgoCD revert。临时 disable selfHeal 或者改 git。 -
diff 噪声:cluster 自动加 annotation(如 deployment.kubernetes.io/revision)
→ ArgoCD 看到 diff。ignoreDifferences配置过滤。 -
CRD 顺序:先 install operator 再 apply custom resource。
sync-wave 控制。 -
大 manifest repo 慢:几千 yaml → ArgoCD slow。拆多 repo 或者
多 Application。 -
secret 不放 git:用 sealed-secret / external-secret operator,
git 存加密版本。
登录后参与评论。