ArgoCD:把 K8s 部署做成 GitOps(git 是单一真理)

起因

K8s 部署演化:

  1. kubectl apply -f 手动(不知道现在集群什么状态)
  2. CI script kubectl apply 自动化(但 git 跟 cluster 不一致仍可能)
  3. 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 会:

  1. clone git repo
  2. apply apps/web/*.yamlweb namespace
  3. 持续监听 git → 有 change pull + apply
  4. 持续监听 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

踩过的坑

  1. selfHeal 改不动 cluster:dev 手 kubectl edit 救火 → 5 秒被
    ArgoCD revert。临时 disable selfHeal 或者改 git。

  2. diff 噪声:cluster 自动加 annotation(如 deployment.kubernetes.io/revision)
    → ArgoCD 看到 diff。ignoreDifferences 配置过滤。

  3. CRD 顺序:先 install operator 再 apply custom resource。
    sync-wave 控制。

  4. 大 manifest repo 慢:几千 yaml → ArgoCD slow。拆多 repo 或者
    多 Application。

  5. secret 不放 git:用 sealed-secret / external-secret operator,
    git 存加密版本。

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。