GitOps与ArgoCD
1. 概念
GitOps = Git 是唯一事实来源。所有基础设施和应用配置存 Git,变更靠 PR。自动化工具监听 Git 变化,自动同步到集群。
Git 仓库(yaml / helm)
↓ watch
ArgoCD(或 Flux)
↓ sync
K8s 集群
核心原则:
- 声明式(yaml 描述期望状态)
- 版本化(git 历史 = 审计记录)
- 自动同步(push 即生效)
- 自愈(手动改集群会被 revert)
2. ArgoCD 安装
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 获取 admin 初始密码
argocd admin initial-password -n argocd
# 暴露 UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# 访问 https://localhost:8080
CLI:
brew install argocd
argocd login localhost:8080 --username admin --password xxx --insecure
3. Application 定义
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-frontend
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-configs.git
targetRevision: main
path: frontend/prod # yaml 所在目录
destination:
server: https://kubernetes.default.svc
namespace: frontend
syncPolicy:
automated:
prune: true # 删除 git 里没有的资源
selfHeal: true # 手动改了会恢复
syncOptions:
- CreateNamespace=true
4. 目录结构
k8s-configs/ # 独立 repo(配置和代码分离)
├── frontend/
│ ├── base/ # Kustomize base
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ ├── ingress.yaml
│ │ └── kustomization.yaml
│ ├── dev/
│ │ ├── kustomization.yaml # patch image tag / env
│ │ └── patches.yaml
│ ├── staging/
│ │ └── kustomization.yaml
│ └── prod/
│ └── kustomization.yaml
└── backend/
└── ...
或 Helm:
k8s-configs/
├── frontend/
│ ├── Chart.yaml
│ ├── values-dev.yaml
│ ├── values-staging.yaml
│ └── values-prod.yaml
5. CI 更新镜像 tag → 触发同步
# CI 里构建完镜像后更新 git repo
- name: Update image tag
run: |
cd k8s-configs
sed -i "s|image: myapp:.*|image: myapp:$}} github.sha }}|" frontend/prod/deployment.yaml
git add . && git commit -m "deploy frontend $}} github.sha }}" && git push
或用 ArgoCD Image Updater(自动监听 registry 新 tag):
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: web=ghcr.io/myorg/frontend
argocd-image-updater.argoproj.io/web.update-strategy: semver
6. 核心功能
6.1 Sync
- OutOfSync:Git 和集群不一致
- Synced:一致
- Auto-Sync:自动对齐
argocd app sync my-frontend
argocd app diff my-frontend
argocd app get my-frontend
6.2 Rollback
argocd app history my-frontend
argocd app rollback my-frontend <revision>
或 revert git commit → ArgoCD 自动 sync 回去。
6.3 Wave / Hook
控制同步顺序:
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1" # 0 先 1 后
argocd.argoproj.io/hook: PreSync # 同步前执行(如 migrate)
6.4 Health Check
ArgoCD 内置对 Deployment / Service / Ingress 的健康判断:
- Healthy / Degraded / Progressing / Suspended / Missing
7. Multi-Cluster
argocd cluster add <context-name>
一套 ArgoCD 管多个集群(dev + staging + prod)。
8. SSO 集成
# argocd-cm ConfigMap
data:
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: xxx
clientSecret: $dex.github.clientSecret
orgs:
- name: myorg
用 OIDC / GitHub / GitLab / LDAP 登录。
9. 与 Helm / Kustomize 集成
ArgoCD 原生支持:
- 纯 yaml
- Kustomize(path 下有 kustomization.yaml)
- Helm chart(path 下有 Chart.yaml)
- Jsonnet
- 自定义 config management plugin
10. 最佳实践
| 实践 | 说明 |
|---|---|
| 配置 repo 和代码 repo 分离 | 配置变化不触发 CI build |
| PR review 配置变更 | 不直接 push main |
| 开 selfHeal | 防手动 kubectl edit 导致漂移 |
| 每环境一个 Application | dev / staging / prod |
| 用 App of Apps 模式 | 一个 Application 管所有 Application |
| 限制 ArgoCD 权限 | 只能操作特定 namespace |
| Secret 用 sealed-secrets | 加密后提交 git |
11. 常见反模式
- CI 直接
kubectl apply:无审计、无 review - 配置和代码混一个 repo:每次代码改都触发 diff
- 不开 selfHeal:人手动改了 git 不知道
- prune 打开但没保护:git 误删 yaml = 生产资源被删
- secret 明文存 git:即使私有 repo 也不安全
- 不监控 OutOfSync:漂移了没人知
- 一个 Application 管所有服务:一个挂全挂
12. 延伸阅读
- ArgoCD 文档
- Flux 文档 — 另一个 GitOps 工具
- GitOps Principles
- App of Apps Pattern