GitOps与ArgoCD实践:声明式持续交付

系统讲解 GitOps 理念、ArgoCD 核心架构与实践、应用同步策略、自动回滚、多集群管理以及 sealed-secrets 密钥管理。

GitOps 将 Git 仓库作为基础设施和应用配置的单一可信源,通过自动化工具持续同步实际状态到期望状态。ArgoCD 是目前 Kubernetes 生态中最成熟的 GitOps 工具,被广泛用于生产环境的多集群持续交付。


目录


1. GitOps 核心理念

GitOps 由 Weaveworks 在 2017 年提出,核心原则:

  1. 声明式系统:系统配置描述期望状态,存储在版本控制中
  2. 版本控制:所有变更通过 Git 提交的审计追踪
  3. 自动同步:自动化工具持续将实际状态与 Git 中的期望状态对齐
  4. 差异化监控:实时可见实际状态与期望状态的差异

推拉模型对比

特性传统 CI/CD(Push)GitOps(Pull)
触发方CI 系统主动推送部署代理轮询拉取
凭证位置CI 系统需集群凭证集群只需 Git 凭证
安全性CI 暴露 K8s API 访问Git 凭证权限可严格控制
可见性需登录 CI 系统查看Git 提交即部署记录
回滚重新运行 PipelineGit Revert → 自动回滚

2. GitOps vs 传统 CI/CD

传统 CI/CD 流程

开发者 push → CI 构建镜像 → CI push 镜像 → CI kubectl apply
                    ↑                          │
                    └────── 需要 K8s 凭证 ─────┘

问题:CI 系统需要 K8s 集群的 admin 权限,凭证泄露风险高。

GitOps 流程

开发者 push → CI 构建镜像 → CI 更新 Git(镜像 tag)→ ArgoCD 自动同步到集群
                                 ↑
                          Git = 单一可信源

集群中的 ArgoCD 周期性地拉取 Git 仓库,检测到差异后自动或手动同步。


3. ArgoCD 架构

┌─────────────────────────────────────┐
│           ArgoCD                     │
│                                      │
│  ┌──────────────┐   ┌────────────┐  │
│  │   API Server │───│   Web UI   │  │
│  │              │   │  (管理界面) │  │
│  └──────┬───────┘   └────────────┘  │
│         │                            │
│  ┌──────▼───────┐   ┌────────────┐  │
│  │  Repository  │   │ Application│  │
│  │   Server     │   │ Controller │  │
│  │  (Git Repo)  │   │ (Reconcile)│  │
│  └──────┬───────┘   └─────┬──────┘  │
│         │                 │          │
│         └────────┬────────┘          │
│                  ↓                   │
│           ┌──────────┐               │
│           │  Redis   │ (状态缓存)    │
│           └──────────┘               │
└─────────────────────────────────────┘
                  ↓
         ┌─────────────────┐
         │ Target Clusters │ (K8s 集群)
         └─────────────────┘

核心组件

组件作用
API Server暴露 gRPC/REST API,Web UI 和 CLI 的入口
Repository Server克隆 Git 仓库、生成 K8s manifest
Application Controller监控 Application 状态,执行同步操作
Dex身份认证(SSO/OIDC/LDAP/GitHub)
Redis缓存 Git 状态和 K8s 资源状态

4. ArgoCD 安装与配置

安装

# 创建命名空间
kubectl create namespace argocd

# 安装 ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 暴露 UI(开发测试用)
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'

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

CLI 配置

# 安装 argocd CLI
brew install argocd

# 登录
argocd login argocd.example.com --username admin --password <password>

# 修改密码
argocd account update-password

添加 Git 仓库

# HTTPS 方式
argocd repo add https://github.com/example/gitops-repo.git \
  --username <user> --password <token>

# SSH 方式
argocd repo add git@github.com:example/gitops-repo.git \
  --ssh-private-key-path ~/.ssh/id_rsa

5. Application 定义

基础 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-api
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io   # 级联删除
spec:
  project: default                             # ArgoCD 项目
  source:
    repoURL: https://github.com/example/gitops-repo.git
    targetRevision: main                       # Git 分支/标签/SHA
    path: overlays/production/api
    # 支持 Helm、Kustomize、 plain YAML、Jsonnet
    # kustomize:
    #   namePrefix: prod-
    # helm:
    #   valueFiles:
    #     - values-production.yaml
  destination:
    server: https://kubernetes.default.svc     # 本集群,外部集群填 API Endpoint
    namespace: production
  syncPolicy:
    automated:
      prune: true          # 删除 Git 中不存在的资源
      selfHeal: true       # 自动修复手动修改
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - PruneLast=true
  revisionHistoryLimit: 10

ApplicationSet(多环境/多集群)

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: api-applications
  namespace: argocd
