k8s的ipvs转发svc服务访问慢的问题(网络CNI VXLAN 模式延迟调优flannel calico 都存在)
现象:
svc 模式为 NodePort ,访问 pod 所在 node 的 nodeport 快,通过其他 node 转发的访问 慢。
排查方法:
跟 k8s svc 的 externalTrafficPolicy 属性无关;它如果是 local 直接就不能访问。
查看 ipvs 后端
$ ipvsadm -ln |& grep 9153
proxyMode 是 ipvs ,用 ipvsadm 看下超时的时候的状态,一直是SYN_RECV,也就是发送了 SYN ,没收到回包。
$ ipvsadm -lnc |& grep 9153 TCP 00:59 SYN_RECV 10.96.0.10:41282 10.96.0.10:9153 10.244.2.73:9153
抓包:因为 CNI 使用的 flannel ,用的 VXLAN 模式。master 上抓9153和flannel.1的 8472 端口,coredns 的 POD 所在 node 上抓 flannel 的 VXLAN 包,下面三个是对应的:
[root@master /root]# tcpdump -nn -i flannel.1 port 9153 [root@node2 /root]# tcpdump -nn -i eth0 port 8472
先看上面的第一部分,搜了下资料,得知 TCP 默认 SYN 报文最大 retry 5次,每次超时了翻倍,1s -> 3s -> 7s -> 15s -> 31s -> 63s。只有63秒的时候 node 的机器上才收到了 VXLAN 的报文。说明 POD 所在 node 压根没收到63秒之前的。
查看网卡状态
ethtool -k eth0 |grep rx ethtool -k flannel.1 |grep rx
原因:
flannel网络设置将发送端的checksum打开了,但是flannel想利用了Checksum offloading的机制,自己不计算checksum,想留给网卡硬件来计算,这样的目的是不消耗CPU,利用网卡硬件分担CPU消耗,这原本是没问题的,但是flannel下层还有个ens33,这个ens33才是真的NIC,但是对ens33来说,从flannel发过来的是属于报文,ens33是否会对上层协议报文进行校验,然后将值填写到udp层报文内容去呢?这个我感觉不会,如果会的话,还要再了解下flannel的虚拟网络及硬件网卡之间的offloadinig机制。
解决方法:
1. 最简单,关闭 CNI 的 VXLAN 网卡的 checksum offload 但是重启失效
搜了下wireshark linux udp checksum incorrect,都是推荐把 Checksum Offload disable 掉就行了,例如我这里是 flannel ,则是:
sudo ethtool -K flannel.1 tx-checksum-ip-generic off
2. 更改 kubeproxy 镜像
发现了 Dockerfile的改动 , 1.17.0里的 Dockerfile 的BASEIMAGE是用 指定了一个源安装了最新的iptables,然后利用update-alternatives把脚本/usr/sbin/iptables-wrapper去替代iptables 来检测应该使用nft还是legacy, hack 下镜像回自带源里的 iptables 验证下。
FROM registry.aliyuncs.com/google_containers/kube-proxy:v1.17.5 RUN rm -f /usr/sbin/iptables && clean-install iptables
构建的镜像推送到了 dockerhub 上zhangguanzhang/hack-kube-proxy:v1.17.5,更改下集群 kube-proxy ds 的镜像。
3. 升级到新内核
具体版本就不知道了,只要在这个 内核pr 合并后出的内核版本都行,有人说这些可以 Stable kernels 5.6.13, 5.4.41, 4.19.123, 4.14.181 and later have the checksum patch included.
4.创建一个 oneshot 服务
cat << EOF >>/etc/systemd/system/xiaodu-flannel-tx-off.service [Unit] Description=Turn off checksum offload on flannel.1 After=sys-devices-virtual-net-flannel.1.device [Install] WantedBy=sys-devices-virtual-net-flannel.1.device [Service] Type=oneshot ExecStart=/sbin/ethtool -K flannel.1 tx-checksum-ip-generic off EOF sudo systemctl enable xiaodu-flannel-tx-off sudo systemctl start xiaodu-flannel-tx-off
参考文档:
Kubernetes 1.17 CNI VXLAN 模式延迟调优
Kubernetes + Flannel: UDP packets dropped for wrong checksum – Workaround
共 0 条评论