ArgoCD GitOps 持续交付
大约 10 分钟约 2951 字
ArgoCD GitOps 持续交付
简介
ArgoCD 是一个基于 Kubernetes 的声明式 GitOps 持续交付工具,它通过自动同步 Git 仓库中的 Kubernetes 清单与应用的实际部署状态,实现了以 Git 为唯一可信源的应用交付模式。ArgoCD 能够自动检测 Git 仓库中配置的变更,并将这些变更自动或半自动地同步到目标 Kubernetes 集群中,提供了可视化的管理界面和丰富的通知机制,是云原生应用交付领域最受欢迎的开源工具之一。
特点
GitOps 理念与实践
GitOps 的核心理念是将 Git 仓库作为基础设施和应用配置的唯一可信源,所有变更都通过 Git 提交来驱动。
# GitOps 工作流程示例
# 1. 开发者推送代码到应用仓库
# 2. CI 流水线构建镜像并推送到镜像仓库
# 3. CI 流水线更新配置仓库中的镜像标签
# 4. ArgoCD 检测到配置变更并同步到集群
# 配置仓库目录结构示例
# ├── apps/
# │ ├── frontend/
# │ │ ├── deployment.yaml
# │ │ ├── service.yaml
# │ │ └── ingress.yaml
# │ ├── backend/
# │ │ ├── deployment.yaml
# │ │ └── service.yaml
# │ └── database/
# │ └── statefulset.yaml
# ├── environments/
# │ ├── dev/
# │ ├── staging/
# │ └── production/
# └── argocd/
# ├── AppProject.yaml
# └── Application.yaml# ArgoCD 安装配置
apiVersion: v1
kind: Namespace
metadata:
name: argocd
---
# 使用 Kustomize 安装 ArgoCD
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd
resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/v2.9.0/manifests/install.yaml
patches:
- target:
kind: ConfigMap
name: argocd-cm
patch: |
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
url: "https://argocd.example.com"
statusbadge.enabled: "true"
resource.customizations: |
networking.k8s.io/Ingress:
health.lua: |
hs = {}
hs.status = "Healthy"
return hsApplication CRD 配置
Application 是 ArgoCD 的核心资源,定义了应用的来源、目标集群和同步策略。
# 基础 Application 配置
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
namespace: argocd
labels:
app: frontend
environment: production
annotations:
notifications.argoproj.io/subscribe.on-deployed.slack: deploy-notify
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/frontend
destination:
server: https://kubernetes.default.svc
namespace: frontend
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# 使用 Helm Chart 的 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend-api
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/helm-charts.git
targetRevision: main
path: charts/backend-api
helm:
valueFiles:
- values.yaml
- values-production.yaml
parameters:
- name: image.tag
value: "v2.1.0"
- name: replicas
value: "3"
releaseName: backend-api
destination:
server: https://kubernetes.default.svc
namespace: backend
syncPolicy:
automated:
prune: true
selfHeal: true# 使用 Kustomize 的 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring-stack
namespace: argocd
spec:
project: infrastructure
source:
repoURL: https://github.com/myorg/infra-configs.git
targetRevision: main
path: monitoring/overlays/production
kustomize:
namePrefix: prod-
nameSuffix: -monitoring
images:
- prom/prometheus:v2.48.0
- grafana/grafana:10.2.0
commonLabels:
managed-by: argocd
destination:
server: https://kubernetes.default.svc
namespace: monitoringSync 同步策略
ArgoCD 提供了灵活的同步策略,包括自动同步、手动同步和钩子机制。
# AppProject 配置
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: "Production environment project"
sourceRepos:
- "https://github.com/myorg/*"
destinations:
- namespace: "frontend"
server: https://kubernetes.default.svc
- namespace: "backend"
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ""
kind: Namespace
- group: "rbac.authorization.k8s.io"
kind: ClusterRole
namespaceResourceBlacklist:
- group: ""
kind: ResourceQuota
- group: ""
kind: LimitRange
roles:
- name: admin
description: "Admin privileges"
policies:
- p, proj:production:admin, applications, *, production/*, allow
- p, proj:production:admin, repositories, *, *, allow# Sync Hook 示例 - 数据库迁移
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
namespace: backend
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myregistry.com/backend:v2.1.0
command: ["npm", "run", "migrate"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
restartPolicy: Never
backoffLimit: 3
---
# PostSync Hook - 通知
apiVersion: batch/v1
kind: Job
metadata:
name: deploy-notify
namespace: backend
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: notify
image: alpine:3.18
command:
- /bin/sh
- -c
- |
echo "Deployment completed successfully"
# 发送通知到 Slack
wget -qO- --post-data='{"text":"Backend v2.1.0 deployed successfully"}' \
"${SLACK_WEBHOOK_URL}"
env:
- name: SLACK_WEBHOOK_URL
valueFrom:
secretKeyRef:
name: notification-secrets
key: slack-webhook
restartPolicy: Never多集群管理
ArgoCD 支持通过单一实例管理多个 Kubernetes 集群的应用部署。
# 注册外部集群
# 使用 argocd CLI 添加集群
# argocd cluster add production-cluster --name prod-us-east
# 多集群 Application 配置
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-multi-cluster
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/frontend
destination:
server: https://prod-us-east.example.com
namespace: frontend
---
# 使用 ApplicationSet 实现多集群自动分发
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: frontend-global
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: https://prod-us-east.example.com
name: us-east
replicas: "3"
- cluster: https://prod-eu-west.example.com
name: eu-west
replicas: "2"
- cluster: https://prod-ap-south.example.com
name: ap-south
replicas: "2"
template:
metadata:
name: "frontend-{{name}}"
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/frontend
helm:
parameters:
- name: replicaCount
value: "{{replicas}}"
destination:
server: "{{cluster}}"
namespace: frontend
syncPolicy:
automated:
prune: true
selfHeal: trueApplicationSet 高级模式
Git 目录生成器
# 自动为每个 Git 目录创建 Application
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: microservices
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/myorg/k8s-manifests.git
revision: main
directories:
- path: services/*
template:
metadata:
name: '{{path.basename}}'
labels:
app: '{{path.basename}}'
managed-by: applicationset
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueGit 文件内容生成器
# 从 JSON/YAML 配置文件动态生成 Application
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-configs
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/myorg/infra-configs.git
revision: main
files:
- path: "clusters/**/config.json"
template:
metadata:
name: '{{cluster.name}}-apps'
spec:
project: '{{cluster.project}}'
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: '{{cluster.revision}}'
path: '{{cluster.path}}'
helm:
values: |
replicaCount: {{cluster.replicas}}
environment: {{cluster.environment}}
destination:
server: '{{cluster.server}}'
namespace: '{{cluster.namespace}}'
# config.json 示例
# {
# "cluster": {
# "name": "prod-us-east",
# "project": "production",
# "server": "https://prod-us-east.example.com",
# "path": "apps/backend",
# "revision": "main",
# "replicas": 3,
# "environment": "production",
# "namespace": "backend"
# }
# }矩阵生成器(Matrix Generator)
# 组合多个生成器 — 环境 x 服务矩阵
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: all-services-all-envs
namespace: argocd
spec:
generators:
- matrix:
generators:
- list:
elements:
- env: dev
revision: develop
replicas: "1"
- env: staging
revision: release
replicas: "2"
- env: production
revision: main
replicas: "3"
- list:
elements:
- service: frontend
path: services/frontend
- service: backend
path: services/backend
- service: worker
path: services/worker
template:
metadata:
name: '{{service}}-{{env}}'
labels:
app: '{{service}}'
env: '{{env}}'
spec:
project: '{{env}}'
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: '{{revision}}'
path: '{{path}}'
helm:
parameters:
- name: replicaCount
value: '{{replicas}}'
- name: image.tag
value: '{{revision}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{service}}-{{env}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueArgoCD Image Updater
自动镜像更新
# ArgoCD Image Updater 自动检测并更新镜像标签
# 安装 Image Updater
# kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
# Application 注解配置自动更新
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend-api
namespace: argocd
annotations:
# 启用自动镜像更新
argocd-image-updater.argoproj.io/image-list: backend=myregistry.com/backend:latest
# 更新策略:semver(语义版本)、latest、name(按名称排序)
argocd-image-updater.argoproj.io/backend.update-strategy: semver
argocd-image-updater.argoproj.io/backend.allow-tags: regexp:^v[0-9]+\.[0-9]+\.[0-9]+$
# 写回方式:git commit 更新配置
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main
argocd-image-updater.argoproj.io/git-repository: https://github.com/myorg/k8s-manifests.git
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/backend
helm:
parameters:
- name: image.tag
value: v1.0.0
destination:
server: https://kubernetes.default.svc
namespace: backendSSO 与 RBAC 集成
配置 OIDC 认证
# ArgoCD SSO 配置(argocd-cm)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: "https://argocd.example.com"
# OIDC 配置(以 Keycloak 为例)
oidc.config: |
name: Keycloak
issuer: https://keycloak.example.com/realms/myorg
clientID: argocd
clientSecret: $oidc-keycloak-client-secret
requestedScopes:
- openid
- profile
- email
- groups
---
# RBAC 配置(argocd-rbac-cm)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
# 管理员 — 完全访问
g, myorg:admins, role:admin
# 开发者 — 可部署到开发和测试环境
g, myorg:developers, role:developer
p, role:developer, applications, *, myorg/*, allow
p, role:developer, applications, sync, */production, deny
# 运维 — 可部署到所有环境
g, myorg:ops, role:ops
p, role:ops, applications, *, */*, allow
p, role:ops, clusters, get, *, allow
p, role:ops, repositories, *, *, allow
# 只读用户
g, myorg:readonly, role:readonly
# scopes 控制从 OIDC Token 中提取哪些字段用于 RBAC
scopes: "[groups]"ArgoCD CLI 常用命令
日常运维操作
# 登录
argocd login argocd.example.com --username admin --password xxx
# 应用管理
argocd app list # 列出所有应用
argocd app get frontend-app # 查看应用详情
argocd app sync frontend-app # 手动同步
argocd app sync frontend-app --prune # 同步并清理多余资源
argocd app diff frontend-app # 查看配置差异
argocd app history frontend-app # 查看同步历史
argocd app rollback frontend-app <revision> # 回滚到指定版本
argocd app set frontend-app -p image.tag=v2.0.0 # 覆盖参数
argocd app delete frontend-app --cascade # 删除应用及资源
# 项目管理
argocd proj list # 列出项目
argocd proj get production # 查看项目详情
argocd proj allow-ssh-repo production https://github.com/myorg # 允许仓库
# 集群管理
argocd cluster list # 列出集群
argocd cluster add production-cluster # 添加集群
# 仓库管理
argocd repo list # 列出仓库
argocd repo add https://github.com/myorg/k8s-manifests.git # 添加仓库
# 调试
argocd app logs frontend-app # 查看应用日志
argocd app manifest frontend-app # 查看生成的清单
argocd account can-i sync applications '*' '*/production' # RBAC 检查通知与告警
# ArgoCD 通知配置
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-deployed: |
message: |
应用 {{.app.metadata.name}} 已成功部署到 {{.app.spec.destination.namespace}}。
镜像版本: {{.app.status.summary.images}}
slack:
attachments: |
[{
"title": "{{.app.metadata.name}}",
"title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
"color": "#18be52",
"fields": [
{ "title": "同步状态", "value": "{{.app.status.sync.status}}" },
{ "title": "健康状态", "value": "{{.app.status.health.status}}" }
]
}]
trigger.on-deployed: |
- description: "应用部署成功"
oncePer: app.status.sync.revision
send:
- app-deployed
when: app.status.operationState.phase in ['Succeeded']优点
缺点
总结
ArgoCD 通过将 GitOps 理念与 Kubernetes 原生资源紧密结合,为企业提供了一套完整的持续交付解决方案。其 Application CRD 和 AppProject 提供了精细化的多租户管理能力,Sync 策略和 Hook 机制支持复杂的部署流程编排,ApplicationSet 更是极大地简化了多集群应用分发的复杂度。作为 CNCF 毕业项目,ArgoCD 拥有活跃的社区和丰富的生态系统,是实施云原生 GitOps 实践的首选工具。
关键知识点
- DevOps 主题的核心是让交付更快、更稳、更可审计。
- 自动化不是把命令脚本化,而是把失败、回滚、权限和观测一起设计进去。
- 生产链路必须明确制品、环境、凭据、配置和责任边界。
项目落地视角
- 把流水线拆成构建、测试、制品、部署、验证和回滚几个阶段。
- 为关键步骤补齐日志、指标、通知和人工兜底点。
- 定期演练扩容、回滚、故障注入和灾备切换。
常见误区
- 只关注部署成功,不关注失败恢复和审计追踪。
- 把环境差异藏在临时脚本或人工操作里。
- 上线频率高了以后,没有标准化制品和配置管理。
进阶路线
- 继续补齐 GitOps、可观测性、平台工程和成本治理。
- 把主题和应用架构、安全、权限、备份恢复联动起来理解。
- 形成团队级平台能力,而不是每个项目重复造轮子。
适用场景
- 当你准备把《ArgoCD GitOps 持续交付》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合构建自动化交付、基础设施治理、监控告警和生产发布体系。
- 当团队规模扩大、发布频率提升或环境变多时,这类主题会显著影响交付效率。
落地建议
- 所有自动化流程尽量做到幂等、可审计、可回滚。
- 把制品、变量、凭据和执行权限分层管理。
- 定期演练扩容、回滚、密钥轮换和灾备恢复。
排错清单
- 先定位失败发生在代码、构建、制品、环境还是权限层。
- 检查流水线变量、凭据、镜像标签和目标环境配置是否一致。
- 如果问题偶发,重点看并发发布、资源争抢和外部依赖抖动。
复盘问题
- 如果把《ArgoCD GitOps 持续交付》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《ArgoCD GitOps 持续交付》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《ArgoCD GitOps 持续交付》最大的收益和代价分别是什么?
