背景
近期因项目需要,在调研多主机上docker容器之间网络互通的方案,调试基于overlay + consul的方案时,在两个主机上分别拉取容器、关闭防火墙后,容器间相互可ping通,但基于wget测试对端80端口时,一直无响应。
原因
在两台主机上分别对4789 udp端口进行抓包,可以发现,当从node节点的容器ping master节点上的容器时,node节点和master节点上都能抓到vxlan的包。但当从node节点的容器向master节点上的容器时,在node节点上能抓到syn包,但master节点上一直无响应。
直观看现象,由于node和master在同一网段,可以确定是数据包没有最终从node节点的网卡发出去,但防火墙本身已经被关闭,又会有什么因素导致数据包不能被发出去呢?
执行journalctl -xe -u docker,查看docker服务的日志,并未发现什么异常,初步断定,此异常和docker服务无关。目前的情况已经有点超过过往的认知了,此前从未想过会有什么情况能导致数据包发不出。
在一遍遍的核对各种overlay网络搭建的帖子后,确定搭建的过程本身是没有问题的。经过多次百度搜索,也未找到类型的问题描述。
后来在谷歌上用docker overlay tcp关键词搜索,最终命中到一篇帖子,提到是因为网卡的checksum offloading机制导致的(原始文章参见:docker overlay tcp不通问题)。
解决方案
按照帖子的描述,分别在node和master上分别执行如下命令,再次测试wget,通了!
ethtool -K ens192 tx off
后记
这个问题,在百度上很少看到有反馈,目前暂不清楚是否跟系统所在的环境有关(本人所用两台虚拟机均为ESXI上创建的虚拟机),后来搜索checksum offload关键词,看到一篇类似的问题描述,但docker环境有差异,其中提到跟内核版本和k8s有关(具体见:农行信创之容器云适配经验分享:问题、挑战与解决之道 | 运维进阶_mob604756f33d49的技术博客_51CTO博客),至于跟内核版本是否有关,这个是存疑的,本人测试环境内核版本已经升级到6.0以上了。