ArgoCD GitOps 部署

ArgoCD 是声明式的、GitOps 持续交付工具,用于在 Kubernetes 集群中自动部署应用程序。它通过监听 Git 仓库中的声明式配置文件,自动将集群状态同步到期望状态。

核心概念

概念 说明
Application ArgoCD 管理的应用,指向 Git 仓库和集群目标
ApplicationSet 批量创建 Application,支持跨集群、多环境
Project 隔离资源,控制 Application 的部署范围
Sync Policy 同步策略:手动、自动、半自动
Health Check 健康检查,评估 Kubernetes 资源状态
Rollback 一键回滚到 Git 仓库中的任意版本

安装 ArgoCD

使用 kubectl 安装


# 创建命名空间
kubectl create namespace argocd

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

# 安装 HA 版本(生产环境推荐)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml

使用 Helm 安装


helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  --set server.service.type=LoadBalancer \
  --values values-production.yaml

访问 ArgoCD UI


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

# 端口转发(开发环境)
kubectl port-forward svc/argocd-server -n argocd 8080:443

# CLI 登录
argocd login localhost:8080 --username admin --password <password>

创建 Application

方式一:UI 创建

1. 打开 ArgoCD UI → + New App

2. 填写 Application 名称和项目

3. 配置 Git 仓库 URL

4. 设置目标集群和命名空间

5. 配置同步策略和健康检查

方式二:CLI 创建


argocd app create myapp \
  --repo https://github.com/example/k8s-manifests.git \
  --path ./myapp \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace production \
  --sync-policy automated \
  --self-heal \
  --auto-prune

方式三:声明式 YAML


apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/example/k8s-manifests.git
    targetRevision: HEAD
    path: ./myapp
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - PruneLast=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas
  revisionHistoryLimit: 10

ApplicationSet 批量部署

跨多集群、多环境批量创建 Application:


apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-multicluster
  namespace: argocd
spec:
  generators:
    - matrix:
        generators:
          - clusters:
              selector:
                matchLabels:
                  environment: production
          - git:
              repoURL: https://github.com/example/k8s-config.git
              revision: HEAD
              directories:
                - path: environments/*
  template:
    metadata:
      name: 'myapp-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/k8s-manifests.git
        path: './myapp'
        helm:
          valueFiles:
            - values-{{name}}.yaml
      destination:
        server: '{{server}}'
        namespace: myapp
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

Rollout 金丝雀发布

集成 Argo Rollouts 实现金丝雀发布、蓝绿部署:


apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp
spec:
  replicas: 3
  strategy:
    canary:
      analysis:
        templates:
          - templateName: success-rate
        args:
          - name: service-name
            value: myapp-canary
      canaryService: myapp-canary
      stableService: myapp-stable
      trafficRouting:
        nginx:
          stableIngress: myapp-ingress
          additionalIngressAnnotations:
            canary-by-header: X-Canary
      steps:
        - setWeight: 5
        - pause: {duration: 10m}
        - setWeight: 20
        - pause: {duration: 10m}
        - setWeight: 50
        - pause: {duration: 10m}
        - setWeight: 80
        - pause: {duration: 5m}
        - setWeight: 100
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myapp:latest
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"

Webhook 集成

配置 Git Webhook 触发自动同步:


# 获取 ArgoCD Webhook Secret
argocd admin settings generateSpec argocd-secret \
  --kubeconfig ~/.kube/config \
  --auth-token-name auth-token \
  --auth-token \
  > webhook-secret.yaml

# 在 GitHub/GitLab 配置 Webhook
# Payload URL: https://argocd.example.com/api/webhook
# Secret: <your-webhook-secret>

SSO 集成(Dex + LDAP)


# argocd-cm ConfigMap
data:
  url: https://argocd.example.com
  dex.config: |
    connectors:
      - type: ldap
        id: ldap
        name: LDAP
        config:
          host: ldap.example.com:636
          insecure: false
          bindDN: cn=admin,dc=example,dc=com
          bindPW: <admin-password>
          userSearch:
            baseDN: ou=users,dc=example,dc=com
            filter: (objectClass=person)
            username: uid
            idAttr: uid
            emailAttr: mail
            nameAttr: givenName
          groupSearch:
            baseDN: ou=groups,dc=example,dc=com
            filter: (objectClass=groupOfNames)
            userAttr: member
            groupAttr: cn
            nameAttr: cn

配置管理

应用级别 Sync Wave

控制资源同步顺序:


# deployment.yaml (wave 0)
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "0"
spec:
  ...

# service.yaml (wave 1)
apiVersion: v1
kind: Service
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "1"
spec:
  ...

# ingress.yaml (wave 2)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "2"
spec:
  ...

资源修剪策略


# 手动修剪已删除的资源
argocd app sync myapp --prune

# 强制同步(覆盖集群状态)
argocd app sync myapp --force

监控与告警

Prometheus Metrics


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

ArgoCD Notifications + Slack


apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  service.slack: |
    apiURL: https://slack.com/api/chat.postMessage
    token: $slack-token
  trigger.on-sync-succeeded: |
    - when: status.operationState.phase == 'Succeeded'
      oncePer: status.operationState.syncResult.revision
      send:
        - app-sync-succeeded
  template.app-sync-succeeded: |
    message: |
      ✅ App {{.app.metadata.name}} synced successfully
      Revision: {{.app.status.operationState.syncResult.revision}}

故障排除


# 查看 Application 同步状态
argocd app get myapp

# 列出所有 Application
argocd app list

# 查看资源差异
argocd app diff myapp

# 手动同步
argocd app sync myapp

# 卸载 Application(保留集群资源)
argocd app delete myapp --cascade=false

# 查看 ArgoCD Server 日志
kubectl logs -n argocd deployment/argocd-server -f
kubectl logs -n argocd statefulset/argocd-application-controller -f

最佳实践

  • Git 作为唯一真相来源:所有 Kubernetes 资源声明必须存在于 Git 中
  • 分支策略:使用 main 作为稳定分支,功能分支用于预览
  • 蓝绿部署:使用 Argo Rollouts 实现零 downtime 部署
  • 多环境管理:使用 values-{env}.yaml 管理不同环境配置
  • Resource Hooks:使用 PreSync、Sync、PostSync Hook 执行数据库迁移
  • App of Apps:使用顶层 Application 管理子 Application,实现分层治理

下一步