定位 kube-virt 虚拟机 dhcp 无法获取的问题

298 阅读2分钟

由于我这边用的是 containerd,而且 kubevirt pod 中一般没有抓包命令,所以需要找到虚拟机 pod 所在的 ns,基于 宿主机上的抓包工具进行抓包,确认 dhcp 的服务是没有问题的。

kubectl get 的 pod 名,和 crictl pods 查到的 pod 名是一致的,基于 crictl 的 pod 名,查找到 pod 所在的 网络 ns 比较简单直接,然后 基于 ip netns exec bash 进入,执行 tcpdump 进行抓包

    
crictl pods 


NETNS=$(sudo crictl inspectp b4d57432254b9 | jq -r '.info.runtimeSpec.linux.namespaces[] |select(.type=="network") | .path')
    
# echo $NETNS
/var/run/netns/cni-737d885b-3a13-ff0c-1f28-da3f90238437
# ip netns exec cni-737d885b-3a13-ff0c-1f28-da3f90238437 bash


sudo tcpdump -i any port 67 or port 68 -e -n -vv    
    

最后是定位到 dhcp 对应的端口没有起来

正常的情况下 kubectl exec 虚拟机 virt-launcher pod 中,可以看到 端口是 up 的

   
# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0 1234272 17716 ?       Ssl  05:56   0:00 /usr/bin/virt-launcher-monitor --qemu-timeout 338s --name hcctest22 --uid 6bc17558-2c43-451c
root         11  0.0  0.0 4243140 77272 ?       Sl   05:56   0:06 /usr/bin/virt-launcher --qemu-timeout 338s --name hcctest22 --uid 6bc17558-2c43-451c-9e5d-90
root         26  0.0  0.0  30956 15296 ?        S    05:56   0:00 /usr/sbin/virtlogd -f /etc/libvirt/virtlogd.conf
root         27  0.1  0.0 1611540 51576 ?       Sl   05:56   0:13 /usr/sbin/libvirtd -f /var/run/libvirt/libvirtd.conf
qemu         99  2.6  0.1 1793364 592840 ?      Sl   05:56   3:17 /usr/bin/qemu-system-x86_64 -name guest=hccns2_hcctest22,debug-threads=on -S -object {"qom-t
root        172  0.0  0.0   3972  3312 pts/0    Ss   08:03   0:00 bash
root        179  0.0  0.0   5700  2876 pts/0    R+   08:03   0:00 ps -aux
[root@hcctest22 /]# ss -tunlp
Netid          State           Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port          Process
udp            UNCONN          0                0                                0.0.0.0:67                            0.0.0.0:*              users:(("virt-launcher",pid=11,fd=17))
[root@hcctest22 /]#

    
    
我还参考了一个脚本,但是这个脚本看起来没有问题,但真正用起来并不顺利,而且 nsenter 无法使用宿主机上的 tcpdump 

#### WAY with crictl 
#### TODO validate crictl with docker runtime !!

# Get all pods of a specific node 
#kubectl  get po --field-selector=spec.nodeName="fluffy-master" --all-namespaces
kubectl get --all-namespaces po --field-selector=spec.nodeName=="$(hostname)" -o json | jq -r '.items[] | select(.status.hostIP!=.status.podIP) | "(.metadata.name) (.metadata.namespace)"'

# Get the Pod ID of the Pod with crictl
POD_ID=$(sudo crictl pods --name=nginx-6f858d4d45-vnszm --namespace=default -q --no-trunc)

# Get the network namespace of this pod
NETNS=$(sudo crictl inspectp ${POD_ID} | jq -r '.info.runtimeSpec.linux.namespaces[] |select(.type=="network") | .path')

# Jump into the network namespace and execute something
sudo nsenter --net=${NETNS} ip -o a s

    
参考: https://gist.github.com/johscheuer/dc20988895d6fddfd057e221d47587d3