- content
以每周一个节点,记录知识点。
2025-04-28~30
K8S 中的 NodePort 服务在 NAT 环境下的访问问题
在 Kubernetes 集群中使用 NodePort 类型的服务时,可能会遇到这样的情况:同一时间,部分客户端可以正常访问服务,而另一部分客户端却无法访问。特别是当客户端位于 NAT 网络环境中时,这个问题更为明显。
问题原因:
这个问题主要与 Linux 内核的两个参数设置有关:
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 1
当这两个参数同时被启用时,会对 NAT 网络环境产生不良影响。
技术原理:
在 K8S 工作节点上,可以通过 sysctl 命令查看这两个参数的设置:
$ sysctl net.ipv4.tcp_tw_recycle
net.ipv4.tcp_tw_recycle = 1
$ sysctl net.ipv4.tcp_timestamps
net.ipv4.tcp_timestamps = 1
当这两个参数都启用时会发生什么:
tcp_timestamps
参数启用后,TCP 连接会记录数据包的时间戳信息tcp_tw_recycle
参数启用后,服务器会使用时间戳机制来快速回收处于 TIME_WAIT 状态的连接- 在 NAT 环境中,多个客户端会共享同一个外部 IP 地址
- 服务器会按照每个源 IP 地址(Per-Host)记录并更新最近接收到的时间戳
- 由于 NAT 后面的不同客户端系统启动时间不同,它们的时间戳也会不同
- 服务器会将时间戳记录更新为最大值,导致时间戳较小的客户端发送的数据包被视为”过期重复数据”而被丢弃
解决方法:
最简单的解决方法是在 Kubernetes 工作节点上禁用tcp_tw_recycle
参数:
sysctl -w net.ipv4.tcp_tw_recycle=0
并将此设置永久保存到/etc/sysctl.conf
文件中:
net.ipv4.tcp_tw_recycle = 0
注意事项:
在现代 Linux 内核中(特别是 4.12 版本之后),tcp_tw_recycle
参数已被移除,因为它会导致此类 NAT 环境下的连接问题。如果您正在使用较新的内核版本,可能不会遇到此问题。
参考:
- https://www.sdnlab.com/17530.html