K8s 故障排查
排查流程
常用排查命令
# ===== 查看状态 =====
kubectl get pods -o wide # Pod 状态 + Node
kubectl get pods --field-selector=status.phase!=Running # 非运行态
kubectl get events --sort-by=.lastTimestamp # 按时间排序的事件
kubectl describe pod <pod-name> # Pod 详细信息(重点看 Events)
# ===== 日志 =====
kubectl logs <pod-name> # 当前日志
kubectl logs <pod-name> --previous # 上一次崩溃的日志
kubectl logs <pod-name> -c <container> # 多容器指定
kubectl logs -l app=myapp --tail=100 # 按标签查看
# ===== 进入容器 =====
kubectl exec -it <pod-name> -- sh
kubectl exec -it <pod-name> -c <container> -- bash
# ===== 临时调试容器(K8s 1.25+)=====
kubectl debug <pod-name> -it --image=busybox -- sh
kubectl debug node/<node-name> -it --image=busybox
# ===== 资源使用 =====
kubectl top pods # Pod CPU/内存
kubectl top nodes # Node CPU/内存
kubectl describe node <node-name> # Node 资源分配
# ===== 网络调试 =====
kubectl run debug --rm -it --image=busybox -- sh
# 在临时 Pod 中:
nslookup myapp-svc # DNS 解析
wget -qO- http://myapp-svc:80/health # HTTP 测试
Pod 常见状态与排查
Pending
Pod 无法被调度到 Node。
kubectl describe pod <pod-name>
# 检查 Events 部分:
# FailedScheduling: 0/3 nodes are available: 3 Insufficient cpu
# FailedScheduling: 0/3 nodes are available: 1 node(s) had taint
| 原因 | 排查 | 解决 |
|---|---|---|
| 资源不足 | kubectl describe node,检查 Allocatable vs Allocated | 扩容 Node 或降低 requests |
| NodeSelector 无匹配 | kubectl get nodes --show-labels | 添加 label 或修改 selector |
| 污点不容忍 | `kubectl describe node | grep Taints` |
| PVC 未绑定 | kubectl get pvc | 创建 PV 或检查 StorageClass |
CrashLoopBackOff
容器反复崩溃重启。
# 查看崩溃日志
kubectl logs <pod-name> --previous
# 查看退出码
kubectl describe pod <pod-name>
# Last State: Terminated, Exit Code: 1 (应用错误)
# Last State: Terminated, Exit Code: 137 (OOM Killed)
# Last State: Terminated, Exit Code: 143 (SIGTERM)
| Exit Code | 原因 | 解决 |
|---|---|---|
| 1 | 应用运行时错误 | 查看日志修复代码 |
| 137 | OOM Killed(内存超限) | 增大 memory limits |
| 143 | SIGTERM / 优雅退出失败 | 检查 terminationGracePeriodSeconds |
| 126 | 权限不足 | 检查文件权限和 USER |
| 127 | 命令不存在 | 检查 CMD/ENTRYPOINT |
ImagePullBackOff
kubectl describe pod <pod-name>
# Events:
# Failed to pull image "myregistry.com/myapp:v1": unauthorized
| 原因 | 解决 |
|---|---|
| 镜像名拼写错误 | 检查 image 字段 |
| Tag 不存在 | 确认镜像已推送 |
| 私有仓库认证失败 | 创建 imagePullSecrets |
| 网络不通 | 检查 Node 到仓库的网络 |
# 创建私有仓库凭证
kubectl create secret docker-registry regcred \
--docker-server=myregistry.com \
--docker-username=user \
--docker-password=pass
Service 无法访问
# 1. 检查 Service 的 selector 是否匹配 Pod
kubectl get svc myapp-svc -o yaml
kubectl get pods -l app=myapp
# 2. 检查 Endpoints
kubectl get endpoints myapp-svc
# 如果 ENDPOINTS 为空,说明 selector 不匹配
# 3. 测试 Pod 到 Service
kubectl run debug --rm -it --image=busybox -- sh
wget -qO- http://myapp-svc:80
# 4. 检查 NetworkPolicy
kubectl get networkpolicy -A
常用排查脚本
k8s-debug.sh
#!/bin/bash
# K8s 快速排查脚本
NS=${1:-default}
echo "=== Namespace: $NS ==="
echo -e "\n--- 异常 Pod ---"
kubectl get pods -n "$NS" --field-selector=status.phase!=Running,status.phase!=Succeeded
echo -e "\n--- 最近事件 ---"
kubectl get events -n "$NS" --sort-by=.lastTimestamp | tail -20
echo -e "\n--- Node 资源 ---"
kubectl top nodes
echo -e "\n--- 空 Endpoints ---"
kubectl get endpoints -n "$NS" | awk 'NR==1 || $2==""'
常见面试问题
Q1: Pod 一直 Pending 怎么排查?
答案:
kubectl describe pod查看 Events- 常见原因:
- 资源不足:Node CPU/内存不够 → 扩容或降低 requests
- NodeSelector/Affinity 不匹配 → 检查 Node 标签
- 污点无容忍 → 添加 tolerations
- PVC 未绑定 → 检查 StorageClass 和 PV
kubectl describe node查看各 Node 的 Allocatable 和 Allocated
Q2: CrashLoopBackOff 如何排查?
答案:
kubectl logs <pod> --previous:查看上一次崩溃日志kubectl describe pod:查看 Exit Code- 137 = OOM → 增大内存
- 1 = 应用错误 → 修复代码
- 127 = 命令不存在 → 检查 Dockerfile
kubectl debug <pod>进入调试容器排查
Q3: 如何排查 Service 访问不通?
答案:
按链路排查:
- Endpoints 是否有值:
kubectl get endpoints <svc>- 为空 → selector 与 Pod label 不匹配
- Pod 是否 Ready:readinessProbe 未通过的 Pod 不会加入 Endpoints
- 端口映射:Service port vs targetPort vs containerPort
- NetworkPolicy:是否限制了入站流量
- DNS 解析:在容器内
nslookup <svc-name>验证