Argo CI/CD 完全指南:从构建到部署的每一步详解

Argo CI/CD 完全指南:从构建到部署的每一步详解

前言

Argo 是 Kubernetes 原生 CI/CD 解决方案,由两个核心组件组成:

组件 职责 类比
Argo Workflows CI(持续集成):构建、测试、打包 Jenkins/GitLab CI
Argo CD CD(持续部署):声明式 GitOps 部署 Spinnaker/Flux

一句话总结:Argo Workflows 负责”构建出什么”,Argo CD 负责”把什么部署到哪里”。


第一部分:Argo Workflows — CI 流程详解

1.1 什么是 Argo Workflows

Argo Workflows 是一个 Kubernetes 原生工作流引擎,用于编排并行执行的容器任务。每个任务(Step)都是一个 Pod,任务之间通过 Artifact(产物)传递数据。

1.2 CI 流程的四个核心步骤

┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
│  代码拉取  │───▶│  编译构建  │───▶│  单元测试  │───▶│  镜像推送  │
│  (Checkout)│   │ (Build)  │   │  (Test)  │   │  (Push)  │
└─────────┘    └─────────┘    └─────────┘    └─────────┘
     │              │              │              │
     ▼              ▼              ▼              ▼
  Git Repo      Dockerfile     测试报告        Docker Hub

1.3 完整 CI 工作流示例

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: ci-pipeline-
  namespace: argo
spec:
  entrypoint: ci-pipeline
  serviceAccountName: argo-sa
  # 全局参数
  arguments:
    parameters:
    - name: git-repo
      value: "https://github.com/your-org/your-app.git"
    - name: git-revision
      value: "main"
    - name: image-tag
      value: "latest"

  # 模板定义
  templates:
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 主流程:定义步骤执行顺序
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  - name: ci-pipeline
    steps:
    - - name: checkout
        template: git-checkout

    - - name: build
        template: docker-build
        arguments:
          artifacts:
          - name: source-code
            from: "{{steps.checkout.outputs.artifacts.source-code}}"

    - - name: test
        template: unit-test
        arguments:
          artifacts:
          - name: source-code
            from: "{{steps.checkout.outputs.artifacts.source-code}}"

    - - name: push
        template: docker-push
        arguments:
          artifacts:
          - name: image
            from: "{{steps.build.outputs.artifacts/image}}"

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 步骤 1:代码拉取 (Checkout)
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  - name: git-checkout
    container:
      image: alpine/git:2.0
      command: [sh, -c]
      args:
      - |
        git clone {{workflow.parameters.git-repo}} /workspace
        cd /workspace
        git checkout {{workflow.parameters.git-revision}}
        echo "Checkout completed at $(date)"
    outputs:
      artifacts:
      - name: source-code
        path: /workspace

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 步骤 2:编译构建 (Build)
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  - name: docker-build
    inputs:
      artifacts:
      - name: source-code
        path: /workspace
    container:
      image: docker:24-dind
      command: [sh, -c]
      args:
      - |
        cd /workspace
        # 构建镜像
        docker build -t my-app:{{workflow.parameters.image-tag}} .
        # 输出镜像引用供下一步使用
        echo "my-app:{{workflow.parameters.image-tag}}" > /tmp/image-name
    outputs:
      artifacts:
      - name: image
        path: /tmp/image-name

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 步骤 3:单元测试 (Test)
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  - name: unit-test
    inputs:
      artifacts:
      - name: source-code
        path: /workspace
    container:
      image: golang:1.21
      command: [sh, -c]
      args:
      - |
        cd /workspace
        go test -v ./... -coverprofile=coverage.out
        go tool cover -html=coverage.out -o coverage.html
        echo "Test completed, coverage: $(go tool cover -func=coverage.out | grep total)"
    outputs:
      artifacts:
      - name: test-report
        path: /workspace/coverage.html
      - name: test-results
        path: /workspace/coverage.out

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 步骤 4:镜像推送 (Push)
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  - name: docker-push
    inputs:
      artifacts:
      - name: image
        path: /tmp/image-name
    container:
      image: docker:24
      env:
      - name: DOCKER_REGISTRY
        value: "registry.example.com"
      - name: DOCKER_USER
        valueFrom:
          secretKeyRef:
            name: docker-credentials
            key: username
      - name: DOCKER_PASS
        valueFrom:
          secretKeyRef:
            name: docker-credentials
            key: password
      command: [sh, -c]
      args:
      - |
        IMAGE_NAME=$(cat /tmp/image-name)
        docker login $DOCKER_REGISTRY -u $DOCKER_USER -p $DOCKER_PASS
        docker tag $IMAGE_NAME $DOCKER_REGISTRY/$IMAGE_NAME
        docker push $DOCKER_REGISTRY/$IMAGE_NAME
        echo "Pushed: $DOCKER_REGISTRY/$IMAGE_NAME"

