外观
实训 16:Kubernetes 滚动发布、故障与回滚
约 1848 字大约 6 分钟
云计算实训第16次课
2026-07-30
1. 任务情境
课程站点当前运行 v1。你需要使用 Deployment 滚动发布 v2,记录修订历史并验证 Service 页面。随后把错误镜像作为新修订提交,保留 rollout 超时、ImagePullBackOff 和事件证据;确认 v2 仍在服务后,明确回滚到最后一个已验证修订并完成同路回归。
2. 环境与边界
| 项目 | 课堂要求 |
|---|---|
| 控制端 | WSL 或教师机本地终端 |
| 集群 | 教师指定的第 16 次课隔离 K3s/k3d |
| 命名空间 | cloud-course-16 |
| Deployment/Service | lesson16-web |
| 正确镜像 | nginx:1.27-alpine |
| 故障镜像 | nginx:lesson16-missing,仅用于本课隔离环境 |
| 允许变更 | 本课清单、修订、错误镜像和本课回滚 |
| 禁止操作 | 其他命名空间、系统组件、共享工作负载、全局删除 |
报告不得包含 kubeconfig、令牌、证书、完整地址和其他命名空间数据。
3. 准备实验目录
[WSL] mkdir -p "$HOME/cloud-course/lab-16"创建个人目录。
[WSL] cp -R starter/. "$HOME/cloud-course/lab-16/"复制清单、验收和清理脚本。
[WSL] cd "$HOME/cloud-course/lab-16"进入本课目录。
起始文件:
lab-16/
├── manifests/
│ ├── namespace.yaml
│ ├── service.yaml
│ ├── configmap-v1.yaml
│ ├── configmap-v2.yaml
│ ├── deployment-v1.yaml
│ └── deployment-v2.yaml
├── verify.sh
└── cleanup.sh4. 步骤一:上下文与清单预检
[WSL] kubectl config current-context与教师公布的第 16 次课上下文逐字核对。
[WSL] kubectl get nodes确认至少一个节点 Ready。
[WSL] kubectl get namespace cloud-course-16首次执行应为 NotFound。若已经存在,先联系教师,不接管未知资源。
[WSL] kubectl apply --dry-run=client \
-f manifests/namespace.yaml \
-f manifests/configmap-v1.yaml \
-f manifests/service.yaml \
-f manifests/deployment-v1.yaml预检 v1 对象。
[WSL] kubectl diff -f manifests/deployment-v1.yaml在 Namespace 创建后,可用 diff 预览 Deployment 与当前对象的差异。diff 返回 1 通常表示存在差异,不等于命令故障。
检查点:
- replicas 为 3;
maxUnavailable: 0、maxSurge: 1;- Pod 标签为 v1;
- ConfigMap 引用为 v1;
- Service 选择 app 标签,不固定版本;
- 探针和资源限制存在。
5. 步骤二:发布并验收 v1
[WSL] kubectl apply \
-f manifests/namespace.yaml \
-f manifests/configmap-v1.yaml \
-f manifests/service.yaml \
-f manifests/deployment-v1.yaml创建 v1 基线。
[WSL] kubectl rollout status deployment/lesson16-web \
-n cloud-course-16 --timeout=120s等待三个副本就绪。
[WSL] kubectl rollout history deployment/lesson16-web -n cloud-course-16预期 revision 1 为 lesson16 release v1。
[WSL] kubectl exec -n cloud-course-16 deploy/lesson16-web -- \
wget -q -O - http://lesson16-web | grep 'release='预期 release=v1。
6. 步骤三:滚动发布 v2
[WSL] kubectl apply --dry-run=client \
-f manifests/configmap-v2.yaml \
-f manifests/deployment-v2.yaml先检查 v2 对象能够生成。
[WSL] kubectl apply \
-f manifests/configmap-v2.yaml \
-f manifests/deployment-v2.yaml提交 v2 内容与 Pod 模板。
[WSL] kubectl rollout status deployment/lesson16-web \
-n cloud-course-16 --timeout=120s记录新旧副本交接过程和成功行。
[WSL] kubectl rollout history deployment/lesson16-web -n cloud-course-16预期同时出现 v1 与 v2。
[WSL] kubectl get deployment,replicaset,pods \
-n cloud-course-16 -l app.kubernetes.io/name=lesson16-web -o wide记录 Deployment 3/3、新 ReplicaSet 三个副本和旧 ReplicaSet 0 个副本。
[WSL] kubectl exec -n cloud-course-16 deploy/lesson16-web -- \
wget -q -O - http://lesson16-web | grep 'release='预期 release=v2。
截图 1 包含 rollout success、v1/v2 历史、3/3 和 v2 页面。
7. 步骤四:注入错误镜像修订
故障前记录:
[WSL] kubectl get deployment lesson16-web -n cloud-course-16 \
-o jsonpath='image={.spec.template.spec.containers[0].image}{" version="}{.spec.template.metadata.labels.app\.kubernetes\.io/version}{"\n"}'预期正确镜像和 v2 标签。
在同一次 patch 中写入故障说明和错误镜像:
[WSL] kubectl patch deployment lesson16-web -n cloud-course-16 \
--type=strategic \
-p '{"metadata":{"annotations":{"kubernetes.io/change-cause":"lesson16 fault invalid image"}},"spec":{"template":{"spec":{"containers":[{"name":"web","image":"nginx:lesson16-missing"}]}}}}'不要把“先 annotate、再 set image”拆成两步,否则可能让当前修订的 change-cause 变得难以解释。
[WSL] kubectl rollout status deployment/lesson16-web \
-n cloud-course-16 --timeout=15s预期超时,退出码非 0。
[WSL] kubectl get deployment,pods \
-n cloud-course-16 -l app.kubernetes.io/name=lesson16-web -o wide预期三个旧 Pod 仍 1/1 Running,一个新 Pod 先出现 ErrImagePull,重试后进入 ImagePullBackOff;Deployment READY 3/3、UP-TO-DATE 1、AVAILABLE 3。
[WSL] fault_pod="$(kubectl get pods -n cloud-course-16 \
-l app.kubernetes.io/name=lesson16-web \
-o jsonpath='{range .items[?(@.status.containerStatuses[0].ready==false)]}{.metadata.name}{"\n"}{end}' \
| head -n 1)"只从本课标签中取得尚未就绪的故障 Pod,不依赖它当前处于哪一个镜像拉取重试阶段。
[WSL] kubectl describe pod -n cloud-course-16 "$fault_pod"在 Events 中寻找 Failed、not found、ErrImagePull 和 ImagePullBackOff。
[WSL] kubectl exec -n cloud-course-16 deploy/lesson16-web -- \
wget -q -O - http://lesson16-web | grep 'release='预期仍返回 v2,说明旧副本暂时保住用户路径;不能据此宣告故障发布成功。
截图 2 包含超时、坏 Pod、事件和仍返回 v2 的用户路径。
8. 步骤五:选择并执行回滚
[WSL] kubectl rollout history deployment/lesson16-web -n cloud-course-16确认修订 2 是最后一个已验证的 v2,修订 3 是错误镜像。
[WSL] kubectl rollout undo deployment/lesson16-web \
-n cloud-course-16 --to-revision=2明确回到修订 2。
[WSL] kubectl rollout status deployment/lesson16-web \
-n cloud-course-16 --timeout=120s等待回滚完成。Deployment 达到 3/3 后,故障 Pod 还可能短暂处于退出过程;继续观察,直到本课 Pod 全部为 1/1 Running 再运行最终验收。
[WSL] kubectl rollout history deployment/lesson16-web -n cloud-course-16观察 v2 模板成为新的修订 4。修订号前进是正常现象。
[WSL] kubectl get deployment lesson16-web -n cloud-course-16 \
-o jsonpath='image={.spec.template.spec.containers[0].image}{" version="}{.spec.template.metadata.labels.app\.kubernetes\.io/version}{"\n"}'预期 image=nginx:1.27-alpine version=v2。
[WSL] kubectl exec -n cloud-course-16 deploy/lesson16-web -- \
wget -q -O - http://lesson16-web | grep 'release='预期 release=v2。
[WSL] bash verify.sh运行完整自动验收。
截图 3 包含回滚成功、历史、正确模板、3/3 和 v2 页面。
9. 故障排查对照
| 现象 | 优先证据 | 可能范围 | 不要先做 |
|---|---|---|---|
| rollout 超时 | Deployment、ReplicaSet、Pods | 新修订未完成 | 重装集群 |
| ImagePullBackOff | Pod Events、镜像字段 | 镜像名、仓库、凭据或网络 | 删除旧可用 Pod |
| Running 但 0/1 | readiness 事件、应用日志 | 路径、端口、启动时长 | 删除探针 |
| 新旧版本混合过久 | strategy、readyReplicas、events | 就绪或资源门禁 | 全局 scale |
| 回滚完成但页面不对 | 当前模板、ConfigMap、Service 请求 | 独立对象未恢复 | 宣告全系统恢复 |
10. 清理
[WSL] bash cleanup.sh只删除 cloud-course-16。
[WSL] kubectl get namespace cloud-course-16预期 NotFound。
[WSL] kubectl get namespaces确认其他命名空间仍在。教师统一删除本课 k3d 集群。
11. 人工检查
教师还会核对:
- v1、v2、故障和回滚的时间顺序是否清楚;
- CHANGE-CAUSE 是否与对应 Pod 模板变更一致;
- 错误镜像期间旧 v2 是否仍提供 Service 路径;
- 是否把 ImagePullBackOff 证据与镜像故障假设对应;
- 回滚是否明确选择修订 2;
- 当前镜像、v2 标签、3/3、端点和页面是否全部恢复;
- 是否说明 Deployment 回滚不覆盖数据库和独立对象;
- 清理是否只触及本课命名空间。
12. 报告与提交
填写:
班级_学号_姓名_第16次课_Kubernetes发布回滚报告.docx至少包含:
- 上下文、命名空间和清单边界;
- v1 基线;
- v2 滚动过程、历史和页面;
- 错误镜像的超时、对象状态和事件;
- 为什么旧 v2 暂时仍可用;
- 回滚目标、动作和完整回归;
- 自动验收、人工检查和清理;
- Deployment 回滚的能力边界。
只上传 Word 到智慧职教“第16次课”。
