这是课程体系的最后一课,也是把你学过的三块拼在一起的那一课:
Git(0003) + CI/CD(0006) + Kubernetes(0014–0016)
↓ ↓ ↓
版本控制 自动构建镜像 容器编排
↓ ↓ ↓
└───────────────┴────────────────────┘
↓
GitOps = 三者合一
学完这课,你就能回答面试里最经典的一道进阶题:「从 git push 到 Pod 更新,中间发生了什么?」
回忆你现在怎么部署 K8s 应用(0014–0016):
# 改代码 → 手动构建镜像 → 手动 push 到 registry → 手动 kubectl apply
docker build -t myapp:v2 .
docker push myapp:v2
kubectl set image deployment/myapp app=myapp:v2
三个问题:
GitOps 的原则:Git 仓库是集群期望状态的唯一真相来源(Single Source of Truth)。集群里跑的任何东西,必须在 Git 里定义。任何对集群的手动修改,会被自动回滚。
开发者 push 到 Git
│
▼
CI(GitHub Actions)
构建镜像 + push 到 registry
│
▼
更新 Git 里的 K8s YAML
(改 image tag)
│
▼
ArgoCD 检测到 Git 变化
│
▼
ArgoCD 对比 Git vs 集群
┌─ 一致?什么都不做
└─ 不一致?自动 sync,把集群拉到和 Git 一样
│
▼
Git = 期望状态 ←→ K8s 集群 = 实际状态
ArgoCD 持续监控差异
| 概念 | 是什么 | 类比 |
|---|---|---|
| Application(ArgoCD) | ArgoCD 管理的一个 K8s 应用。包含 Git 仓库地址 + K8s 资源路径 + 目标集群 | Terraform 的 Resource |
| Sync(同步) | 把集群实际状态拉到 Git 声明的期望状态 | terraform apply |
| Drift(漂移) | 集群状态偏离了 Git——有人手动改了集群 | terraform plan 里的 diff |
用你的 VPS 上的 k3s(如果没有,先跑 curl -sfL https://get.k3s.io | sh -):
# 1. 创建 argocd namespace
kubectl create namespace argocd
# 2. 安装 ArgoCD(官方一条命令)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 3. 等所有 Pod 就绪(约 1-2 分钟)
kubectl wait --for=condition=ready pod --all -n argocd --timeout=300s
# 4. ArgoCD 默认不暴露外部访问。用 port-forward 临时访问 Web UI
kubectl port-forward svc/argocd-server -n argocd 8443:443 &
# 打开 https://localhost:8443(自签名证书,点 Advanced → Proceed)
# 5. 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
echo
# 6. 安装 argocd CLI(另一条途径,推荐)
curl -sSL -o /tmp/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 /tmp/argocd /usr/local/bin/argocd
# 用 CLI 登录
argocd login localhost:8443 --insecure --username admin --password $(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
假设你有一个 K8s 应用,它的 YAML 存在 GitHub 仓库里。目录结构:
# 你的应用仓库(比如 bram35mm/devops-course 的 k8s/ 目录)
k8s/
├── deployment.yaml
├── service.yaml
└── ingress.yaml
告诉 ArgoCD 去监控这个目录:
# 方法一:CLI(最快)
argocd app create demo-app \
--repo https://github.com/bram35mm/my-k8s-app.git \
--path k8s/ \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--sync-policy auto \ # 自动同步(Git 变了就自动 apply)
--auto-prune \ # Git 里删了的 YAML,集群里也删
--self-heal # 有人手动改集群 → 自动修回 Git 的状态
argocd app get demo-app # 查看状态
# Health: Healthy | Sync: Synced ← 期望的样子
# 方法二:Application YAML(IaC 风格——推荐生产使用)
cat > argocd-app.yaml << 'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: demo-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/bram35mm/my-k8s-app.git
targetRevision: main
path: k8s/
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true # 自动删除不在 Git 里的资源
selfHeal: true # 自动修复手动变更
syncOptions:
- CreateNamespace=true
EOF
kubectl apply -f argocd-app.yaml
这是 DevOps 面试必考的全链路流程。把 CI(0006)+ GitOps(本课)串起来:
# 完整流程(5 步,每一步都是自动化的):
# Step 1: 开发者改代码 + push
git add . && git commit -m "feat: add health check endpoint"
git push
# Step 2: GitHub Actions 触发 CI(0006 学的)
# .github/workflows/ci.yml:
# - 跑测试
# - docker build -t ghcr.io/bram35mm/myapp:$COMMIT_SHA
# - docker push ghcr.io/bram35mm/myapp:$COMMIT_SHA
# - 更新 k8s/deployment.yaml 里的 image tag
# - git commit + push 更新后的 YAML
# Step 3: ArgoCD 每 3 分钟自动检测 Git 变化
# 检测到 k8s/deployment.yaml 的 image tag 变了
# Step 4: ArgoCD 对比 Git vs 集群 → 发现不一致
# Git: image: ghcr.io/bram35mm/myapp:abc123
# 集群: image: ghcr.io/bram35mm/myapp:def456
# → OutOfSync!
# Step 5: ArgoCD 自动 sync
# kubectl apply 新的 deployment.yaml
# → Synced + Healthy
把这个流程写成 GitHub Actions Workflow(接在 0006 的 CI 后面):
# .github/workflows/deploy.yml
name: Deploy to K8s via GitOps
on:
push:
branches: [main]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
- name: Push to GHCR
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Update image tag in K8s YAML
run: |
cd k8s
sed -i "s|image:.*|image: ghcr.io/${{ github.repository }}:${{ github.sha }}|" deployment.yaml
git config user.name "GitOps Bot"
git config user.email "bot@gitops"
git add deployment.yaml
git commit -m "deploy: update image to ${{ github.sha }}" || true
git push
这个 Workflow 做的事情:代码 push → 构建镜像 → 推送到 registry → 更新 Git 里的 YAML → ArgoCD 自动 sync 到集群。全程零手动操作。
任务:给你已有的 K8s 应用(或 Lesson 0005 的 Docker demo)加上 ArgoCD 管理,实现 git push 自动部署。
# 在你的 k3s 上(VPS 或本机):
# 1. 确认 ArgoCD 在跑
kubectl get pods -n argocd
# 2. 准备一个简单的 K8s 应用 YAML
mkdir -p /tmp/gitops-demo/k8s
cat > /tmp/gitops-demo/k8s/deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata: { name: gitops-demo }
spec:
replicas: 1
selector: { matchLabels: { app: gitops-demo } }
template:
metadata: { labels: { app: gitops-demo } }
spec:
containers:
- name: app
image: nginx:alpine
ports: [{ containerPort: 80 }]
EOF
cat > /tmp/gitops-demo/k8s/service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata: { name: gitops-demo }
spec:
selector: { app: gitops-demo }
ports: [{ port: 80, targetPort: 80 }]
EOF
# 3. 推到 GitHub(如果你已经 fork/clone 了这个课程仓库,直接放进去)
cd /tmp/gitops-demo
git init && git add -A && git commit -m "k8s app for GitOps demo"
# git remote add origin ... && git push
# 4. 创建 ArgoCD Application,指向你的 GitHub 仓库
argocd app create gitops-demo \
--repo https://github.com/YOUR_USER/YOUR_REPO.git \
--path k8s/ \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--sync-policy auto \
--auto-prune \
--self-heal
# 5. 验证
argocd app get gitops-demo
# 状态: Healthy + Synced
# 6. 测试 self-heal:手动改集群,看 ArgoCD 修回去
kubectl scale deployment gitops-demo --replicas=3
# 等 3 分钟...
kubectl get deployment gitops-demo
# 又变回 1 了!ArgoCD 检测到漂移,自动修复了
面试时被问到 GitOps,记住这四句话就够了:
回头看看你走过的路:
0001 什么是 DevOps? ← 建立了坐标系
0002 Linux 命令行基础 ← 学会了和服务器说话
0003 Git 进阶 ← 掌握了版本控制的深层用法
0004 Shell 脚本编程 ← 自动化从脚本开始
0005 Docker 入门 ← 容器化一切
0006 CI/CD:GitHub Actions ← 代码 push 自动构建测试
0007 部署实战 ← 把应用推到线上
0008 IaC:Terraform ← 基础设施写成代码
0009 监控 & 可观测性 ← 知道系统在干什么
0010 Linux 系统管理进阶 ← 能管服务器了
0011 Linux 排错实战 ← 出问题能自己修
0012 网络协议基础 ← 理解了 TCP/DNS/TLS
0013 网络实战与负载均衡 ← 能配置生产级 Nginx
0014 K8s 核心概念 ← 容器编排上路了
0015 K8s 网络与配置 ← 深入 K8s 内部
0016 K8s 生产实践 ← Helm + HPA + RBAC
0017 Ansible:配置管理 ← 管 100 台服务器像管 1 台
0018 日志系统 ← Metrics + Logs 双支柱
0019 GitOps:ArgoCD ← Git push 即部署
从「前端开发,不懂 DevOps」到能搭 CI/CD + Docker + K8s + IaC + 监控 + 日志 + GitOps 的完整自动化平台——你做到了。