综合练习
这一课你将能做到
- 交付一份可
helm lint / helm template / helm install 的 backend Chart,包含 Deployment、Service、探针、env 注入与 Secret 引用,参数覆盖副本、镜像、DB 地址、Redis、资源限额
- 准备 dev / prod 两份 values,跑通一次
upgrade --install + 失败回滚演练 + helm rollback,用命令与 Pod 状态验收
- (选做)提交 Chart + values 到 Git 并创建 Argo CD Application,完成「改 tag 的 PR → 自动同步 → 观察 Pod」的 GitOps 闭环
为什么要学
前面十一课各给了一块零件:概念(intro)、工具链(install)、骨架(structure)、模板(templates)、生命周期(release)、依赖(deps)、GitOps 原则(gitops-intro)、仓库布局(repo)、Argo(argocd)、Flux(flux)、发布策略(patterns)。本课把零件组装成 可演示、可复现的交付物,对齐仓库目标布局:deploy/charts/backend + deploy/env/dev|prod。做完这份练习,你就完成了从「会写裸 YAML」到「会打包 + 可声明式持续部署」的完整跨越——这正是本 track 标题承诺的能力。
先建立图像
交付物全景
deploy/
charts/
backend/ ← 你维护的业务 Chart
Chart.yaml
values.yaml
templates/(deployment.yaml / service.yaml / _helpers.tpl / NOTES.txt)
env/
dev/backend-values.yaml
prod/backend-values.yaml
argocd/applications/ ← 选做 GitOps
backend-dev.yaml
验收主路径
helm lint → helm template → install → kubectl get → 健康探测
upgrade --install → 失败演练 → history → rollback
(选做)Argo Application → 改 tag PR → 自动 sync
| 验收项 | 命令/现象 | 通过标准 |
|---|
| 渲染合法 | helm lint + helm template | 无 Error,含 Deploy+Svc,两环境 diff 符合预期 |
| 可安装 | helm install … -n … | Release deployed,Pod Running |
| 可升级回滚 | upgrade + rollback | history 出现新 revision |
| 密钥安全 | 全文检索 values | 无明文密码,只有 Secret 名 |
| GitOps(选做) | Argo UI | tag 变更自动 OutOfSync→Synced |
跟着做
步骤 1:确认或创建 Chart 骨架
仓库已有 deploy/charts/backend 就在其上扩展;否则:
mkdir -p deploy/charts && cd deploy/charts
helm create backend
# 按 helm-structure 课裁剪:保留 deployment/service/_helpers/NOTES
Chart.yaml:
apiVersion: v2
name: backend
description: CodeRoadMap Spring Boot backend (MySQL external, Redis via env)
type: application
version: 0.1.0
appVersion: "1.0.0"
步骤 2:参数化 values(默认 + 双环境)
deploy/charts/backend/values.yaml:
replicaCount: 1
image:
repository: registry.example/coderoadmap-backend
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8080
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
probes:
readinessPath: /actuator/health/readiness
livenessPath: /actuator/health/liveness
db:
host: mysql.coderoadmap-dev.svc
passwordSecretName: backend-db-secret
passwordSecretKey: password
redis:
host: redis.coderoadmap.svc
resources: {}
deploy/env/dev/backend-values.yaml(只写差异):
replicaCount: 1
image:
tag: "1.0.0-dev"
deploy/env/prod/backend-values.yaml:
replicaCount: 2
image:
tag: "1.0.0"
db:
host: mysql.prod.internal
resources:
limits:
cpu: "500m"
memory: 512Mi
模板要点回顾:镜像串加引号、env 用 secretKeyRef 引密码、resources 用 with .Values.resources 条件渲染、探针从 .Values.probes.* 取路径——四个参数化点都在前课练过。
步骤 3:本地渲染 + 学习集群安装
helm lint deploy/charts/backend
helm template backend deploy/charts/backend \
-f deploy/env/dev/backend-values.yaml > /tmp/backend-dev.yaml
# 抽查:副本 1、tag -dev、无 resources 块
helm upgrade --install backend deploy/charts/backend \
-n coderoadmap-dev --create-namespace \
-f deploy/env/dev/backend-values.yaml \
--wait --timeout 5m --atomic
kubectl get pods,svc -n coderoadmap-dev
若没有真实业务镜像,可临时把 image.repository 指向公共测试镜像验证结构,再换回。
步骤 4:健康探测
# 先确认 Service 实际名字(fullname helper 可能带前缀)
kubectl get svc -n coderoadmap-dev
kubectl -n coderoadmap-dev port-forward svc/backend 8080:8080
# 另开终端
curl -sS http://127.0.0.1:8080/actuator/health/readiness
返回 {"status":"UP"} 即链路通。路径以你的 Spring Boot 实际 actuator 配置为准,改 values 的 probes.* 而不是改模板。
步骤 5:升级 + 失败回滚演练
# 正常升级
helm upgrade --install backend deploy/charts/backend \
-n coderoadmap-dev -f deploy/env/dev/backend-values.yaml \
--set image.tag=1.0.1 --wait --timeout 5m --atomic
helm history backend -n coderoadmap-dev
# 失败演练:不存在的镜像
helm upgrade --install backend deploy/charts/backend \
-n coderoadmap-dev -f deploy/env/dev/backend-values.yaml \
--set image.tag=does-not-exist --wait --timeout 2m --atomic \
|| echo "EXPECTED FAILURE"
# 手动回滚路径(若演练环境未开 atomic)
helm rollback backend 2 -n coderoadmap-dev
在笔记记录每次操作前后的 revision 号与 Pod 变化——这份记录就是你的「发布手册」雏形。
步骤 6:选做 GitOps 闭环
提交 Chart + values 后,参照 gitops-argocd 课创建 deploy/argocd/applications/backend-dev.yaml(path 指 deploy/charts/backend,valueFiles 相对上溯 ../../env/dev/)。验证三件事:
- UI 里
backend-dev 出现且 Synced
- 开一个只改
image.tag 的 PR,merge 后自动 OutOfSync→Synced→Pod 滚动
kubectl scale 手改副本被 selfHeal 拉回
步骤 7:清单勾选
讲清楚要点
- 因为综合练习的目标是可复现交付,所以验收以命令与现象为准——lint/template/install/history 每条都要真跑过,「我觉得装上了」不算数。
- 因为环境差异必须进 values,所以禁止为交差复制两份 Chart 目录——一份 Chart + 两份 values 是本 track 的核心纪律。
- 因为生产密钥不能进 Git,所以练习也要养成 Secret 名引用习惯——学习集群用
kubectl create secret 手工创建即可,姿势从练开始。
- 因为 GitOps 是加分项,所以主路径先保证 Helm CLI 闭环——本地渲染、安装、升级、回滚全绿之后,Argo 通了才是锦上添花。
- 因为 Service 名受 fullname helper 影响,所以 port-forward 前先
kubectl get svc——不要死记示例名。
- 因为 helm rollback 与 git revert 是两套工具,所以两种都演练——CLI rollback 理解 Release 机制;Git revert 理解 GitOps 真相源,二者在真实团队里共存。
你可能会懵的地方
- 仓库已有 deploy/ 脚本,冲突吗?
不删现网路径,
charts/、env/、argocd/ 是新增目录并行演进;旧脚本在 K8s 化完成后再清理。
- install 后一直 ImagePullBackOff?
检查 repository/tag 是否真实可拉、私有仓库凭证是否配置;学习环境先用公共镜像验证 Chart 结构。
- 探针 404?
actuator 路径与应用配置有关(management.endpoints.web.base-path);改 values 的
probes.* 对齐应用,不改模板。
- 必须做完 Argo 才算完课?
不是。最低合格线:Chart + 双环境 values + upgrade/rollback 演练;Argo 按环境资源选做。
- 下一步学什么?
顺着你刚搭的链路向上走:用 github-actions-essentials 给 backend 配 CI——测试、构建镜像、推送 registry、自动开「改 tag」的 PR;再回头补 Kubernetes 路线图的 Helm/GitOps/ArgoCD 节点勾选。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 交一份没有 Chart.yaml 的 YAML 目录 | 不是 Chart | 按标准结构组织 |
| prod values 写明文密码 | 泄密 | Secret + passwordSecretName |
| 不跑 lint 直接 install | 低级 YAML 错误进集群 | 先 lint/template |
| 升级成功从不演练回滚 | 事故时不会退 | 故意升错再 rollback 一次 |
| 每个环境复制一份 Chart | 模板分叉 | 单 Chart 多 values |
| 只追 Argo 界面不跑 CLI | 基本功缺失 | CLI 闭环为主,GitOps 加分 |
卡点急救
- 现象:
helm lint 报 helper 未定义——裁剪脚手架时删多了;对照 helm-structure 课补回 fullname/labels/selectorLabels 三个 define。
- 现象:Pod 反复重启、探针失败——
kubectl describe pod 看 readiness/liveness 失败详情;多半是 actuator 路径不匹配或应用依赖(MySQL/Redis)不可达;先修 values 里的 db/redis 地址与探针路径。
- 现象:Argo 一直 OutOfSync 且 diff 显示「多出资源」——有人手改过集群(如手动 scale);selfHeal 开启会自动拉回;否则查 diff 来源、恢复 Git 或确认该改动并回写 values。
面试常问
-
描述你如何把一个 Spring Boot 应用从零交付到 K8s 并接上 GitOps。
标准叙述线(可背):Dockerfile 构建镜像 → 编写业务 Chart(Deployment/Service/探针/env,参数化副本、tag、DB 地址,密码走 Secret 引用)→ 双环境 values 分文件 → helm lint/template 本地验证 → upgrade --install --wait --atomic 部署 → Chart 与 values 进 Git、prod 目录加评审保护 → Argo CD Application 指向 Chart 与 env values,automated+selfHeal → 发布=改 tag 的 PR,回滚=revert。全程 CI 只负责构建推镜像,不持集群凭据。
-
你的 values 里为什么没有密码?密码怎么进去的?
values 只保留 passwordSecretName/passwordSecretKey 引用;实际密文由集群内 Secret 提供(学习环境手工创建,生产用 External Secrets 从 Vault 同步或 Sealed Secrets 封存)。这样 Git 仓库可公开审计而不泄漏凭据,轮换密码也不需要改 Chart。
-
如何验证一次发布是「真的成功」?
三层验证:同步层(helm history/Argo UI Synced)、资源层(kubectl get pods Ready、探针通过)、业务层(curl 健康端点、错误率/延迟指标无异常)。只看命令返回成功是初级错误——--wait --atomic 已把命令成功对齐资源就绪,但仍需业务指标确认。
自测三问
- 列出本课最低合格交付物的文件路径清单(Chart 与两份 values)。
- 写出从
helm template 到 helm rollback 的完整命令序列(含失败演练分支)。
- 选做 GitOps 时,改哪个文件会触发同步?为什么密钥依然不能出现在这个文件里?
小结一句话
一份 backend Chart + dev/prod 双 values + upgrade/rollback 演练 + 可选 Argo 同步 = 本 track 的完整交付物;至此你已打通「docker → k8s → helm → GitOps」的入门轨,下一步接 CI 构建链路。
延伸