1.4 每个步骤的详细说明

步骤 1:代码拉取 (Checkout)

项目 说明
目的 从 Git 仓库拉取最新代码
输入 Git 仓库地址、分支/Tag
输出 源代码(作为 Artifact 传递给后续步骤)
关键点 使用 outputs.artifacts 将代码传递给下一步

常见问题

# 使用 SSH 克隆(需要配置 SSH Key)
args:
- |
  mkdir -p ~/.ssh
  echo "{{secrets.ssh-private-key}}" > ~/.ssh/id_rsa
  chmod 600 ~/.ssh/id_rsa
  git clone git@github.com:org/repo.git /workspace

# 使用 Token 克隆
args:
- |
  git clone https://{{secrets.github-token}}@github.com/org/repo.git /workspace

步骤 2:编译构建 (Build)

项目 说明
目的 编译代码、构建 Docker 镜像
输入 源代码(来自上一步的 Artifact)
输出 Docker 镜像引用
关键点 使用 docker:dind(Docker-in-Docker)或 kaniko

Docker-in-Docker vs Kaniko

# 方案 A:Docker-in-Docker(需要特权模式)
container:
  image: docker:24-dind
  securityContext:
    privileged: true

# 方案 B:Kaniko(推荐,无需特权)
container:
  image: gcr.io/kaniko-project/executor:latest
  args:
  - --context=/workspace
  - --dockerfile=/workspace/Dockerfile
  - --destination=registry.example.com/my-app:{{workflow.parameters.image-tag}}

步骤 3:单元测试 (Test)

项目 说明
目的 运行单元测试、生成测试报告
输入 源代码
输出 测试报告、覆盖率报告
关键点 测试失败时工作流自动终止

测试失败处理

- name: unit-test
  container:
    image: golang:1.21
    command: [sh, -c]
    args:
    - |
      go test -v ./... 
      # 非零退出码会自动失败工作流
  # 可选:失败时执行清理
  onExit:
    template: cleanup

步骤 4:镜像推送 (Push)

项目 说明
目的 将构建的镜像推送到镜像仓库
输入 镜像引用(来自构建步骤)
输出 推送成功的镜像地址
关键点 使用 Secret 管理镜像仓库凭证

Secret 配置

# 创建 Docker 仓库凭证 Secret
kubectl create secret generic docker-credentials 
  --from-literal=username=myuser 
  --from-literal=password=mypassword 
  -n argo

第二部分:Argo CD — CD 流程详解

2.1 什么是 Argo CD

Argo CD 是一个声明式的 GitOps 持续部署工具。它的核心思想是:Git 仓库是单一事实来源,集群状态应该与 Git 中定义的状态保持一致。

