Skip to content

第16章 故障排查实战

本章汇总 Kubernetes Service 相关的常用排查命令、典型故障案例和排查清单。


16.1 常用排查命令

查看 Service

bash
kubectl get svc -o wide
kubectl describe svc <svc-name>

查看 Endpoints/EndpointSlice

bash
kubectl get endpoints <svc-name>
kubectl get endpointslices -l kubernetes.io/service-name=<svc-name>

查看 Pod 标签

bash
kubectl get pods -l app=web --show-labels

从 Pod 内访问 Service

bash
kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- sh
wget -O- http://<svc-name>:<port>

DNS 排查

bash
kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup <svc-name>

kube-proxy 排查

bash
kubectl logs -n kube-system -l k8s-app=kube-proxy

节点规则排查

bash
# iptables
iptables -t nat -L KUBE-SERVICES -n -v | grep <svc-name>
iptables -t nat -L KUBE-NODEPORTS -n -v

# ipvs
ipvsadm -Ln
ipvsadm -Lnc

抓包

bash
# 抓 ClusterIP
tcpdump -i any -nn host 10.96.123.45

# 抓 NodePort
tcpdump -i any -nn port 30080

# 抓后端 Pod
tcpdump -i any -nn host 10.244.1.10 and port 8080

16.2 故障排查清单

遇到 Service 访问不通时,按以下顺序排查:

text
1. Pod 是否正常运行?
   └─ kubectl get pods -l app=xxx

2. Pod 标签是否匹配 Service selector?
   └─ kubectl get svc <svc-name> -o yaml | grep selector
   └─ kubectl get pods --show-labels

3. Endpoints 是否包含 Pod IP?
   └─ kubectl get endpoints <svc-name>

4. readinessProbe 是否通过?
   └─ kubectl describe pod <pod-name>

5. 从 Pod 内直接访问目标 Pod IP:targetPort 是否通?
   └─ telnet <pod-ip>:<target-port>

6. 从 Pod 内访问 Service ClusterIP:port 是否通?
   └─ wget -O- http://<cluster-ip>:<port>

7. DNS 解析是否正常?
   └─ nslookup <svc-name>

8. kube-proxy 是否正常运行?
   └─ kubectl logs -n kube-system -l k8s-app=kube-proxy

9. 节点上 iptables/ipvs 规则是否正确?
   └─ iptables -t nat -L KUBE-SERVICES -n -v
   └─ ipvsadm -Ln

10. 是否有 NetworkPolicy 阻止流量?
    └─ kubectl get networkpolicies

16.3 典型故障案例

案例1:Service 能解析,但访问无响应

现象nslookup 正常,但 curl 无响应。

排查

  1. kubectl get endpoints <svc-name> 查看是否有后端。
  2. 如果有后端,直接 telnet <pod-ip>:<target-port> 测试容器端口是否通。
  3. 常见原因:targetPort 配置错误。

案例2:Endpoints 为空

现象:Service 没有后端。

排查

  1. 检查 selector 是否匹配 Pod 标签。
  2. 检查 Pod 是否 Running 且 readinessProbe 通过。
  3. 检查 Pod 是否处于 Terminating 状态。

案例3:Pod 看到的源 IP 是节点 IP

现象:需要真实客户端 IP,但日志里都是节点 IP。

解决:将 Service 的 externalTrafficPolicy 改为 Local,并确保 LB 健康检查正确。

案例4:Local 模式下部分请求失败

现象:部分节点有 Pod,部分节点没有,LB 仍把流量发到空节点。

解决

  1. 配置 LB 健康检查,探测 NodePort。
  2. 使用 Topology Spread Constraints 保证 Pod 均匀分布。

案例5:滚动更新时偶发 502

现象:应用升级时偶尔出现 502。

原因:长连接仍指向旧 Pod,旧 Pod 被删除后连接中断。

解决

  1. 配置优雅的 terminationGracePeriodSeconds。
  2. 应用正确处理 SIGTERM,等待连接排空。
  3. 使用 readinessProbe 和 preStop hook。

16.4 本章小结

  • 排查 Service 问题要从 Pod、Label、Endpoints、DNS、kube-proxy、网络策略逐层检查。
  • 常见原因包括 selector 不匹配、targetPort 错误、readinessProbe 失败、NetworkPolicy 拦截。
  • 保留源 IP 和滚动更新问题需要结合业务逻辑和流量策略综合解决。

本章练习

  1. 故意制造一个 selector 不匹配的 Service,按排查清单定位问题。
  2. 故意配置错误的 targetPort,观察现象并修复。
  3. 为你的团队写一份 Service 故障排查 SOP。