Featured image of post overlay网络跨节点tcp通信问题

overlay网络跨节点tcp通信问题

vxlan

表象就是程序icmp协议通信正常,但是tcp测试端口无法正常响应。

1
2
$ ping <container_hostname>
# 正常响应
1
2
$ nc -vz <container_hostname> <target_port>
# 无返回,提示超时

这种问题只能通过抓包来看了,抓了对应的tcp端口,没看到啥有用的信息,可以说完全没动静,overlay网络内部使用 vxlan 技术实现网络内部互通,通过 udp 4789 端口进行流量转发的,我们可以抓这个端口看看这个问题:

1
$ tcpdump -i eth0 udp port 4789 -vv -X
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
dropped privs to tcpdump
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:40:30.099488 IP (tos 0x0, ttl 64, id 27463, offset 0, flags [none], proto UDP (17), length 110)
    my.host.test1.60770 > 192.168.1.1.vxlan: [bad udp cksum 0x9c61 -> 0xccff!] VXLAN, flags [I] (0x08), vni 4097
IP (tos 0x0, ttl 64, id 23147, offset 0, flags [DF], proto TCP (6), length 60)
    10.0.1.176.37729 > 10.0.1.192.http: Flags [S], cksum 0x179e (incorrect -> 0x483c), seq 2649600431, win 28200, options [mss 1410,sackOK,TS val 3070156816 ecr 0,nop,wscale 7], length 0
        0x0000:  4500 006e 6b47 0000 4011 c1dd c0a8 6604  E..nkG..@.....f.
        0x0010:  c0a8 6605 ed62 12b5 005a 9c61 0800 0000  ..f..b...Z.a....
        0x0020:  0010 0100 0242 0a00 01c0 0242 0a00 01b0  .....B.....B....
        0x0030:  0800 4500 003c 5a6b 4000 4006 c8e1 0a00  ..E..<Zk@.@.....
        0x0040:  01b0 0a00 01c0 9361 0050 9ded b1af 0000  .......a.P......
        0x0050:  0000 a002 6e28 179e 0000 0204 0582 0402  ....n(..........
        0x0060:  080a b6fe e010 0000 0000 0103 0307       ..............
19:40:31.121657 IP (tos 0x0, ttl 64, id 28076, offset 0, flags [none], proto UDP (17), length 110)
    my.host.test1.48450 > 192.168.1.1.vxlan: [bad udp cksum 0xcc81 -> 0xf920!] VXLAN, flags [I] (0x08), vni 4097
IP (tos 0x0, ttl 64, id 23148, offset 0, flags [DF], proto TCP (6), length 60)
    10.0.1.176.37729 > 10.0.1.192.http: Flags [S], cksum 0x179e (incorrect -> 0x443d), seq 2649600431, win 28200, options [mss 1410,sackOK,TS val 3070157839 ecr 0,nop,wscale 7], length 0
        0x0000:  4500 006e 6dac 0000 4011 bf78 c0a8 6604  E..nm...@..x..f.
        0x0010:  c0a8 6605 bd42 12b5 005a cc81 0800 0000  ..f..B...Z......
        0x0020:  0010 0100 0242 0a00 01c0 0242 0a00 01b0  .....B.....B....
        0x0030:  0800 4500 003c 5a6c 4000 4006 c8e0 0a00  ..E..<Zl@.@.....
        0x0040:  01b0 0a00 01c0 9361 0050 9ded b1af 0000  .......a.P......
        0x0050:  0000 a002 6e28 179e 0000 0204 0582 0402  ....n(..........
        0x0060:  080a b6fe e40f 0000 0000 0103 0307       ..............

通过抓包看到报错192.168.1.1.vxlan: [bad udp cksum 0x9c61 -> 0xcc,这个报错表明UDP数据包的checksum不匹配:

查看是否开启了网卡checksum ( on 就是开启了 ):

1
2
3
4
5
6
7
8
$ ethtool -k <interface> | grep checksum
rx-checksumming: on
tx-checksumming: on
        tx-checksum-ipv4: off [fixed]
        tx-checksum-ip-generic: on
        tx-checksum-ipv6: off [fixed]
        tx-checksum-fcoe-crc: off [fixed]
        tx-checksum-sctp: off [fixed]

小成本的解决方案,可以直接关闭源端校验:

1
$ ethtool --offload <interface> tx off

关闭 tx-checksumming 选项会导致此错误直接消失,因为它会禁用发送数据包的校验和计算,当然什么都是两面的,关闭此选项也可能会降低数据可靠性,并增加数据包损坏的风险。

核心问题可能是linux内核的bug 或者 网络设备转发时产生的问题,但是这个在我这一层可能已经无法解决了。(或许可以升级内核试试?)