饮墨

子安饮墨馀三斗,留与卿儿作赋来

用 Argo CD 实现 GitOps 持续部署:3 步将 K8s 应用交付从手动 apply 升级到自动同步

痛点:kubectl apply 管不住多集群、多环境

团队规模一大,Kubernetes 的应用交付就开始失控:

  • 配置漂移:有人直接 kubectl edit 改了线上 Deployment,Git 仓库里的 YAML 和实际运行状态对不上
  • 回滚靠记忆:上次部署是谁操作的、改了什么、怎么回退,全凭口头沟通
  • 多环境同步难:dev / staging / prod 三套集群,手动逐个 apply 容易漏、容易错

GitOps 的核心理念是:Git 仓库是唯一事实来源(Single Source of Truth),集群状态必须和 Git 声明一致。Argo CD 就是落地 GitOps 最成熟的开源工具。

方案:Argo CD 做了什么

Argo CD 是一个 Kubernetes 原生的持续部署控制器,核心逻辑很简单:

  1. 监听 Git 仓库中的 Kubernetes manifest(YAML / Helm / Kustomize)
  2. 持续对比 Git 声明状态 vs 集群实际状态
  3. 发现差异(OutOfSync)时自动或手动触发同步(Sync)

架构上它部署在目标 K8s 集群内,通过 Application CRD 管理每个应用的来源和目标。

核心优势对比:

维度 传统 CI/CD push 模式 Argo CD GitOps pull 模式
部署触发 CI pipeline 推送到集群 集群主动拉取 Git 变更
权限暴露 CI 需要集群 admin 凭据 仅 Argo CD 内部有权限
配置漂移检测 实时检测并告警
回滚 需要重跑 pipeline git revert 即回滚
审计追踪 靠 CI 日志 Git commit history

实操:3 步在生产集群落地 Argo CD

第 1 步:安装 Argo CD

# 创建命名空间
kubectl create namespace argocd

# 安装稳定版(以 v2.13 为例)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.13.3/manifests/install.yaml

# 等待所有 Pod Ready
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/part-of=argocd -n argocd --timeout=300s

# 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

生产环境建议用 Helm Chart 安装,方便管理 HA 模式和自定义配置:

helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd -n argocd \
  --set server.replicas=2 \
  --set controller.replicas=2 \
  --set redis-ha.enabled=true

第 2 步:创建 Application 资源

假设你的 Git 仓库结构如下:

k8s-manifests/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
└── overlays/
    ├── dev/
    ├── staging/
    └── prod/
        └── kustomization.yaml

创建 Argo CD Application:

# argocd-app-prod.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-prod
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/yourorg/k8s-manifests.git
    targetRevision: main
    path: overlays/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp
  syncPolicy:
    automated:
      prune: true        # 删除 Git 中已移除的资源
      selfHeal: true     # 自动修复配置漂移
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
    retry:
      limit: 3
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
kubectl apply -f argocd-app-prod.yaml

关键字段说明: - automated.prune: true — Git 中删掉的资源,集群里也会自动清理 - automated.selfHeal: true — 有人手动改了集群资源,Argo CD 会自动恢复到 Git 定义的状态 - ServerSideApply — 避免大 manifest 的 annotation 超限问题

第 3 步:配置 Webhook + RBAC 加速与管控

配置 Git Webhook 缩短同步延迟:

Argo CD 默认每 3 分钟轮询 Git,配置 Webhook 可实现秒级响应:

# GitHub Webhook URL(Argo CD Server 的 /api/webhook 端点)
# Settings -> Webhooks -> Payload URL:
# https://argocd.yourdomain.com/api/webhook
# Content type: application/json
# Secret: 与 argocd-secret 中的 webhook.github.secret 一致

argocd-secret 中添加 Webhook Secret:

kubectl -n argocd patch secret argocd-secret -p '{"stringData": {"webhook.github.secret": "your-webhook-secret"}}'

配置 RBAC 限制操作权限:

# argocd-rbac-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    # 开发团队只能查看和同步,不能删除
    p, role:developer, applications, get, */*, allow
    p, role:developer, applications, sync, */*, allow
    # SRE 团队有完整权限
    p, role:sre, applications, *, */*, allow
    p, role:sre, clusters, *, *, allow
    # 绑定 SSO group
    g, dev-team, role:developer
    g, sre-team, role:sre
  policy.default: role:readonly

避坑:3 个生产环境常见问题

1. Secret 管理不要裸放 Git

Git 仓库存明文 Secret 是大忌。推荐方案:

  • Sealed Secrets:加密后的 SealedSecret 可以安全存 Git,集群内控制器解密
  • External Secrets Operator:从 Vault / AWS Secrets Manager 动态拉取
  • SOPS + age:用 Mozilla SOPS 加密 YAML 中的敏感字段
# 示例:用 Sealed Secrets
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
# sealed-secret.yaml 可以安全提交到 Git

2. 大规模 Application 用 ApplicationSet 批量管理

管理 50+ 微服务时,逐个写 Application YAML 不现实:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: all-microservices
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: https://github.com/yourorg/k8s-manifests.git
        revision: main
        directories:
          - path: services/*
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/yourorg/k8s-manifests.git
        targetRevision: main
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'

3. 同步波次(Sync Wave)控制部署顺序

数据库 migration 要在应用 Deployment 之前执行:

# 在 Job 的 annotations 中指定 wave
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"  # 负数先执行
---
# Deployment wave 默认为 0,会在 Job 之后同步

总结

动作 命令 / 配置
安装 Argo CD kubectl apply -f install.yaml 或 Helm Chart
创建应用 Application CRD + syncPolicy.automated
自动修复漂移 selfHeal: true
加速同步 配置 Git Webhook
批量管理 ApplicationSet generators
安全回滚 git revert → 自动同步

Argo CD 解决的核心问题是:让 Git 成为集群状态的唯一权威来源,消灭配置漂移和手动操作风险。对于已经有 CI 流水线(GitHub Actions / GitLab CI)的团队,只需要把 CI 的职责收缩到"构建镜像 + 更新 Git 中的镜像 tag",部署环节完全交给 Argo CD,职责清晰、权限最小化。

落地建议:先在非生产环境跑起来,开启 selfHeal 观察一周,确认没有误操作后再推到 prod 集群。

您还没有登录,请登录后发表评论。