第 11 章:ArgoCD 与 GitOps——现代运维方式

6 阅读4分钟

第 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 工具。它持续做两件事:

  1. 监控 Git 仓库:你推送了什么新的期望状态
  2. 监控集群实际状态:现在集群长什么样
  3. 发现差异时同步:把集群拉到和 Git 一致

11.3.1 ArgoCD 核心组件

组件作用
application-controller核心控制器,watch Git 和集群,执行同步
repo-server从 Git 拉取配置,渲染 Helm/Kustomize
serverAPI 服务,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(实际以你命令输出为准)

image.png

注意:安全组需放行 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:

  1. 几秒到几十秒内,应用状态变成 OutOfSync
  2. ArgoCD 自动检测到 Git 变化
  3. 执行同步,状态变成 Syncing
  4. 集群中 Deployment 的镜像被改成 v1.1.0
  5. K8s 开始滚动更新
  6. 全部完成后显示 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 课后练习

  1. 用 Helm 在你的测试集群安装 ArgoCD,记录 NodePort 和初始密码。
  2. 创建一个 Git 仓库,放入一个简单的 Deployment + Service。
  3. 在 ArgoCD 中创建 Application,完成首次同步。
  4. 修改 Git 中的镜像 tag,观察 ArgoCD 从 OutOfSync 到 Synced 的全过程。
  5. 在集群中手动 kubectl scale 改副本数,观察 ArgoCD 是否会把它改回来(开启 selfHeal 的前提下)。

下一章(第 12 章):《3 台 ECS 从零搭建 K8s 集群 + Prometheus 监控栈实战》。这是整个专栏的实战基础,会把前面所有概念落地生根。