GitOps 将 Git 仓库作为基础设施和应用配置的单一可信源,通过自动化工具持续同步实际状态到期望状态。ArgoCD 是目前 Kubernetes 生态中最成熟的 GitOps 工具,被广泛用于生产环境的多集群持续交付。
目录
- 1. GitOps 核心理念
- 2. GitOps vs 传统 CI/CD
- 3. ArgoCD 架构
- 4. ArgoCD 安装与配置
- 5. Application 定义
- 6. 同步策略与自动化
- 7. 多集群管理
- 8. 密钥管理:Sealed Secrets
- 9. 生产最佳实践
1. GitOps 核心理念
GitOps 由 Weaveworks 在 2017 年提出,核心原则:
- 声明式系统:系统配置描述期望状态,存储在版本控制中
- 版本控制:所有变更通过 Git 提交的审计追踪
- 自动同步:自动化工具持续将实际状态与 Git 中的期望状态对齐
- 差异化监控:实时可见实际状态与期望状态的差异
推拉模型对比
| 特性 | 传统 CI/CD(Push) | GitOps(Pull) |
|---|---|---|
| 触发方 | CI 系统主动推送 | 部署代理轮询拉取 |
| 凭证位置 | CI 系统需集群凭证 | 集群只需 Git 凭证 |
| 安全性 | CI 暴露 K8s API 访问 | Git 凭证权限可严格控制 |
| 可见性 | 需登录 CI 系统查看 | Git 提交即部署记录 |
| 回滚 | 重新运行 Pipeline | Git Revert → 自动回滚 |
2. GitOps vs 传统 CI/CD
传统 CI/CD 流程
开发者 push → CI 构建镜像 → CI push 镜像 → CI kubectl apply
↑ │
└────── 需要 K8s 凭证 ─────┘
问题:CI 系统需要 K8s 集群的 admin 权限,凭证泄露风险高。
GitOps 流程
开发者 push → CI 构建镜像 → CI 更新 Git(镜像 tag)→ ArgoCD 自动同步到集群
↑
Git = 单一可信源
集群中的 ArgoCD 周期性地拉取 Git 仓库,检测到差异后自动或手动同步。
3. ArgoCD 架构
┌─────────────────────────────────────┐
│ ArgoCD │
│ │
│ ┌──────────────┐ ┌────────────┐ │
│ │ API Server │───│ Web UI │ │
│ │ │ │ (管理界面) │ │
│ └──────┬───────┘ └────────────┘ │
│ │ │
│ ┌──────▼───────┐ ┌────────────┐ │
│ │ Repository │ │ Application│ │
│ │ Server │ │ Controller │ │
│ │ (Git Repo) │ │ (Reconcile)│ │
│ └──────┬───────┘ └─────┬──────┘ │
│ │ │ │
│ └────────┬────────┘ │
│ ↓ │
│ ┌──────────┐ │
│ │ Redis │ (状态缓存) │
│ └──────────┘ │
└─────────────────────────────────────┘
↓
┌─────────────────┐
│ Target Clusters │ (K8s 集群)
└─────────────────┘
核心组件:
| 组件 | 作用 |
|---|---|
| API Server | 暴露 gRPC/REST API,Web UI 和 CLI 的入口 |
| Repository Server | 克隆 Git 仓库、生成 K8s manifest |
| Application Controller | 监控 Application 状态,执行同步操作 |
| Dex | 身份认证(SSO/OIDC/LDAP/GitHub) |
| Redis | 缓存 Git 状态和 K8s 资源状态 |
4. ArgoCD 安装与配置
安装
# 创建命名空间
kubectl create namespace argocd
# 安装 ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 暴露 UI(开发测试用)
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
# 获取初始密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
CLI 配置
# 安装 argocd CLI
brew install argocd
# 登录
argocd login argocd.example.com --username admin --password <password>
# 修改密码
argocd account update-password
添加 Git 仓库
# HTTPS 方式
argocd repo add https://github.com/example/gitops-repo.git \
--username <user> --password <token>
# SSH 方式
argocd repo add git@github.com:example/gitops-repo.git \
--ssh-private-key-path ~/.ssh/id_rsa
5. Application 定义
基础 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: production-api
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io # 级联删除
spec:
project: default # ArgoCD 项目
source:
repoURL: https://github.com/example/gitops-repo.git
targetRevision: main # Git 分支/标签/SHA
path: overlays/production/api
# 支持 Helm、Kustomize、 plain YAML、Jsonnet
# kustomize:
# namePrefix: prod-
# helm:
# valueFiles:
# - values-production.yaml
destination:
server: https://kubernetes.default.svc # 本集群,外部集群填 API Endpoint
namespace: production
syncPolicy:
automated:
prune: true # 删除 Git 中不存在的资源
selfHeal: true # 自动修复手动修改
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
revisionHistoryLimit: 10
ApplicationSet(多环境/多集群)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: api-applications
namespace: argocd
spec:
generators:
# 生成器:基于 Git 目录结构
- git:
repoURL: https://github.com/example/gitops-repo.git
revision: main
directories:
- path: overlays/*
template:
metadata:
name: '{{path.basename}}-api'
spec:
project: default
source:
repoURL: https://github.com/example/gitops-repo.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
ApplicationSet 自动生成多个 Application:
overlays/development/→ Application:development-apioverlays/staging/→ Application:staging-apioverlays/production/→ Application:production-api
集群生成器(多集群)
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
values:
branch: main
template:
spec:
source:
targetRevision: '{{values.branch}}'
destination:
name: '{{name}}' # 引用集群名
6. 同步策略与自动化
同步策略配置
syncPolicy:
automated:
prune: true # Git 删除资源时,集群也删除
selfHeal: true # 集群手动修改后,自动恢复到 Git 状态
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
syncOptions:
- CreateNamespace=true # 自动创建目标 Namespace
- PrunePropagationPolicy=foreground # 前台删除,等待资源清理完成
- PruneLast=true # 先创建/更新,最后删除
- ApplyOutOfSyncOnly=true # 仅同步差异资源,加快同步速度
手动同步控制
# 查看应用状态
argocd app get production-api
# 手动同步
argocd app sync production-api
# 同步特定资源
argocd app sync production-api --resource apps:Deployment:api-server
# 查看同步历史
argocd app history production-api
# 回滚到历史版本
argocd app rollback production-api 3
资源钩(Hooks)
ArgoCD 支持在同步生命周期中执行 Hook:
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
argocd.argoproj.io/hook: PreSync # Sync 前执行
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: myapp:latest
command: ["python", "manage.py", "migrate"]
| Hook 类型 | 触发时机 |
|---|---|
PreSync | 同步前 |
Sync | 和应用资源一起 |
PostSync | 同步成功且健康后 |
SyncFail | 同步失败后 |
7. 多集群管理
添加外部集群
# 在目标集群创建 ServiceAccount
kubectl create sa argocd-manager -n kube-system
kubectl create clusterrolebinding argocd-manager-role \
--clusterrole=cluster-admin --serviceaccount=kube-system:argocd-manager
# 获取 Token
kubectl get secret $(kubectl get sa argocd-manager -n kube-system -o jsonpath='{.secrets[0].name}') \
-n kube-system -o jsonpath='{.data.token}' | base64 -d
# 在 ArgoCD 中注册集群
argocd cluster add <context-name> --name production-eks
多集群 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-us-east
spec:
source:
repoURL: https://github.com/example/gitops-repo.git
targetRevision: main
path: base/api
destination:
name: production-eks-us-east # 引用注册的集群名
namespace: production
8. 密钥管理:Sealed Secrets
GitOps 的核心矛盾:配置放在 Git 中,但密钥不能明文存储。
Sealed Secrets 方案
# 安装 kubeseal CLI 和 controller
brew install kubeseal
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# 1. 创建普通 Secret
kubectl create secret generic db-password \
--from-literal=password='S3cr3t!' \
--dry-run=client -o yaml > secret.yaml
# 2. 加密为 SealedSecret
kubeseal --controller-namespace=kube-system < secret.yaml > sealed-secret.yaml
# 3. 提交 sealed-secret.yaml 到 Git(安全,可以公开存放)
git add sealed-secret.yaml && git commit
# 4. ArgoCD 同步到集群后,controller 自动解密为普通 Secret
kubectl get secret db-password -o yaml
SealedSecret 由集群公钥加密,只能由安装了对应私钥的集群解密。
替代方案对比
| 方案 | 原理 | Git 安全 | 适用场景 |
|---|---|---|---|
| Sealed Secrets | 集群公钥加密 | ✅ | 单集群,简单场景 |
| External Secrets Operator | 同步 Vault/AWS SM | ✅ | 多集群,企业级 |
| SOPS | Age/GPG 加密 | ✅(密钥不在 Git) | Flux 用户 |
| Helm Secrets | SOPS + Helm | ✅ | Helm 用户 |
9. 生产最佳实践
项目隔离
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: "生产环境项目"
sourceRepos:
- https://github.com/example/gitops-repo.git
destinations:
- namespace: production
server: https://kubernetes.default.svc
clusterResourceWhitelist: # 允许操作集群级别资源
- group: ''
kind: Namespace
namespaceResourceBlacklist: # 禁止操作敏感资源
- group: ''
kind: ResourceQuota
roles:
- name: developer
description: "开发者只读权限"
policies:
- p, proj:production:developer, applications, get, production/*, allow
RBAC 集成
# ArgoCD 配置 RBAC
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
p, role:developer, applications, sync, production/*, allow
p, role:admin, *, *, *, allow
g, github-org:my-team, role:developer
监控与告警
# Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-metrics
endpoints:
- port: metrics
path: /metrics
关键监控指标:
# 应用不同步状态
argocd_app_info{sync_status="OutOfSync"}
# 同步失败计数
argocd_app_sync_total{phase!="Succeeded"}
灾难恢复
# 导出所有 ArgoCD 配置
echo "备份 Application..."
kubectl get applications -n argocd -o yaml > argocd-backup.yaml
# ArgoCD 本身也可用 GitOps 管理(App of Apps 模式)
# Git 中存放所有 Application 定义,ArgoCD 自托管
总结
| 主题 | 核心要点 |
|---|---|
| GitOps 理念 | Git 单一可信源,声明式、版本化、自动化 |
| ArgoCD 架构 | API Server + Repo Server + Controller + Redis |
| Application | 声明 Git 源、目标集群、同步策略 |
| ApplicationSet | 批量生成应用,支持多环境多集群 |
| 同步策略 | automated/prune/selfHeal + Hooks |
| 密钥管理 | Sealed Secrets / ESO / SOPS |
| 多集群 | argocd cluster add + Application destination.name |
GitOps 不是工具的替代,而是工作范式的转变:将变更的审批和审计从 CI 流水线迁移到 Git 工作流,使基础设施变更与代码变更一样可追溯、可回滚、可 review。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。