K8s 服务间歇性 503 与 conntrack 表溢出排查
2026-08-11 00:53:03
# Kubernetes
用户访问偶发 503,重启 Pod 能短暂恢复,但应用日志里完全查不到报错。这种”网关报 503、应用无日志”的组合,往往不是应用层问题,而是内核连接跟踪表(conntrack)溢出。本文给出完整的定位与解决路径。
问题现象与背景原因
典型现象:请求随机返回 503,且网关(Ingress Nginx / 业务网关)日志里有大量 502/503,但后端 Pod 的 access log 里查不到对应请求——说明请求在到达应用之前就被丢了。
1 | curl https://pay.example.com/callback |
核心原因:conntrack 表溢出。
- kube-proxy 在 iptables 模式 下,依赖 Linux 内核的连接跟踪表(nf_conntrack)做 NAT 转发。
- 高并发(尤其短连接、支付回调、健康检查探测这类每秒成千上万次新建连接)场景下,conntrack 表项来不及回收,表被填满。
- 表满后,新连接在内核 netfilter 层被直接 DROP,表现为随机 503 / 超时,而应用层和 kube-proxy 日志都看不出异常(连接在内核就被丢了)。
- 重启 Pod 会清空其相关 conntrack 表项,所以”重启能短暂恢复”,但流量一上来表又满了。
提示:503 但应用日志全干净、且重启能短暂恢复——这是 conntrack 溢出最典型的特征,优先往这个方向查。
排查过程(思路与定位方法)
第一步:登录任意工作节点,看 conntrack 当前用量与上限。
1 | # 当前已用 conntrack 表项 |
若 nf_conntrack_count 长期接近 nf_conntrack_max,基本可确定溢出。
第二步:看内核有没有丢包记录。
1 | # 查看 conntrack 因表满而丢包的次数 |
nstat 中 nf_conntrack 相关计数持续增长也佐证溢出。
第三步:确认 kube-proxy 当前模式(iptables 模式风险最高)。
1 | kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode |
第四步:确认是不是短连接洪峰导致。 看节点新建连接速率、Ingress 每秒请求数,与 503 出现时间是否吻合。
最终的解决方法
临时止血(立刻生效,重启节点后失效):
1 | # 调大 conntrack 表容量(按内存估算,一般设为 内存KB/16K 或更大,如 4 倍) |
长期根治(三选一或组合):
- 切换 kube-proxy 为 IPVS 模式:IPVS 基于哈希表,不依赖 per-connection conntrack,能扛更高并发,是社区推荐的高性能方案。
- 前置 Nginx / 网关做连接收敛:把海量短连接收拢为少量长连接打到后端,降低 conntrack 压力。
- 服务改长连接 / 连接池:客户端复用连接,减少新建连接数。
提示:IPVS 模式同样会在某些场景(如
masquerade)用到 conntrack,但整体并发能力远强于 iptables,是生产环境首选。
操作命令(可直接复制执行)
1 | # 1. 查 conntrack 用量与上限 |