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















暂无评论内容