Kubernetes NodePort Service随机网络异常及HAProxy适配问题咨询
问题解答
1. 未运行应用Pod的主节点无法正常承担负载转发功能的原因
NodePort服务默认externalTrafficPolicy为Cluster模式,所有节点都会监听指定的NodePort端口,当请求打到没有对应Pod的节点时,kube-proxy会通过iptables/ipvs规则把请求转发到其他有Pod的节点。此时转发失败的常见原因:
- 节点内核参数
rp_filter(反向路径过滤)设置为严格模式(值为1):当节点收到请求后要转发到其他节点,响应包的源IP会变成远端Pod/节点IP,反向路径校验认为该路径非法,直接丢弃包。 - 集群CNI插件跨节点网络不通:比如Flannel的VXLAN端口被封禁、Calico的BGP对等关系异常,导致节点之间无法转发集群内流量。
- iptables FORWARD链默认策略为DROP:即使关闭firewalld,部分系统(安装过Docker的环境更常见)默认FORWARD链是DROP,跨节点转发的流量会被直接丢弃。
2. HAProxy无法识别NodePort为可用后端的原因
HAProxy默认的健康检查是短连接探测,会随机触发跨节点转发失败的场景:如果健康检查请求正好被转发到其他节点且链路不通,HAProxy就会判定后端不可用。你手动curl的时候是偶发成功,刚好碰到了请求转发到本地Pod的情况就会返回正常,但HAProxy的连续健康检查只要有几次失败就会标记后端离线。
3. 随机访问异常的根因和解决方法
根因
默认Cluster模式下,NodePort请求有1/3概率打到主节点(无Pod),2/3概率打到工作节点,打到工作节点的请求又有50%概率被转发到另一个工作节点的Pod。只要跨节点流量转发链路不通,就会出现随机的三种结果:
- 请求转发到本地Pod:正常返回
- 请求转发到其他节点,包被静默丢弃:请求挂起超时
- 请求转发到其他节点,被反向路径过滤拦截:节点返回ICMP网络不可达报错
解决步骤
- 先修复跨节点转发基础配置,所有节点执行以下命令:
# 修改rp_filter为宽松模式,允许非对称路径的流量 sysctl -w net.ipv4.conf.all.rp_filter=2 sysctl -w net.ipv4.conf.default.rp_filter=2 # 确保FORWARD链默认允许转发 iptables -P FORWARD ACCEPT # 永久保存配置 echo "net.ipv4.conf.all.rp_filter=2" >> /etc/sysctl.conf echo "net.ipv4.conf.default.rp_filter=2" >> /etc/sysctl.conf sysctl -p
- 验证跨节点Pod通信正常:
# 拿到两个Nginx Pod的IP地址 kubectl get pods -o wide # 在任意节点上分别curl两个Pod的80端口,都应该正常返回Nginx欢迎页 curl <第一个Pod的IP>:80 curl <第二个Pod的IP>:80
- 如果你使用kube-proxy的ipvs模式,额外执行以下配置:
sysctl -w net.ipv4.vs.conntrack=1 echo "net.ipv4.vs.conntrack=1" >> /etc/sysctl.conf sysctl -p
修复完成后不需要将externalTrafficPolicy设置为Local,即可同时保留负载均衡能力和正常的NodePort访问能力。
内容的提问来源于stack exchange,提问作者Adam Winter
相关产品推荐
相关产品推荐