spec:
  generators:
    # 生成器:基于 Git 目录结构
    - git:
        repoURL: https://github.com/example/gitops-repo.git
        revision: main
        directories:
          - path: overlays/*
  template:
    metadata:
      name: '{{path.basename}}-api'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/gitops-repo.git
        targetRevision: main
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

ApplicationSet 自动生成多个 Application:

  • overlays/development/ → Application: development-api
  • overlays/staging/ → Application: staging-api
  • overlays/production/ → Application: production-api

集群生成器(多集群)

spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
        values:
          branch: main
  template:
    spec:
      source:
        targetRevision: '{{values.branch}}'
      destination:
        name: '{{name}}'   # 引用集群名

6. 同步策略与自动化

同步策略配置

syncPolicy:
  automated:
    prune: true           # Git 删除资源时,集群也删除
    selfHeal: true        # 集群手动修改后,自动恢复到 Git 状态
  retry:
    limit: 5
    backoff:
      duration: 5s
      factor: 2
      maxDuration: 3m
  syncOptions:
    - CreateNamespace=true          # 自动创建目标 Namespace
    - PrunePropagationPolicy=foreground  # 前台删除,等待资源清理完成
    - PruneLast=true                # 先创建/更新,最后删除
    - ApplyOutOfSyncOnly=true       # 仅同步差异资源,加快同步速度

手动同步控制

# 查看应用状态
argocd app get production-api

# 手动同步
argocd app sync production-api

# 同步特定资源
argocd app sync production-api --resource apps:Deployment:api-server

# 查看同步历史
argocd app history production-api

# 回滚到历史版本
argocd app rollback production-api 3

资源钩(Hooks)

ArgoCD 支持在同步生命周期中执行 Hook:

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/hook: PreSync        # Sync 前执行
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: myapp:latest
          command: ["python", "manage.py", "migrate"]
Hook 类型触发时机
PreSync同步前
Sync和应用资源一起
PostSync同步成功且健康后
SyncFail同步失败后

7. 多集群管理

添加外部集群

# 在目标集群创建 ServiceAccount
kubectl create sa argocd-manager -n kube-system
kubectl create clusterrolebinding argocd-manager-role \
  --clusterrole=cluster-admin --serviceaccount=kube-system:argocd-manager

# 获取 Token
kubectl get secret $(kubectl get sa argocd-manager -n kube-system -o jsonpath='{.secrets[0].name}') \
  -n kube-system -o jsonpath='{.data.token}' | base64 -d

# 在 ArgoCD 中注册集群
argocd cluster add <context-name> --name production-eks

多集群 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api-us-east
spec:
  source:
    repoURL: https://github.com/example/gitops-repo.git
    targetRevision: main
    path: base/api
  destination:
    name: production-eks-us-east    # 引用注册的集群名
    namespace: production

8. 密钥管理:Sealed Secrets

GitOps 的核心矛盾:配置放在 Git 中,但密钥不能明文存储

Sealed Secrets 方案

# 安装 kubeseal CLI 和 controller
brew install kubeseal
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# 1. 创建普通 Secret
kubectl create secret generic db-password \
  --from-literal=password='S3cr3t!' \
  --dry-run=client -o yaml > secret.yaml

# 2. 加密为 SealedSecret
kubeseal --controller-namespace=kube-system < secret.yaml > sealed-secret.yaml

# 3. 提交 sealed-secret.yaml 到 Git(安全,可以公开存放)
git add sealed-secret.yaml && git commit

# 4. ArgoCD 同步到集群后,controller 自动解密为普通 Secret
kubectl get secret db-password -o yaml

SealedSecret 由集群公钥加密,只能由安装了对应私钥的集群解密

替代方案对比

方案原理Git 安全适用场景
Sealed Secrets集群公钥加密单集群,简单场景
External Secrets Operator同步 Vault/AWS SM多集群,企业级
SOPSAge/GPG 加密✅(密钥不在 Git)Flux 用户
Helm SecretsSOPS + HelmHelm 用户

9. 生产最佳实践

项目隔离

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: production
  namespace: argocd
spec:
  description: "生产环境项目"
  sourceRepos:
    - https://github.com/example/gitops-repo.git
  destinations:
    - namespace: production
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:    # 允许操作集群级别资源
    - group: ''
      kind: Namespace
  namespaceResourceBlacklist:  # 禁止操作敏感资源
    - group: ''
      kind: ResourceQuota
  roles:
    - name: developer
      description: "开发者只读权限"
      policies:
        - p, proj:production:developer, applications, get, production/*, allow

RBAC 集成

# ArgoCD 配置 RBAC
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.default: role:readonly
  policy.csv: |
    p, role:developer, applications, sync, production/*, allow
    p, role:admin, *, *, *, allow
    g, github-org:my-team, role:developer

监控与告警

# Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: argocd-metrics
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: argocd-metrics
  endpoints:
    - port: metrics
      path: /metrics

关键监控指标:

# 应用不同步状态
argocd_app_info{sync_status="OutOfSync"}

# 同步失败计数
argocd_app_sync_total{phase!="Succeeded"}

灾难恢复

# 导出所有 ArgoCD 配置
echo "备份 Application..."
kubectl get applications -n argocd -o yaml > argocd-backup.yaml

# ArgoCD 本身也可用 GitOps 管理(App of Apps 模式)
# Git 中存放所有 Application 定义,ArgoCD 自托管

总结

主题核心要点
GitOps 理念Git 单一可信源,声明式、版本化、自动化
ArgoCD 架构API Server + Repo Server + Controller + Redis
Application声明 Git 源、目标集群、同步策略
ApplicationSet批量生成应用,支持多环境多集群
同步策略automated/prune/selfHeal + Hooks
密钥管理Sealed Secrets / ESO / SOPS
多集群argocd cluster add + Application destination.name

GitOps 不是工具的替代,而是工作范式的转变:将变更的审批和审计从 CI 流水线迁移到 Git 工作流,使基础设施变更与代码变更一样可追溯、可回滚、可 review。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「云原生」更多文章

  1. Kubernetes多集群联邦:Karmada、Crossplane与Istio多集群实战
  2. CNCF云原生技术全景图:从毕业项目到前沿方向
  3. 容器运行时深度解析:从runc到containerd到安全容器