问题背景
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,验证问题解决。
解决方案
业务层面修改发送报文的配置。