0%

K8S问题排查-UDP请求不通导致设备备份失败

问题背景

K8S双栈环境下,业务Pod纳管了IPv4和IPv6的设备(Pod需要与设备通过UDP协议通信),对IPv4设备配置做备份时可以成功,对IPv6设备配置做备份时失败。

分析过程

查看K8S集群主节点node3上的IP信息:

1
2
3
4
5
6
7
8
9
10
11
[root@node3 ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 0c:da:41:1d:d2:9d brd ff:ff:ff:ff:ff:ff
inet 192.168.65.13/16 brd 192.168.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.65.21/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 2000::65:21/128 scope global deprecated
valid_lft forever preferred_lft 0sec
inet6 2000::65:13/64 scope global
valid_lft forever preferred_lft forever

其中各IP角色如下:

1
2
3
4
192.168.65.13:IPv4节点IP
192.168.65.21:IPv4虚IP
2000::65:13:IPv6节点IP
2000::65:21:IPv6虚IP

查看主节点上接收UDP报文异常的业务Pod:

1
2
3
4
[root@node1 ~]# kubectl get pod -A -owide|grep tftpserver-dm
ss tftpserver-dm-798nv 1/1 Running 2 13d 177.177.166.147 node1 <none> <none>
ss tftpserver-dm-drrsn 1/1 Running 4 13d 177.177.104.10 node2 <none> <none>
ss tftpserver-dm-vmgtf 1/1 Running 6 13d 177.177.135.16 node3 <none> <none>

找到Pod的网卡:

1
2
[root@node3 ~]# ip route |grep 177.177.135.16
177.177.135.16 dev cali928cc4cd898 scope link

在业务提供的页面上触发备份IPv4设备配置的操作,抓包看到数据有请求和响应:

1
2
3
4
5
6
7
8
9
10
11
[root@node3 ~]# tcpdump -n -i cali928cc4cd898 -p udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on cali928cc4cd898, link-type EN10MB (Ethernet), capture size 262144 bytes
07:29:48.654684 IP 192.168.101.254.58625 > 177.177.135.16.tftp: 64 WRQ "running_3346183882.cfg" octet tsize 7304 blksize 512 timeout 5
07:29:48.686337 IP 177.177.135.16.39873 > 192.168.101.254.58625: UDP, length 35
07:29:48.707187 IP 192.168.101.254.58625 > 177.177.135.16.39873: UDP, length 516
07:29:48.707332 IP 177.177.135.16.39873 > 192.168.101.254.58625: UDP, length 4
07:29:48.708377 IP 192.168.101.254.58625 > 177.177.135.16.39873: UDP, length 516
07:29:48.708622 IP 177.177.135.16.39873 > 192.168.101.254.58625: UDP, length 4
07:29:48.710532 IP 192.168.101.254.58625 > 177.177.135.16.39873: UDP, length 516
...

在主机网卡上抓包,同样可以看到数据有请求和响应:

1
2
3
4
5
6
7
8
9
10
12:00:02.333324 IP 192.168.101.254.58631 > 192.168.65.21.tftp:  64 WRQ "running_3346346022.cfg" octet tsize 7304 blksize 512 timeout 5
12:00:02.349104 ARP, Request who-has 192.168.101.254 tell 192.168.65.13, length 28
12:00:02.350492 ARP, Reply 192.168.101.254 is-at 58:6a:b1:df:e3:d1, length 46
12:00:02.350499 IP 192.168.65.13.56284 > 192.168.101.254.58631: UDP, length 35
12:00:02.373403 IP 192.168.101.254.58631 > 192.168.65.13.56284: UDP, length 516
12:00:02.373603 IP 192.168.65.13.56284 > 192.168.101.254.58631: UDP, length 4
12:00:02.374613 IP 192.168.101.254.58631 > 192.168.65.13.56284: UDP, length 516
12:00:02.374724 IP 192.168.65.13.56284 > 192.168.101.254.58631: UDP, length 4
12:00:02.375775 IP 192.168.101.254.58631 > 192.168.65.13.56284: UDP, length 516
...

在业务提供的页面上触发备份IPv6设备配置的操作,抓包看到设备侧主动发送一个请求后,后续的数据传输请求就没有应答了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@node3 ~]# tcpdump -n -i cali928cc4cd898 -p udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on cali928cc4cd898, link-type EN10MB (Ethernet), capture size 262144 bytes
08:14:31.913637 IP6 2000::65:119.41217 > fd00:177:177:0:7bf3:bb28:910a:873c.tftp: 64 WRQ "running_3346210712.cfg" octet tsize 8757 blksize 512 timeout 5
08:14:31.925400 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.38680 > 2000::65:119.41217: UDP, length 35
08:14:34.928820 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.38680 > 2000::65:119.41217: UDP, length 35
08:14:37.931610 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.38680 > 2000::65:119.41217: UDP, length 35
08:14:40.933541 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.38680 > 2000::65:119.41217: UDP, length 35
08:19:25.395306 IP6 2000::65:119.41218 > fd00:177:177:0:7bf3:bb28:910a:873c.tftp: 64 WRQ "startup_3346213742.cfg" octet tsize 8757 blksize 512 timeout 5
08:19:25.410374 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.48233 > 2000::65:119.41218: UDP, length 35
08:19:28.413797 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.48233 > 2000::65:119.41218: UDP, length 35
08:19:31.415977 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.48233 > 2000::65:119.41218: UDP, length 35
08:19:34.418414 IP6 fd00:177:177:0:7bf3:bb28:910a:873c.48233 > 2000::65:119.41218: UDP, length 35
...

