由于我这边用的是 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