文章

ArgoCD GitOps 实战

ArgoCD GitOps 实战

概述

ArgoCD 是声明式 GitOps 持续部署工具,核心理念:Git 仓库是 Kubernetes 集群状态的唯一真实来源。ArgoCD 持续监控 Git 仓库变化,自动同步到目标集群,并检测配置漂移(Drift Detection)。

GitOps 核心原则

         Git Repo(唯一声明源)

        ┌─────┴─────┐
        │   ArgoCD   │
        │ Controller │
        └─────┬─────┘
     ┌───────┼───────┐
     ↓       ↓       ↓
  Cluster  Cluster  Cluster
原则说明
声明式所有 K8s 资源配置文件存在 Git 中
版本化每次变更都是 Git Commit,可回溯/回滚
自动同步ArgoCD 自动将 Git 状态同步到集群
持续调和检测实际状态与 Git 声明的差异(Drift)

Application CRD —— 核心资源

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io  # 删除 App 时级联删除 K8s 资源
spec:
  project: default
  source:
    repoURL: https://github.com/example/gitops
    targetRevision: main                     # 监控的分支/标签/commit
    path: apps/my-app/overlays/production    # Helm/Kustomize/Plain YAML 路径

    # Helm 示例
    # helm:
    #   valueFiles:
    #   - values-prod.yaml

    # Kustomize 示例
    # kustomize:
    #   namePrefix: prod-

  destination:
    server: https://kubernetes.default.svc    # 目标集群 API
    namespace: production                     # 部署命名空间

  syncPolicy:
    automated:                                # 自动同步
      prune: true                             # 删除 Git 中不存在的资源
      selfHeal: true                          # 自动修复漂移
      allowEmpty: false                       # 不允许空资源
    syncOptions:
    - CreateNamespace=true                    # 自动创建命名空间
    - PrunePropagationPolicy=foreground       # 级联删除

  # 健康检查忽略特定资源
  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas                          # HPA 动态调整 replica 不计入 Drift

Sync 策略

手动同步 vs 自动同步

策略automated: falseautomated: true
触发方式手动点击 Sync / CLI / APIArgoCD 自动检测 Git 变化
适用生产环境(需人工确认)开发/测试环境
安全低(需 PR 审查 + CodeOwner)

Sync 窗口(维护窗口控制)

spec:
  syncPolicy:
    syncWindows:
    - kind: deny                # 禁止同步窗口
      schedule: '0 8 * * 1'    # 每周一 8:00
      duration: 4h              # 持续 4 小时
      applications:
      - '*-prod'                # 仅禁止生产应用
      namespaces:
      - production

多集群管理

# 注册外部集群(通过 argocd CLI)
argocd cluster add <cluster-context>

# Application 指定不同集群
spec:
  destination:
    server: https://cluster-a.example.com    # 指定集群
    namespace: production
---
spec:
  destination:
    server: https://cluster-b.example.com
    namespace: staging

App of Apps 模式(管理 ArgoCD 自身)

# root-app.yaml —— 管理其他 Application 的 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/gitops
    path: apps/                          # 此目录下所有子目录都是 App 声明
    directory:
      recurse: true
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
gitops-repo/
└── apps/
    ├── app-a/
    │   └── overlays/
    │       └── production/      → ArgoCD Application A
    ├── app-b/
    │   └── overlays/
    │       └── production/      → ArgoCD Application B
    └── app-c/
        └── overlays/
            └── production/      → ArgoCD Application C

部署策略:蓝绿 vs 金丝雀

ArgoCD 本身不做流量切分,需配合 K8s Service/Ingress 或 Argo Rollouts。

# Argo Rollouts —— 金丝雀发布(CRD)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20             # 20% 流量
      - pause: { duration: 5m }   # 等待 5 分钟(观察监控)
      - setWeight: 50             # 50% 流量
      - pause: {}
      - setWeight: 100            # 全量
      maxSurge: "25%"
      maxUnavailable: 0
# Argo Rollouts —— 蓝绿发布
spec:
  strategy:
    blueGreen:
      activeService: my-app-active
      previewService: my-app-preview
      autoPromotionEnabled: false   # 手动确认后才切换
      prePromotionAnalysis:         # 切换前自动分析
        templates:
        - templateName: smoke-test

CLI 常用命令

# 登录
argocd login argocd.example.com --sso

# 查看
argocd app list
argocd app get my-app
argocd app diff my-app              # 显示 Git vs 集群差异
argocd app history my-app           # 部署历史

# 操作
argocd app sync my-app              # 手动同步
argocd app sync my-app --dry-run    # 预演
argocd app rollback my-app 3        # 回滚到版本 3
argocd app delete my-app            # 删除 Application
argocd app terminate-op my-app      # 终止正在进行的操作

# 强制覆盖(紧急回滚)
argocd app sync my-app --force --prune

日常运维要点

监控健康状态

# 查看整体健康
argocd app list
# 输出:NAME    NAMESPACE    STATUS    HEALTH    SYNC STATUS
#      my-app  production   Synced    Healthy   Synced
状态含义行动
Healthy所有 Pod Ready✅ 正常
Progressing正在部署等待
DegradedPod CrashLoop/ImagePullBackoff排查
Missing资源完全不存在同步
SuspendedHPA 等暂停检查

Drift Detection 漂移检测

argocd app diff my-app
# 显示哪些资源的实际状态与 Git 声明不一致

常见漂移来源:

  • 手动 kubectl edit/scale 修改(打破 GitOps 原则)
  • HPA 动态调整 replicas(需 ignoreDifferences 配置)
  • Operator 自动修改资源(如 cert-manager 注入字段)

权限与 RBAC

# argocd-rbac-cm ConfigMap
policy.csv: |
  p, role:developer, applications, get, *, allow
  p, role:developer, applications, sync, *, deny    # 开发者不能手动 Sync
  p, role:admin, applications, *, *, allow
  g, dev-team, role:developer
  g, platform-team, role:admin

常见问题 / 坑点

问题原因解决方案
一直 OutOfSyncHelm Render 的值与集群实际不符检查 values 文件 + 环境差异
手动改的资源被自动回滚selfHeal: true接受 GitOps 约束,任何变更走 PR
删除 Application 后资源还留着未设 finalizersresources-finalizer.argocd.argoproj.io
Secret 明文存在 Git 中直接提交 Secret YAML用 Sealed Secrets / External Secrets Operator
所有集群共用一个 ArgoCD单点故障同集群部署或 Hub-Spoke 模式
Progressing 一直不完成Deployment 不 Readykubectl describe 排查 Pod 启动问题

关联知识

参考资源

学习时间

阶段时间备注
初次学习2026-07-14Application CRD + Sync + 多集群 + Rollouts

状态: 📖 已掌握 下次复习日期: 2026-08-14