在 CKA 考试中,排错通常分为两大类:节点级故障(Node NotReady)和工作负载级故障(Pod Crash/Pending)。
# 核心排错心智模型:自上而下的漏斗排查法
遇到任何故障,考场上千万不要像没头苍蝇一样乱敲,牢记这个四步排查漏斗:
- 看宏观状态:
kubectl get nodes/kubectl get pods -o wide(谁出事了?在哪出事的?) - 看资源事件:
kubectl describe <resource> <name>(翻到底部的 Events,K8s 会直接告诉你哪里卡住了) - 看容器日志:
kubectl logs <pod-name>(如果是应用内部报错,必须看日志) - 看底层进程: 如果是节点挂了,必须 SSH 登录到那台机器上,用
systemctl status kubelet和journalctl -u kubelet查系统日志。
# 实战挑战一:节点级故障(拯救 NotReady 的 Node1)
这个场景在 CKA 中几乎是必考题:某台 Worker 节点突然失联,要求你找出原因并恢复。
# 第一步:制造“凶案现场”
请新开一个终端,SSH 登录到你的 node1 服务器上,执行以下破坏命令:
## 停止 node1 上的核心组件 kubelet
sudo systemctl stop kubelet
# 第二步:发现问题(回到 Master 节点)
在你的 master 节点上,假装你是刚接手考题的考生,检查集群状态:
kubectl get nodes
预期现象: 你会看到
node1的 STATUS 变成了NotReady。
# 第三步:按图索骥进行抢救
-
查看节点事件(确认不是网络插件引起的):
kubectl describe node node1翻到最下面的 Events,你会看到类似
Kubelet stopped posting node status的警告。这明确指向了 kubelet 进程问题。 -
顺藤摸瓜(回到 Node1 终端): 在考场上,遇到节点问题,你必须通过
ssh <节点名>登录到故障机。现在在你的node1终端上排查服务状态:sudo systemctl status kubelet你会看到状态是
inactive (dead)。 -
执行修复:
sudo systemctl start kubelet sudo systemctl enable kubelet -
验证恢复(回到 Master 节点):
kubectl get nodes等待十几秒后,
node1重新变为Ready,满分到手!
# 实战挑战二:工作负载级故障(经典的 CrashLoopBackOff)
这是 K8s 日常运维中最让人头疼的状态,Pod 不断重启然后死掉。
# 第一步:制造“凶案现场”
在 Master 节点上执行以下命令,部署一个带有致命拼写错误的 Pod:
cat <<EOF kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: crash-pod
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo "Hello CKA" && seleep 3600'] # 注意这里的 seleep 是故意写错的
EOF
# 第二步:发现问题
kubectl get pods -w
预期现象: 你会观察到
crash-pod的状态在ContainerCreating->Error->CrashLoopBackOff之间疯狂横跳。
# 第三步:标准的排错黄金两连击
-
第一击:看事件 (Events)
kubectl describe pod crash-pod看最底部,它可能会说 Started container,但随后又 Created。光看事件看不出具体的业务错误,这时候必须用第二击。
-
第二击:看日志 (Logs) 这就是找出应用级崩溃原因的终极武器:
kubectl logs crash-pod预期输出: 屏幕上会无情地打印出
sh: seleep: not found。真相大白!
# 第四步:执行修复
既然知道是命令写错了,我们需要修复它。因为 Pod 的 command 字段大多是不可变的(Immutable),最快的方法是导出原 YAML,修改后重建:
## 1. 把现有的 Pod 配置导出到文件
kubectl get pod crash-pod -o yaml > fix.yaml
## 2. 删除坏掉的 Pod
kubectl delete pod crash-pod
## 3. 用 vi 编辑器打开 fix.yaml
vi fix.yaml
## 找到 seleep,改成 sleep,然后一定要把文件中包含 resourceVersion, uid 那些系统自动生成的行删掉(或者干脆只保留核心字段)
## 更好的 CKA 考场应对方式:既然只是单 Pod,直接一句话重建最快:
kubectl run crash-pod --image=busybox --restart=Never --command -- sh -c 'echo "Hello CKA" && sleep 3600'
# 🛠️ 清理战场
kubectl delete pod crash-pod