2.2 GitOps 工作原理

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Git 仓库    │────▶│   Argo CD    │────▶│  Kubernetes  │
│ (声明式配置)  │     │  (同步控制器) │     │   集群       │
└──────────────┘     └──────────────┘     └──────────────┘
      │                     │                    │
      │  1. 检测变更         │  2. 拉取配置        │
      │◀─────────────────────│                    │
      │                     │                    │
      │                     │  3. 应用配置         │
      │                     │─────────────────────▶│
      │                     │                    │
      │  4. 同步状态报告     │◀───────────────────│
      │◀─────────────────────│                    │

2.3 CD 流程的四个核心步骤

┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│  提交配置 │──▶│  自动同步 │──▶│  健康检查 │──▶│  回滚/通知 │
│  (Commit)│   │ (Sync)   │   │ (Health) │   │ (Rollback)│
└──────────┘   └──────────┘   └──────────┘   └──────────┘

2.4 完整的 CD 配置示例

步骤 1:创建 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # Git 仓库配置(单一事实来源)
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  source:
    repoURL: https://github.com/your-org/argocd-manifests.git
    targetRevision: main
    path: manifests/my-app  # Git 仓库中的路径

    # 可选:使用 Helm
    # helm:
    #   valueFiles:
    #   - values-prod.yaml
    #   parameters:
    #   - name: image.tag
    #     value: "v1.2.3"

    # 可选:使用 Kustomize
    # kustomize:
    #   images:
    #   - my-app:v1.2.3

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 目标集群配置
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  destination:
    server: https://kubernetes.default.svc  # 本地集群
    # server: https://192.168.1.100:6443    # 远程集群
    namespace: production                   # 目标命名空间

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 同步策略配置
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  syncPolicy:
    automated:
      prune: true      # 自动删除 Git 中不存在的资源
      selfHeal: true   # 自动修复集群中的漂移配置
    syncOptions:
    - CreateNamespace=true  # 自动创建命名空间
    - PrunePropagationPolicy=foreground
    - PruneLast=true

  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  # 健康检查配置
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas

步骤 2:Git 仓库中的 Kubernetes manifests

argocd-manifests/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   └── configmap.yaml
├── overlays/
│   ├── dev/
│   │   └── kustomization.yaml
│   ├── staging/
│   │   └── kustomization.yaml
│   └── production/
│       └── kustomization.yaml
└── charts/
    └── my-app/
        ├── Chart.yaml
        └── templates/

示例:deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: registry.example.com/my-app:v1.2.3
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

步骤 3:自动同步流程

┌─────────────────────────────────────────────────────────────┐
│                    Argo CD 同步流程                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 检测变更                                                 │
│     └── Argo CD 每 3 分钟(默认)轮询 Git 仓库                │
│     └── 或使用 Webhook 实时触发                              │
│                                                             │
│  2. 比较状态                                                 │
│     └── Git 中定义的状态 vs 集群中的实际状态                  │
│     └── 生成差异报告(Diff)                                 │
│                                                             │
│  3. 执行同步                                                 │
│     └── 自动模式:直接应用变更                                │
│     └── 手动模式:需要人工确认                                │
│                                                             │
│  4. 健康检查                                                 │
│     └── 检查 Deployment 是否 Ready                           │
│     └── 检查 Pod 是否 Running                                │
│     └── 超时则标记为 Degraded                                │
│                                                             │
│  5. 通知(可选)                                             │
│     └── Slack/钉钉/邮件通知                                  │
│     └── 同步成功/失败/回滚                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 4:回滚机制

# 方法 1:通过 Argo CD UI 回滚
# 访问 https://argocd.example.com → 选择应用 → Rollback

# 方法 2:通过 CLI 回滚
argocd app rollback my-app --revision 5

# 方法 3:通过 API 回滚
curl -X POST https://argocd.example.com/api/v1/applications/my-app/rollback 
  -H "Authorization: Bearer $TOKEN" 
  -d '{"revision": 5}'

# 方法 4:Git 回滚(推荐)
git revert HEAD~1
git push origin main
# Argo CD 会自动检测到变更并同步

