我们有两个版本的内核节点,分别是两个批次的节点,安装了3.10.95和5.4.x的内核
在出现Readiness probe failed和Liveness probe failed是一次pod驱逐而后就发生的
查看事件
# kubectl get events --sort-by='.lastTimestamp' -n kube-system
LAST SEEN TYPE REASON OBJECT MESSAGE
50m Warning Unhealthy pod/calico-node-dbjr4 Readiness probe failed:
48m Warning Unhealthy pod/calico-node-8t7rc Liveness probe failed:
43m Warning Unhealthy pod/calico-node-msj2z Liveness probe failed:
34m Warning Unhealthy pod/calico-node-9gxqf Liveness probe failed:
34m Warning Unhealthy pod/calico-node-cj8qk Readiness probe failed:
32m Warning Unhealthy pod/calico-node-tph5b Liveness probe failed:
回到Kuboard面板查看事件
有一种可能tcp_tw_recycle
,tcp_tw_recycle
在低版本的内核里面是可以被启用的,于是我们查看,发现过是打开状态
关闭tcp_tw_recycle
在 kernel 的4.12之后的版本中tcp_tw_recycle已经被移除了
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
于是我们关闭
sysctl -w net.ipv4.tcp_tw_recycle=0
当打开tcp_tw_recycle的时候很有可能会发生calico的状态存在断续的或者一直起不来的情况,原因就是这种连接资源快速回收和重用的机制会在k8s中出现问题,特别是在有会话session的时候
tcp_tw_recyle=1
无法接收 NATed 数据包的服务器。
默认情况下,当tcp_tw_reuse
和tcp_tw_recycle
都被禁用时,内核将确保处于TIME_WAIT
状态的套接字将保持在该状态足够长的时间——足够长的时间以确保属于未来连接的数据包不会被误认为是旧连接的延迟数据包。
当您启用时tcp_tw_reuse
,处于TIME_WAIT
状态的套接字可以在它们到期之前使用,并且内核将尝试确保没有关于 TCP 序列号的冲突。如果您启用tcp_timestamps
(又名 PAWS,用于防止包装序列号),它将确保不会发生这些冲突。然而,你需要TCP时间戳上启用两个端(至少,这是我的理解)。有关详细信息,请参阅tcp_twsk_unique的定义。
当您启用 时tcp_tw_recycle
,内核会变得更加激进,并且会对远程主机使用的时间戳做出假设。它将跟踪每个具有连接TIME_WAIT
状态的远程主机使用的最后一个时间戳),如果时间戳正确增加,则允许重新使用套接字。但是,如果主机使用的时间戳发生变化(即及时回溯),SYN
数据包将被悄悄丢弃,并且连接将无法建立(您将看到类似于“连接超时”的错误)。如果您想深入了解内核代码,tcp_timewait_state_process的定义可能是一个很好的起点。
现在,时间戳永远不应该回到过去;除非:
- 主机重新启动(但是,当它恢复时,
TIME_WAIT
套接字可能已经过期,所以这将不是问题); - IP 地址很快被其他东西重用(
TIME_WAIT
连接会保留一点,但其他连接可能会被攻击TCP RST
,这会释放一些空间); - 网络地址转换(或 smarty-pants 防火墙)涉及连接中间。
在后一种情况下,您可以在同一个 IP 地址后面有多个主机,因此,不同的时间戳序列(或者,所述时间戳在每个连接上由防火墙随机化)。在这种情况下,一些主机将随机无法连接,因为它们被映射到TIME_WAIT
服务器存储桶具有更新时间戳的端口。这就是为什么文档会告诉您“NAT 设备或负载平衡器可能会因为设置而开始丢帧”的原因。
有些人建议不要管tcp_tw_recycle
,但启用tcp_tw_reuse
并降低tcp_fin_timeout
. 我同意 :-)
阅读-> 这篇文章有助于理解
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
net.ipv4.tcp_tw_reuse = 0
net.core.somaxconn = 32768
net.netfilter.nf_conntrack_max=1000000
vm.swappiness = 0
vm.max_map_count=655360
fs.file-max=6553600
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 10
问题仍然没有解决,此时我们并没有发现有用的日志信息,查看kublet日志如下,仍然提示探针失败
如下
12月 29 10:52:10 master1 kubelet[1458]: E1229 10:52:10.468294 1458 remote_runtime.go:392] ExecSync 312728508abf1a1bfea28a70a174e8a97e57685fc8bae741fa1702fb341e4b06 '/bin/calico-node -felix-ready -bird-ready' from runtime service failed: rpc error: code = DeadlineExceeded desc = context deadline exceeded
12月 29 10:52:10 master1 kubelet[1458]: I1229 10:52:10.468344 1458 prober.go:117] Readiness probe for "calico-node-dbjr4_kube-system(8d8d3b92-b7d3-424d-a6af-48b8559cbe15):calico-node" failed (failure):
12月 29 10:52:10 master1 kubelet[1458]: E1229 10:52:10.543839 1458 remote_runtime.go:392] ExecSync 4805cd505d5b6494d26130cc0bf83a458c1b099c1eefebac8dff942ffe04b980 '/usr/bin/check-status -r' from runtime service failed: rpc error: code = DeadlineExceeded desc = context deadline exceeded
12月 29 10:52:10 master1 kubelet[1458]: I1229 10:52:10.543899 1458 prober.go:117] Readiness probe for "calico-kube-controllers-5b75d4f8db-pn5ll_kube-system(b4c2985a-6476-448c-9e44-c2a1e7a7db07):calico-kube-controllers" failed (failure):
查看系统,目前并没有其他特别的异常,并且业务正常,我们试图调整探针返回时间来测试
调整Liveness/Readiness
calico探针的命令如下
/bin/calico-node '-felix-live' - '-bird-live'
/bin/calico-node '-felix-ready' '-bird-ready'
我们在yaml文件中默认配置的是1秒,在1.20版本也是如此
livenessProbe:
exec:
command:
- /bin/calico-node
- '-felix-live'
- '-bird-live'
failureThreshold: 6
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: calico-node
readinessProbe:
exec:
command:
- /bin/calico-node
- '-felix-ready'
- '-bird-ready'
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
但是这在一个负载较高的环境中可能需要增加timeoutSeconds
关于探针阅读这篇linuxea:kubernetes 存活状态liveness probe(7)
failureThreshold:探测几次,默认3次探测失败,则失败
periodSeconds:间隔时间,10秒
timeoutSeconds:探测超时时间,1秒
initialDelayseconds : 初始化探测延迟时间(在容器启动的时候,
直接修改 timeoutSeconds: 5,而后观察一小时。问题解决
# kubectl get events --sort-by='.lastTimestamp' -n kube-system
No resources found in kube-system namespace.
参考
Dropping of connections with tcp_tw_recycle
Why does the TCP protocol have a TIME_WAIT state?
calico-node unexplained readiness/liveness probe fails
Calico pod Intermittently triggers probe failed events
linuxea:kubernetes 存活状态liveness probe(7)