K8S 集群不要开启net.ipv4.tcp_tw_recycl
问题描述
网络流量图.png- client1 和 client2同时通过NodePort方式访问FrontEnd Pod1
- FrontEnd Pod1 通过Service访问 BackEnd Pod3
- SNAT后 Pod3看到的两个client的访问都是FrontEnd Pod1的IP
- client上面两个timestamps 不是循序递增的, 导致小的SYN包会被drop
- 是Drop不是RST
导致client_2请求超时
对比两台机器上 netstat -s 的结果,发现 passive connections rejected because of time stamp 的统计在好的机器上是没有的
机器配置
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_recycle = 1
解决办法
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_recycle = 0
在 kernel 的4.12后net.ipv4.tcp_tw_recycle
参数被移除
tcp_timestamps
tcp_timestamps (Boolean; default: enabled; since Linux 2.2)
Enable RFC 1323 TCP timestamps.
tcp_timestamp 是 RFC1323 定义的优化选项,主要用于 TCP 连接中 RTT(Round Trip Time) 的计算,开启 tcp_timestamp
- 有利于系统计算更加准确的 RTT,
- 也就有利于 TCP 性能的提升。(默认开启)
tcp_timestamps详情请见:rfc7323.pdf
tcp_tw_recycle
tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
Enable fast recycling of TIME_WAIT sockets. Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation).
开启tcp_tw_recycle会启用tcp time_wait的快速回收
RFC1323中有如下一段描述:
An additional mechanism could be added to the TCP, a per-host cache of the last timestamp received from any connection. This value could then be used in the PAWS mechanism to reject old duplicate segments from earlier incarnations of the connection, if the timestamp clock can be guaranteed to have ticked at least once since the old connection was open. This would require that the TIME-WAIT delay plus the RTT together must be at least one tick of the sender’s timestamp clock. Such an extension is not part of the proposal of this RFC.
PAWS
PAWS全名Protect Againest Wrapped Sequence numbers,目的是解决在高带宽下,TCP序列号在一次会话中可能被重复使用而带来的问题
如下图:
img_58631de1f1e16.png
-
客户端发送的序列号为A的数据包A1因某些原因在网络中“迷路”
-
在一定时间没有到达服务端
-
客户端超时重传序列号为A的数据包A2
-
接下来假设带宽足够,传输用尽序列号空间,重新使用A,此时服务端等待的是序列号为A的数据包A3,而恰巧此时前面“迷路”的A1到达服务端,如果服务端仅靠序列号A就判断数据包合法,就会将错误的数据传递到用户态程序,造成程序异常。
-
Enable fast recycling of TIME-WAIT sockets
what is time wait, 2MSL(Maximum Segment Lifetime)
Maximum Segment Lifetime: 最长报文
Screen Shot 2019-10-13 at 12.17.36 AM.png
开启tcp_tw_recycle的时候,
- kernel会记录每一个peer的最后一个报文的时间戳,
- 如果记录的时间戳仍然有效距离当前时间小于TCP_PAWS_MSL
- 并且新收到的syn报文的时间戳比kernel记录的该peer的时间戳还要小,即时光倒流了
- 那么认为新收到的报文是有问题的, 从而drop掉
- 看到的现象就是,内核收到了新的syn报文,但只是默默drop了(没什么好处理方法,回RST可能误伤),所以造成了psql连接超时。
参考文献
https://www.m690.com/
https://ieevee.com/tech/2017/07/19/tcp-tw-recycle.html
http://blog.itpub.net/31559359/viewspace-2284113/
http://perthcharles.github.io/2015/08/27/timestamp-NAT/