第三部分:CI/CD 完整流水线集成

3.1 端到端流程图

┌──────────────────────────────────────────────────────────────────────────┐
│                        Argo CI/CD 完整流水线                               │
├──────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────────────────────────┐                                 │
│  │        Argo Workflows (CI)           │                                 │
│  │  ┌──────┐ ┌──────┐ ┌──────┐ ┌─────┐ │                                 │
│  │  │Checkout│▶│ Build │▶│ Test │▶│ Push│ │                                 │
│  │  └──────┘ └──────┘ └──────┘ └─────┘ │                                 │
│  │           │                        │                                 │
│  │           ▼                        │                                 │
│  │    更新 Git 中的 image tag ─────────┼─────────────────────────┐      │
│  └─────────────────────────────────────┘                       │      │
│                                                                  │      │
│  ┌─────────────────────────────────────┐                       │      │
│  │           Argo CD (CD)              │◀──────────────────────┘      │
│  │  ┌──────────┐ ┌──────────┐ ┌─────┐  │                             │
│  │  │检测变更  │▶│ 自动同步  │▶│健康 │  │                             │
│  │  │(GitOps)  │ │          │ │检查 │  │                             │
│  │  └──────────┘ └──────────┘ └─────┘  │                             │
│  └─────────────────────────────────────┘                             │
│                                                                  │      │
│                              Kubernetes 集群                        │      │
│                              ┌──────────┐                          │      │
│                              │ 新镜像部署 │                          │      │
│                              └──────────┘                          │      │
│                                                                      │      │
└──────────────────────────────────────────────────────────────────────────┘

3.2 CI 触发 CD 的两种方案

方案 A:CI 更新 Git 触发 CD(推荐)

# CI 工作流最后一步:更新 Git 中的镜像标签
- name: update-git
  template: git-update
  dependencies:
  - push

- name: git-update
  container:
    image: alpine/git:2.0
    env:
    - name: GIT_AUTHOR_NAME
      value: "argo-ci"
    - name: GIT_AUTHOR_EMAIL
      value: "ci@example.com"
    command: [sh, -c]
    args:
    - |
      git clone https://{{secrets.git-token}}@github.com/org/argocd-manifests.git /manifests
      cd /manifests
      # 更新 image tag
      sed -i "s/image:.*@.*/image: {{steps.push.outputs.parameters.image-digest}}/" overlays/production/deployment.yaml
      git add .
      git commit -m "chore: update image to {{workflow.parameters.image-tag}}"
      git push

方案 B:CI 直接调用 Argo CD API

- name: sync-argocd
  container:
    image: argoproj/argocd:latest
    env:
    - name: ARGOCD_SERVER
      value: "https://argocd.example.com"
    - name: ARGOCD_AUTH_TOKEN
      valueFrom:
        secretKeyRef:
          name: argocd-secret
          key: auth-token
    command: [argocd, app, sync]
    args:
    - my-app
    - --revision={{workflow.parameters.image-tag}}

3.3 Webhook 集成(GitHub/GitLab)

# GitHub Webhook 触发 CI
apiVersion: argoproj.io/v1alpha1
kind: WorkflowEventBinding
metadata:
  name: github-webhook
  namespace: argo
spec:
  event:
    selector: "payload.repository.name == 'my-app'"
  submit:
    workflowTemplateRef:
      name: ci-pipeline
    arguments:
      parameters:
      - name: git-repo
        value: "{{payload.repository.clone_url}}"
      - name: git-revision
        value: "{{payload.ref}}"

第四部分:高级功能与最佳实践

4.1 多环境部署

# overlays/dev/kustomization.yaml
namespace: dev
bases:
- ../../base
patchesStrategicMerge:
- replicas.yaml
images:
- name: my-app
  newTag: dev-latest

