造一个真故障,再把它读出来
本实验在会发生真实故障的集群中运行
VM 中运行着真正的 k3s。由于 kubelet 和 containerd 确实在运行,
镜像拉取失败时会出现 ImagePullBackOff,进程退出时会变成
CrashLoopBackOff,超出内存时也会真的发生 OOMKilled。
CKA 课程中其他实验使用的模拟集群,甚至无法制造这些症状。 因此此前只能通过文字学习。
首次启动大约需要 2 分钟。
目标
有意制造六种故障,并亲手掌握应从哪里、以何种方式读取各自的原因。 最后,将其汇总成一张分类表。
为什么这很重要
故障排查不是知识,而是条件反射。看到 kubectl get pod 显示的文字后,
必须在 3 秒内想到“下一步看哪里”。
而且,看似相似的症状,其原因可能完全不同。
Pending和ContainerCreating都表示“尚未启动”,但前者是调度器问题,后者是 kubelet 问题。liveness失败和readiness失败都表示“probe 失败”,但前者会引发重启,后者只会将 Pod 从流量中移除。- 通过
env引用不存在的 ConfigMap 会导致CreateContainerConfigError,而将相同 ConfigMap 作为卷引用时,则会处于Pending。
这些区别无法只靠背诵掌握,必须亲手制造才能形成直觉。
步骤
所有 Pod 都创建在 broken namespace 中。名称已固定。
ts-image——使用不存在的镜像制造ImagePullBackOff,从事件中读取实际原因并保存到/root/cka/imagepull.txt。然后将修复后的版本启动为ts-image-fixed。ts-crash——使用立即退出的命令制造CrashLoopBackOff,读取已经退出的容器日志并保存到/root/cka/crashloop.txt。同时记录重启次数。ts-oom——让容器使用超过内存limits的内存以制造OOMKilled,并将结果连同退出码保存到/root/cka/oom.txt。ts-liveness和ts-readiness——分别只配置一个会失败的 probe,将结果有何不同保存到/root/cka/probe.txt。ts-pending——创建无法调度的 Pod,并将调度器留下的原因保存到/root/cka/pending.txt。还要写出Pending与ContainerCreating的区别。ts-config(env 引用)和ts-volume(卷引用)——二者都指向不存在的 ConfigMap,并将状态为何不同保存到/root/cka/configref.txt。- 在
/root/cka/triage.md中创建包含五种症状的分类表。每一行为증상 · 어디를 볼까 · 흔한 원인。 - 在
/root/cka/report.md中写入oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods=四行,并说明首先查看什么。
参考
- 事件位于
kubectl -n broken describe pod <이름>底部的Events:中,也可以通过kubectl get events --sort-by=.lastTimestamp按时间查看全部事件。 - 已退出容器的日志使用
kubectl logs <파드> --previous。如果不知道这一点,就无法诊断 CrashLoopBackOff,因为当前容器还来不及留下日志。 - 退出原因和状态码位于
kubectl get pod <이름> -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'。 - 要有意消耗内存,可以使用
dd if=/dev/zero of=/dev/shm/x bs=1M count=<큰 수>。 - 常见错误 1:第 3 步只设置
requests,却不设置limits。OOM 会在超出limits时发生。 - 常见错误 2:第 4 步将两个 probe 配置在同一个 Pod 中。这样就无法判断是哪个 probe 导致重启。
无法拉取镜像时
ts-image——使用不存在的镜像制造 ImagePullBackOff,从事件中读取实际原因并保存到 /root/cka/imagepull.txt。然后将修复后的版本启动为 ts-image-fixed。
指定一个不存在的标签即可。不要只看状态,还要从 describe 的 Events 中读取实际原因。
读取已经退出的容器日志
ts-crash——使用立即退出的命令制造 CrashLoopBackOff,读取已经退出的容器日志并保存到 /root/cka/crashloop.txt。同时记录重启次数。
kubectl logs <파드> 查看的是当前容器。要查看刚刚退出的容器,需要使用 --previous。
内存超限时以 137 退出
ts-oom——让容器使用超过内存 limits 的内存以制造 OOMKilled,并将结果连同退出码保存到 /root/cka/oom.txt。
将 limits.memory 设得较小,再让容器使用更多内存。同时写明退出码代表什么。
两种 probe 的结果不同
ts-liveness 和 ts-readiness——分别只配置一个会失败的 probe,将结果有何不同保存到 /root/cka/probe.txt。
每个 Pod 只配置一个 probe。若同时配置两个,就无法判断是哪一个导致重启。
Pending 是调度器问题
ts-pending——创建无法调度的 Pod,并将调度器留下的原因保存到 /root/cka/pending.txt。还要写出 Pending 与 ContainerCreating 的区别。
请求节点无法提供的资源即可。调度器会在事件中记录无法调度的原因。
相同原因,不同症状
ts-config(env 引用)和 ts-volume(卷引用)——二者都指向不存在的 ConfigMap,并将状态为何不同保存到 /root/cka/configref.txt。
分别创建一个通过 envFrom 引用不存在 ConfigMap 的 Pod,以及一个通过卷引用它的 Pod,再比较状态。
汇总成一张表
在 /root/cka/triage.md 中创建包含五种症状的分类表。每一行为 증상 · 어디를 볼까 · 흔한 원인。
每一行为 증상 · 어디를 볼까 · 흔한 원인。目标是在考试中能在 3 秒内想到下一步行动。
总结所学内容
在 /root/cka/report.md 中写入 oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods= 四行,并说明首先查看什么。
除 oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods= 四行外,还要写明调查顺序。