跳到主要内容

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 nodegrep 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应用运行时错误查看日志修复代码
137OOM Killed(内存超限)增大 memory limits
143SIGTERM / 优雅退出失败检查 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 怎么排查?

答案

  1. kubectl describe pod 查看 Events
  2. 常见原因:
    • 资源不足:Node CPU/内存不够 → 扩容或降低 requests
    • NodeSelector/Affinity 不匹配 → 检查 Node 标签
    • 污点无容忍 → 添加 tolerations
    • PVC 未绑定 → 检查 StorageClass 和 PV
  3. kubectl describe node 查看各 Node 的 Allocatable 和 Allocated

Q2: CrashLoopBackOff 如何排查?

答案

  1. kubectl logs <pod> --previous:查看上一次崩溃日志
  2. kubectl describe pod:查看 Exit Code
    • 137 = OOM → 增大内存
    • 1 = 应用错误 → 修复代码
    • 127 = 命令不存在 → 检查 Dockerfile
  3. kubectl debug <pod> 进入调试容器排查

Q3: 如何排查 Service 访问不通?

答案

按链路排查:

  1. Endpoints 是否有值kubectl get endpoints <svc>
    • 为空 → selector 与 Pod label 不匹配
  2. Pod 是否 Ready:readinessProbe 未通过的 Pod 不会加入 Endpoints
  3. 端口映射:Service port vs targetPort vs containerPort
  4. NetworkPolicy:是否限制了入站流量
  5. DNS 解析:在容器内 nslookup <svc-name> 验证

相关链接