第 11 章:ArgoCD 与 GitOps——现代运维方式
前面十章,我们已经学会了用 kubectl、YAML、Helm 管理 K8s。但在真实企业环境中,"人登录服务器执行命令"的模式存在严重问题:变更不可审计、回滚困难、容易误操作。GitOps 就是来解决这些问题的。本章手把手带你把 ArgoCD 装到真实集群,并完成一次"代码提交即发布"的完整体验。
11.1 传统运维模式的三大痛点
假设你的团队有 5 个人管理一个生产集群:
痛点一:变更不可追溯
# 周五晚上小王改了线上配置
$ kubectl set image deployment/backend backend=backend:v1.3.0
周一出问题了,查日志查了半天,没人记得这个改动。没有变更记录,没有审批,没有回滚依据。
痛点二:回滚靠记忆
# 张三记得上周是 v1.2.5 吧?
$ kubectl set image deployment/backend backend=backend:v1.2.5
# 不对,好像是 v1.2.4?
靠人记版本号,回滚风险极高。
痛点三: snowflake 集群(雪花集群)
每个环境、每个集群的配置都不一样,因为都是人工一点点改出来的。想要重新搭一个一模一样的环境?几乎不可能。
11.2 GitOps 的核心理念
GitOps 的回答很简单:
Git 仓库 = 集群状态的唯一事实来源(Single Source of Truth)。
┌─────────────┐ git push ┌──────────────────┐
│ 开发者 │ ─────────────────→ │ Git 仓库 │
└─────────────┘ │ 存所有 YAML/Helm │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ ArgoCD │
│ watch Git 变更 │
│ 自动同步到集群 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ K8s 集群 │
└──────────────────┘
所有变更都走 Git:
- 谁改的 →
git log - 改了什么 →
git diff - 什么时候改的 →
git commit --date - 怎么回滚 →
git revert - 环境怎么复制 → 新集群指向同一个 Git 仓库
11.3 ArgoCD 是什么
ArgoCD 是 CNCF 毕业项目,一个运行在 K8s 集群内部的 GitOps 工具。它持续做两件事:
- 监控 Git 仓库:你推送了什么新的期望状态
- 监控集群实际状态:现在集群长什么样
- 发现差异时同步:把集群拉到和 Git 一致
11.3.1 ArgoCD 核心组件
| 组件 | 作用 |
|---|---|
| application-controller | 核心控制器,watch Git 和集群,执行同步 |
| repo-server | 从 Git 拉取配置,渲染 Helm/Kustomize |
| server | API 服务,Web UI 和 CLI 的后端 |
| dex | 可选,对接 SSO/LDAP 做认证 |
| redis | 缓存 Git 仓库状态 |
11.4 在真实集群上安装 ArgoCD
使用 Helm 安装,适配我们的 4C8G 集群:
# 添加 ArgoCD 仓库
$ helm repo add argo https://argoproj.github.io/argo-helm
$ helm repo update
# 创建命名空间
$ kubectl create namespace argocd
# 安装(NodePort 暴露 Web,限制内存)
$ helm install argocd argo/argo-cd \
--namespace argocd \
--set server.service.type=NodePort \
--set controller.resources.limits.memory="512Mi" \
--set server.resources.limits.memory="256Mi" \
--set repoServer.resources.limits.memory="256Mi"
等待 Pod 全部 Running:
$ kubectl get pods -n argocd
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 3m
argocd-dex-server-xxx 1/1 Running 0 3m
argocd-redis-xxx 1/1 Running 0 3m
argocd-repo-server-xxx 1/1 Running 0 3m
argocd-server-xxx 1/1 Running 0 3m
11.5 获取访问地址和初始密码
# 查看 NodePort
$ kubectl get svc argocd-server -n argocd
NAME TYPE CLUSTER-IP PORT(S) AGE
argocd-server NodePort 10.99.168.210 80:30678/TCP 5m
# 初始密码
$ kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
xK8sF9mP2qR4nL7
浏览器访问:
http://121.40.218.245:30678
用户名:admin
密码:xK8sF9mP2qR4nL7(实际以你命令输出为准)
注意:安全组需放行 30678 端口。
11.6 准备 Git 仓库
假设你已经有一个 Git 仓库,里面放了应用配置:
gitops-demo/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
└── prod/
├── kustomization.yaml
└── replicas-patch.yaml
base/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: registry.cn-hangzhou.aliyuncs.com/demo/backend:v1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
把仓库推送到 GitHub/GitLab/阿里云 Codeup,拿到 HTTPS 地址和访问 Token。
11.7 在 ArgoCD 中创建 Application
可以用 UI,也可以用 CLI。这里用 YAML 方式最清晰:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourname/gitops-demo.git
targetRevision: main
path: overlays/prod
kustomize: {}
destination:
server: https://kubernetes.default.svc
namespace: prod
syncPolicy:
automated:
prune: true # Git 删除的资源,集群里也删除
selfHeal: true # 手动改集群会被自动回正
syncOptions:
- CreateNamespace=true
$ kubectl apply -f backend-argocd-app.yaml
打开 ArgoCD Web UI,你会看到应用状态:
- OutOfSync:Git 和集群不一致,等待同步
- Syncing:正在同步
- Synced:已一致
- Healthy:所有资源健康
11.8 体验一次"Git 提交即发布"
这是 GitOps 最精彩的环节。
第 1 步:修改 Git 中的镜像版本
# gitops-demo/base/deployment.yaml
image: registry.cn-hangzhou.aliyuncs.com/demo/backend:v1.1.0
$ git add .
$ git commit -m "upgrade backend to v1.1.0"
$ git push origin main
第 2 步:观察 ArgoCD
回到 Web UI:
- 几秒到几十秒内,应用状态变成 OutOfSync
- ArgoCD 自动检测到 Git 变化
- 执行同步,状态变成 Syncing
- 集群中 Deployment 的镜像被改成 v1.1.0
- K8s 开始滚动更新
- 全部完成后显示 Synced + Healthy
第 3 步:验证集群
$ kubectl get deployment backend -n prod -o jsonpath='{.spec.template.spec.containers[0].image}'
registry.cn-hangzhou.aliyuncs.com/demo/backend:v1.1.0
$ kubectl get pods -n prod
NAME READY STATUS AGE
backend-6f8d5c9b7a-abc12 1/1 Running 2m
backend-6f8d5c9b7a-def34 1/1 Running 2m
全程没有登录服务器,没有执行 kubectl set image。
11.9 回滚:git revert 即回滚
假设 v1.1.0 有 bug,要回滚:
$ git revert HEAD
$ git push origin main
ArgoCD 检测到 Git 回退到 v1.0.0,自动把集群也同步回 v1.0.0。回滚速度取决于镜像是否还在节点缓存中,通常几十秒到两分钟。
11.10 漂移检测:手动改集群会被自动回正
这是 GitOps 的杀手锏之一。假设有人绕过 ArgoCD,手动改了集群:
$ kubectl scale deployment backend --replicas=5 -n prod
ArgoCD 会很快检测到"Git 里 replicas=2,集群里 replicas=5",自动把集群改回 2 个副本。这种能力叫做 drift detection and self-healing。
当然,紧急情况下可以暂停自动同步,在 ArgoCD UI 里点击 Sync Disable。
11.11 ArgoCD 与 Helm 的结合
ArgoCD 不仅支持 Kustomize,也支持 Helm:
spec:
source:
repoURL: https://github.com/yourname/helm-charts.git
path: charts/backend
targetRevision: main
helm:
valueFiles:
- values-prod.yaml
parameters:
- name: replicaCount
value: "5"
实际项目中,常见组合是:
- 通用 Chart 放在 Git 仓库
- 每个环境一个
values-<env>.yaml - ArgoCD Application 指向对应 values 文件
11.12 生产环境建议
| 方面 | 建议 |
|---|---|
| 认证 | 对接 SSO/LDAP,不要用默认 admin 长期用 |
| 权限 | 一个团队一个 ArgoCD Project,限制可操作命名空间 |
| 同步策略 | 关键应用用手动 Sync,避免误操作自动扩散 |
| 备份 | 备份 argocd 命名空间下的 Secret 和 ConfigMap |
| 回滚 | 紧急情况下可直接 ArgoCD UI 回滚到历史同步状态 |
11.13 本章小结
- GitOps = Git 是集群状态的唯一事实来源
- ArgoCD 是 K8s 原生的 GitOps 工具,持续 watch Git 和集群,自动同步
- 安装:Helm 一键装,NodePort 暴露 UI
- 使用:创建 Application,关联 Git 仓库路径和集群目标命名空间
- 发布:改 Git 里的 YAML → push → ArgoCD 自动同步 → K8s 滚动更新
- 回滚:git revert 即可,秒级、可审计
- 漂移检测:手动改集群会被自动回正
11.14 课后练习
- 用 Helm 在你的测试集群安装 ArgoCD,记录 NodePort 和初始密码。
- 创建一个 Git 仓库,放入一个简单的 Deployment + Service。
- 在 ArgoCD 中创建 Application,完成首次同步。
- 修改 Git 中的镜像 tag,观察 ArgoCD 从 OutOfSync 到 Synced 的全过程。
- 在集群中手动
kubectl scale改副本数,观察 ArgoCD 是否会把它改回来(开启 selfHeal 的前提下)。
下一章(第 12 章):《3 台 ECS 从零搭建 K8s 集群 + Prometheus 监控栈实战》。这是整个专栏的实战基础,会把前面所有概念落地生根。