# overlays/staging/kustomization.yaml
namespace: staging
bases:
- ../../base
patchesStrategicMerge:
- replicas.yaml
images:
- name: my-app
  newTag: staging-latest

# overlays/production/kustomization.yaml
namespace: production
bases:
- ../../base
patchesStrategicMerge:
- replicas.yaml
images:
- name: my-app
  newTag: v1.2.3

4.2 蓝绿部署

# 使用 Argo Rollouts(Argo CD 的扩展)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 6
  strategy:
    blueGreen:
      activeService: my-app-active
      previewService: my-app-preview
      autoPromotionEnabled: false
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:v1.2.4

4.3 金丝雀部署

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: {duration: 5m}
      - setWeight: 25
      - pause: {duration: 5m}
      - setWeight: 50
      - pause: {duration: 10m}
      - setWeight: 100
      analysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          value: my-app

4.4 最佳实践清单

类别 建议
安全性 使用 Secret 管理凭证,不要硬编码
可追溯性 每次部署记录 Git commit SHA
回滚能力 保留至少 10 个历史版本
监控告警 集成 Prometheus + Grafana
权限控制 使用 RBAC 限制访问范围
测试先行 CI 阶段必须通过所有测试
渐进发布 生产环境使用蓝绿/金丝雀部署

第五部分:常见问题排查

5.1 Argo Workflows 常见问题

问题 原因 解决方案
Pod 无法启动 ServiceAccount 权限不足 检查 RBAC 配置
Artifact 传递失败 存储后端未配置 配置 S3/MinIO
工作流卡在 Pending 资源配额不足 检查 ResourceQuota
Docker 构建失败 镜像仓库凭证错误 检查 Secret

5.2 Argo CD 常见问题

问题 原因 解决方案
Sync 失败 Git 仓库不可访问 检查 Repository 凭证
健康状态 Unknown CRD 未安装 安装对应的 CRD
同步漂移 手动修改了集群配置 启用 selfHeal
多集群同步失败 Cluster Secret 未配置 使用 argocd cluster add

5.3 调试命令

# 查看工作流状态
argo get my-workflow
argo logs my-workflow

# 查看工作流详情
argo describe my-workflow

# 查看 Argo CD 应用状态
argocd app get my-app
argocd app diff my-app

# 手动触发同步
argocd app sync my-app

# 查看同步历史
argocd app history my-app

总结

Argo CI/CD 核心要点

┌────────────────────────────────────────────────────────────┐
│                    Argo CI/CD 核心架构                      │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  CI (Argo Workflows)          CD (Argo CD)                 │
│  ─────────────────            ─────────────                │
│  1. 拉取代码                   1. Git 是单一事实来源          │
│  2. 编译构建                   2. 自动同步到集群              │
│  3. 运行测试                   3. 健康检查与回滚              │
│  4. 推送镜像                   4. 多环境管理                  │
│  5. 更新 Git                   5. 蓝绿/金丝雀部署             │
│                                                            │
│  关键连接:CI 更新 Git → CD 检测到变更 → 自动部署             │
│                                                            │
└────────────────────────────────────────────────────────────┘

快速上手步骤

# 1. 安装 Argo Workflows
kubectl create namespace argo
kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.5.0/quick-start-minimal.yaml

# 2. 安装 Argo CD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 3. 创建第一个工作流
argo submit https://raw.githubusercontent.com/argoproj/argo-workflows/refs/heads/master/examples/hello-world.yaml

# 4. 创建第一个 Application
argocd app create my-app 
  --repo https://github.com/your-org/argocd-manifests.git 
  --path manifests/my-app 
  --dest-server https://kubernetes.default.svc 
  --dest-namespace production

# 5. 启动同步
argocd app sync my-app

提示:Argo 是一个强大的 Kubernetes 原生 CI/CD 平台,学习曲线较陡但功能强大。建议从简单的 Hello World 开始,逐步掌握 Workflows 和 Argo CD 的核心概念。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容