GitOps 核心原则
GitOps 是一种现代化的持续交付方法论,由 Weaveworks 在 2017 年提出。它将 Git 作为基础设施和应用配置的唯一可信源(Single Source of Truth),通过声明式方式实现持续部署。
根据 ArgoCD 官方文档,GitOps 遵循四大核心原则:
1. 声明式系统
基础设施和应用配置以声明式描述(YAML/Helm/Kustomize)存储在 Git 中:
# Git 仓库结构示例
infra-repo/
├── apps/
│ ├── frontend/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── configmap.yaml
│ └── backend/
│ ├── deployment.yaml
│ └── service.yaml
├── helm/
│ └── values-production.yaml
└── kustomize/
├── base/
└── overlays/
├── staging/
└── production/
声明式描述的核心价值:配置即文档,Git 历史即审计日志。任何环境变更都可追溯、可回滚。
2. 版本控制
所有变更通过 Git 提交记录,天然具备:
- 变更审计:谁在何时修改了什么,为什么修改
- 版本回滚:
git revert即可回滚到任意历史版本 - 变更评审:通过 Pull Request 实现配置变更的 Code Review
3. 自动同步
代码合并到目标分支后,自动触发部署到目标环境,无需人工执行部署命令:
开发者提交 PR → Code Review → 合并到 main → ArgoCD 检测变更 → 自动同步到集群
4. 持续协调
控制平面持续监控集群实际状态与 Git 期望状态的差异,发现漂移自动纠正:
Git (期望状态) ←→ ArgoCD (协调器) ←→ Cluster (实际状态)
持续对比 ↑↓
发现差异 → 自动同步
这与传统 CI/CD 的根本区别在于:传统 CI/CD 是 Push 模型(CI 推送到集群),GitOps 是 Pull 模型(集群内的 Agent 拉取 Git)。Pull 模型不需要在 CI 系统中存储集群凭据,安全性更高。
ArgoCD 架构
ArgoCD 是 CNCF 毕业项目,是 GitOps 领域最成熟的工具。它以 Kubernetes Controller 形式运行在集群内,持续协调 Git 仓库与集群状态。
核心组件
┌─────────────────────────────────────────────────────────┐
│ ArgoCD 架构 │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ API Server │ │ Repo Server │ │ Application │ │
│ │ (gRPC/REST) │ │ (Git 渲染) │ │ Controller │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ │ ┌───────▼────────┐ │ │
│ │ │ Git Repository │ │ │
│ │ │ (Helm/Kustomize)│ │ │
│ │ └────────────────┘ │ │
│ │ │ │
│ ┌──────▼─────────────────────────────────────▼──────┐ │
│ │ Redis (缓存 + 状态) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ K8s API Server │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
| 组件 | 职责 | 关键点 |
|---|---|---|
| API Server | 暴露 gRPC/REST API,管理 Application CRD | 认证授权、Web UI、CLI 交互 |
| Repo Server | 克隆 Git 仓库,渲染 Helm/Kustomize | 无状态服务,可水平扩展 |
| Application Controller | 协调循环:对比 Git 与集群状态 | 核心控制器,触发同步操作 |
| Redis | 缓存 Git 仓库和渲染结果 | 降低 Repo Server 负载 |
| ApplicationSet Controller | 批量生成 Application | 多集群/多环境场景 |
安装部署
# 安装 ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 获取初始密码
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
# 端口转发访问 UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# 安装 ArgoCD CLI
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd && mv argocd /usr/local/bin/
# 登录
argocd login localhost:8080 --username admin --password <password>
Application CRD 配置
Application 是 ArgoCD 的核心 CRD,定义了"把哪个 Git 仓库的什么内容同步到哪个集群":
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-prod
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io # 删除 App 时级联清理资源
spec:
project: production # 关联的 ArgoCD Project
source:
repoURL: https://github.com/xubaojin/k8s-manifests.git
targetRevision: main # 跟踪的分支/tag
path: apps/frontend/overlays/production # Kustomize 路径
destination:
server: https://kubernetes.default.svc # 目标集群
namespace: production
syncPolicy:
automated:
prune: true # 自动删除 Git 中已移除的资源
selfHeal: true # 自动恢复手动修改(漂移纠正)
syncOptions:
- CreateNamespace=true # 自动创建命名空间
- PrunePropagationPolicy=foreground
- ApplyOutOfSyncOnly=true
revisionHistoryLimit: 10 # 保留 10 个历史版本用于回滚
同步策略详解
Auto Sync(自动同步):
syncPolicy:
automated:
prune: true # Git 中删除的资源在集群中也删除
selfHeal: true # 有人手动 kubectl 改了集群资源,自动恢复
selfHeal 是 GitOps 的核心——它确保集群状态始终与 Git 一致。如果有人手动 kubectl edit 修改了 Deployment 的副本数,ArgoCD 会自动将其恢复为 Git 中声明的值。
Manual Sync(手动同步):
syncPolicy:
# 不配置 automated,需要手动触发同步
syncOptions:
- CreateNamespace=true
适用于生产环境,变更需要人工确认后点击同步。
Helm Chart 同步
spec:
source:
repoURL: https://github.com/xubaojin/helm-charts.git
targetRevision: main
path: charts/frontend
helm:
valueFiles:
- values-production.yaml
parameters:
- name: image.tag
value: v1.2.3
- name: replicaCount
value: "3"
skipCrds: false
Kustomize 同步
spec:
source:
repoURL: https://github.com/xubaojin/k8s-manifests.git
targetRevision: main
path: apps/frontend/overlays/production
kustomize:
images:
- ghcr.io/xubaojin/frontend:v1.2.3 # 覆盖镜像版本
commonAnnotations:
managed-by: argocd
多环境管理:App of Apps 模式
当管理多个微服务 × 多个环境时,Application 数量爆炸式增长。App of Apps 模式通过一个父 Application 管理多个子 Application:
root-app (Application)
├── staging-apps (Application)
│ ├── frontend-staging (Application)
│ ├── backend-staging (Application)
│ └── database-staging (Application)
└── production-apps (Application)
├── frontend-production (Application)
├── backend-production (Application)
└── database-production (Application)
根 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/xubaojin/k8s-manifests.git
targetRevision: main
path: argocd/apps # 此目录下存放子 Application 定义
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
子 Application 目录结构
argocd/
├── apps/
│ ├── staging/
│ │ ├── frontend.yaml # Application CRD
│ │ ├── backend.yaml
│ │ └── database.yaml
│ ├── production/
│ │ ├── frontend.yaml
│ │ ├── backend.yaml
│ │ └── database.yaml
│ └── kustomization.yaml # 聚合所有子 Application
└── projects/
├── staging.yaml # ArgoCD Project
└── production.yaml
kustomization.yaml 聚合所有子 Application:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- staging/
- production/
ArgoCD Project 隔离
Project 提供多租户隔离,限制 Application 可操作的集群和命名空间:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: 生产环境项目
sourceRepos:
- https://github.com/xubaojin/k8s-manifests.git
destinations:
- server: https://kubernetes.default.svc
namespace: production
- server: https://kubernetes.default.svc
namespace: production-*
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceWhitelist:
- group: '*'
kind: '*'
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota # 禁止修改 ResourceQuota
roles:
- name: developer
policies:
- p, proj:production:developer, applications, sync, production/*, allow
groups:
- github:dev-team
ArgoCD CD 工作流实战
完整的 GitOps CD 工作流从代码提交到生产部署的全链路:
开发者 Push → Git 触发 CI → 构建镜像 → 更新 Manifest 仓库 → ArgoCD 检测 → 同步集群
完整流程
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Git Push │───►│ CI 构建 │───►│ 推送镜像 │───►│ 更新 │───►│ ArgoCD │
│ (应用代码)│ │ (测试/构建)│ │ (Registry)│ │ Manifest │ │ 自动同步 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
CI Pipeline(GitHub Actions 示例)
# .github/workflows/ci.yml
name: CI Build and Deploy
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout 应用代码
uses: actions/checkout@v4
- name: Go 测试
run: |
go test ./... -v -coverprofile=coverage.out
- name: 构建并推送镜像
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.sha }}
ghcr.io/${{ github.repository }}:latest
- name: 更新 Manifest 仓库
env:
GH_TOKEN: ${{ secrets.MANIFEST_REPO_TOKEN }}
run: |
# 克隆 manifest 仓库
git clone https://x-access-token:${GH_TOKEN}@github.com/xubaojin/k8s-manifests.git
cd k8s-manifests
# 更新镜像版本(使用 yq)
yq -i ".spec.template.spec.containers[0].image = \"ghcr.io/${{ github.repository }}:${{ github.sha }}\"" \
apps/frontend/overlays/production/deployment-patch.yaml
# 提交并推送
git config user.name "CI Bot"
git config user.email "ci-bot@sre.wang"
git add .
git commit -m "chore: update frontend image to ${{ github.sha }}"
git push origin main
ArgoCD 检测与同步
CI 推送 manifest 更新后,ArgoCD 在默认 3 分钟内检测到变更并触发同步。可通过 argocd-cm ConfigMap 调整轮询间隔:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# 设置 Git 轮询间隔(秒)
timeout.reconciliation: "180"
# 使用 Webhook 替代轮询(推荐)
# 配置 Git Webhook 后可实时触发
更推荐的方式是配置 Git Webhook,变更推送后立即触发同步,无需等待轮询:
# 在 Git 仓库配置 Webhook 指向 ArgoCD
# Payload URL: https://argocd.sre.wang/api/webhook
# Content type: application/json
# ArgoCD Webhook 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
webhook.github.secret: "your-webhook-secret"
同步状态监控
# 查看所有 Application 同步状态
argocd app list
# 查看特定 Application 详情
argocd app get frontend-production
# 手动触发同步
argocd app sync frontend-production
# 查看同步历史
argocd app history frontend-production
# 回滚到历史版本
argocd app rollback frontend-production <revision-id>
漂移检测告警
当有人手动修改集群资源导致漂移时,应配置告警通知:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-production
namespace: argocd
annotations:
notifications.argoproj.io/subscribe.on-deployed.slack: ops-alerts
notifications.argoproj.io/subscribe.on-health-degraded.slack: ops-alerts
notifications.argoproj.io/subscribe.on-sync-failed.slack: ops-alerts
spec:
# ... 其他配置
ArgoCD Notifications 支持 Slack、Teams、邮件等多种通知渠道,关键事件包括:
| 事件 | 说明 | 建议告警级别 |
|---|---|---|
on-sync-succeeded | 同步成功 | Info(可选) |
on-sync-failed | 同步失败 | Critical |
on-health-degraded | 应用健康状态降级 | Critical |
on-deployed | 部署完成 | Info |
on-created | Application 创建 | Warning |
总结
GitOps 不仅仅是工具选择,更是一种运维范式转变。它的核心价值在于:
- 安全性:集群凭据不在 CI 系统中暴露,Git 权限即部署权限
- 可审计:所有变更通过 Git 提交记录,天然合规
- 可回滚:
git revert即可回滚,无需额外的回滚工具 - 漂移纠正:selfHeal 机制确保集群状态始终与期望一致
ArgoCD 作为 GitOps 的核心组件,通过 Application CRD 声明式管理应用生命周期,App of Apps 模式实现多环境规模化,与 CI Pipeline 无缝衔接形成完整 CD 链路。
生产环境实施建议:staging 环境使用 Auto Sync + selfHeal 快速验证,production 环境使用 Manual Sync 人工确认 + Webhook 实时通知。渐进式推进,从非核心应用开始试点,积累经验后逐步扩大覆盖范围。
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- ArgoCD 官方文档 — Argo CD 项目,参考了ArgoCD 官方文档相关内容