主机网卡上抓包,可以看到数据有请求和响应,说明设备的响应到了主机上,但没到Pod网卡上:

1
2
3
4
5
6
7
8
9
10
11
11:55:29.393598 IP6 2000::65:119.41226 > 2000::65:21.tftp:  64 WRQ "startup_3346343382.cfg" octet tsize 8757 blksize 512 timeout 5
11:55:29.401115 IP6 2000::65:13.32991 > 2000::65:119.41226: UDP, length 35
11:55:29.405709 IP6 2000::65:119.41226 > 2000::65:21.32991: UDP, length 516
11:55:29.405745 IP6 2000::65:21 > 2000::65:119: ICMP6, destination unreachable, unreachable port, 2000::65:21 udp port 32991, length 572
11:55:32.404514 IP6 2000::65:13.32991 > 2000::65:119.41226: UDP, length 35
11:55:32.406399 IP6 2000::65:119.41226 > 2000::65:21.32991: UDP, length 516
11:55:32.406432 IP6 2000::65:21 > 2000::65:119: ICMP6, destination unreachable, unreachable port, 2000::65:21 udp port 32991, length 572
11:55:35.407644 IP6 2000::65:13.32991 > 2000::65:119.41226: UDP, length 35
11:55:35.409423 IP6 2000::65:119.41226 > 2000::65:21.32991: UDP, length 516
11:55:35.409463 IP6 2000::65:21 > 2000::65:119: ICMP6, destination unreachable, unreachable port, 2000::65:21 udp port 32991, length 572
...

那IPv6设备的请求响应和IPV4设备场景下的有什么不同呢?对比IPv4和IPv6两个场景下的主机网卡抓包结果,可以看出:

1
2
3
4
IPv4设备请求时主机上抓包分析:
1. 第一次交互时,设备侧(192.168.101.254)先发送请求给VIP(192.168.65.21)
2. 第二次交互时,业务Pod请求以节点IP为源(192.168.65.13)发送给设备;
3. 第三次交互时,设备侧请求以节点IP为目标地址(192.168.65.13)发送给业务Pod
1
2
3
4
IPv6设备请求时主机上抓包分析:
1. 第一次交互时,设备侧(2000::65:119)先发送请求给VIP(2000::65:21)
2. 第二次交互时,业务Pod请求以节点IP为源(2000::65:13)发送给设备;
3. 第三次交互时,设备侧请求以VIP为目标地址(2000::65:21)发送给业务Pod

从上述报文交互过程可看出,IPv6设备在报文交互时源IP和目标地址不一致,经确认是设备侧强制配置了以VIP为目的地址发送报文的配置,而正常情况下,应该以请求报文的源IP作为响应报文的目的地址。

通过临时修改验证,把第三次交互的VIP目的地址改为节点IP,验证问题解决。

解决方案

业务层面修改发送报文的配置。