从 Pod 一直到自愈
目标
从手动启动一个 Pod 开始,分别创建 Deployment、Job、CronJob 和 DaemonSet,沿着所有者关系(ownerReferences)追踪对象,再故意删除一个 Pod,通过删除前后的列表证明自愈确实发生。
为什么重要
实际工作中几乎不会直接创建 Pod,但仍必须理解 Pod,因为所有工作负载控制器归根结底都只是持有 Pod 模板的外壳。Deployment 的问题大多其实是 Pod 模板的问题。
选择控制器的标准可归结为一点:**这个进程会自行结束吗?**若对不会结束的服务使用 Job,它永远无法完成;若对会结束的批处理使用 Deployment,它每次退出都会被重启,看起来像 CrashLoopBackOff。这是新人最常造成的事故之一。
最后一步是本实验的核心。大家都知道“删除 Pod 后会重新出现”,但很少有人亲眼确认回来的并不是同一个 Pod。名称发生变化这一事实,就是“不要依赖 Pod 名称”“不要把状态放在 Pod 内”等原则的共同依据。
步骤
- 创建命名空间
kcna-work,在其中创建镜像为nginx:1.27-alpine的 Podhello,使其达到 Running 状态。 - 在同一命名空间创建 Deployment
web。镜像为nginx:1.27-alpine,replicas 为 3,Pod 模板标签为app=web。 - 将
web的 replicas 扩展到 5,等待 5 个副本全部 Ready。 - 将
web创建的 ReplicaSet 名称以一行保存到/root/kcna-work/rs-name.txt;从web的 Pod 中任选一个,将其metadata.ownerReferences[0].kind值以一行保存到/root/kcna-work/owner.txt。 - 在同一命名空间创建 Job
report:镜像为busybox:1.36,completions为 3。再创建 CronJobnightly:schedule 为每天 03:00(0 3 * * *)。 - 在同一命名空间创建 DaemonSet
node-agent。镜像为busybox:1.36,请提供长期运行的命令,避免容器立即退出。 - 证明自愈:(a) 将
web的 5 个 Pod 名称保存到/root/kcna-work/before.txt;(b) 删除其中一个,并将被删名称以一行保存到/root/kcna-work/deleted.txt;(c) 等新 Pod Ready 后,将 5 个 Pod 名称保存到/root/kcna-work/after.txt。
参考
- 只提取 Pod 名称时,可使用
kubectl get pods -n kcna-work -l app=web -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'。 - 使用
kubectl get rs -n kcna-work查看 ReplicaSet 名称,用kubectl get rs <이름> -n kcna-work -o yaml查看 ownerReferences。 - DaemonSet 没有
kubectl create子命令,必须手写 YAML 后 apply。spec.selector.matchLabels必须与spec.template.metadata.labels相同。 - 常见错误 1:第 5 步 Job 的
restartPolicy留空。默认值Always会被 Job 拒绝。 - 常见错误 2:第 7 步删除 Pod 后立即生成
after.txt。此时新 Pod 尚未进入列表,文件不会有 5 行。
启动第一个 Pod
创建命名空间 kcna-work,在其中创建镜像为 nginx:1.27-alpine 的 Pod hello,使其达到 Running 状态。
先创建命名空间,再在其中创建 Pod。可用 kubectl run 快速创建,也可编写 YAML。Pod 可能需要几秒才能 Running,请检查状态后再评分。
让 Deployment 管理 Pod
在同一命名空间创建 Deployment web。镜像为 nginx:1.27-alpine,replicas 为 3,Pod 模板标签为 app=web。
kubectl create deployment 会自动为 Pod 模板添加标签。请用 -o yaml 查看添加了哪些标签。已就绪副本数可在 status 中查看。
更改副本数
将 web 的 replicas 扩展到 5,等待 5 个副本全部 Ready。
可以用 kubectl scale 一行完成,也可修改清单后再次 apply。想一想哪种方式会留下记录。评分会同时检查 spec 和 status。
追踪所有者关系
将 web 创建的 ReplicaSet 名称以一行保存到 /root/kcna-work/rs-name.txt;从 web 的 Pod 中任选一个,将其 metadata.ownerReferences[0].kind 值以一行保存到 /root/kcna-work/owner.txt。
命名空间的 ReplicaSet 列表中,名称后带有哈希。用 -o jsonpath 或 -o yaml 查看该对象的 metadata.ownerReferences,即可知道创建者;Pod 也有同一字段。
会结束的任务:Job 与 CronJob
在同一命名空间创建 Job report:镜像为 busybox:1.36,completions 为 3。再创建 CronJob nightly:schedule 为每天 03:00(0 3 * * *)。
Job 的 Pod 模板不能把 restartPolicy 设为 Always。想清原因后,正确值就很明确。CronJob 的 schedule 使用标准五段 cron 表达式。
每个节点一个:DaemonSet
在同一命名空间创建 DaemonSet node-agent。镜像为 busybox:1.36,请提供长期运行的命令,避免容器立即退出。
DaemonSet 清单没有 replicas 字段,因为数量不是由人指定。kubectl create 无法创建它,必须手写 YAML,并让 selector 与 template.metadata.labels 一致。
删除 Pod 以证明自愈
证明自愈:(a) 将 web 的 5 个 Pod 名称保存到 /root/kcna-work/before.txt;(b) 删除其中一个,并将被删名称以一行保存到 /root/kcna-work/deleted.txt;(c) 等新 Pod Ready 后,将 5 个 Pod 名称保存到 /root/kcna-work/after.txt。
必须分别保存删除前列表、被删名称和删除后列表,评分才有依据。删除后要等控制器创建新 Pod,再获取列表,才能得到 5 行。请亲自确认新 Pod 名称是否与被删名称相同。