K8s 的 Service 为了拿真实客户端 IP 把 externalTrafficPolicy 改成 Local,改完之后通过负载均衡访问,有三成请求直接超时,节点的 kube-proxy 没有对应规则。

一开始怀疑是「Pod 分布不均,两个节点上没有副本」,查了一圈,方向不对。

排查方向其实有限,先把可能性排一排。Local 策略下只有跑着 Pod 的节点才会响应,没有 Pod 的节点直接丢包。也可能是负载均衡的后端把全部节点都挂了进去,没做就绪判断。

另外,kube-proxy 的模式是 ipvs,Local 策略下的健康检查端口没放行。

上来先确认哪些节点上有 Pod

kubectl get pod -o wide -l app=web

然后看 Service 当前的策略和 endpoints

kubectl get svc web -o wide && kubectl get endpoints web

接着把无副本节点从负载均衡后端摘掉

kubectl get nodes -o wide && kubectl get pod -o wide -l app=web

剩下的就是确认三个节点都有副本后再挂回去

kubectl scale deploy/web --replicas=3 && kubectl get pod -o wide -l app=web

别只看报错消失,验证要多做一步。负载均衡只把有副本的节点作为后端,访问成功率回到 100%,业务日志里能看到真实客户端 IP。

Local 策略要和副本分布一起设计,节点数多于副本数时必然有节点不响应;也可以给 Service 加 internalTrafficPolicy 或改用保留客户端 IP 的负载均衡模式。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189