编辑
2024-01-10
Docker
00
请注意,本文编写于 128 天前,最后修改于 60 天前,其中某些信息可能已经过时。

目录

方法一 (不进入容器)
方法二 (进入容器)
通过 ip link
通过 ethtool 查找
进入容器网络命名空间内部(推荐)

方法一 (不进入容器)

根据 pod 信息到 pod 所在物理机查看路由信息,找到对应的cali*网卡

这里以 nginx-79b95cb6d6-qs546 为例

bash
(base)  ~/ k get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-79b95cb6d6-qs546 1/1 Running 0 3m30s 192.168.162.131 kind-worker <none> <none>

可以看到 该 pod 被调度到了 kind-worker 节点上

登录到 kind-worker 节点上,执行 ip route 命令,查看 192.168.162.131 的路由信息

bash
root@kind-worker:/# ip route | grep 192.168.162.131 192.168.162.131 dev calid74d2a12d3d scope link

执行 ip addr 命令,查看 calid74d2a12d3d 网卡信息

bash
root@kind-worker:/# ip address show calid74d2a12d3d 6: calid74d2a12d3d@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netns cni-52e508fd-4eb9-990a-178d-12723059981a

方法二 (进入容器)

  • 进入容器内部,查看 /sys/class/net/eth0/iflink 文件。以找到此网卡外联的 veth pair 的另一张网卡的 inde
bash
(base)  ~/ k get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-79b95cb6d6-qs546 1/1 Running 0 10m 192.168.162.131 kind-worker <none> <none> (base)  ~/ k exec -it nginx-79b95cb6d6-qs546 bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. root@nginx-79b95cb6d6-qs546:/# cat /sys/class/net/eth0/iflink 11

可以看到 eth0 网卡的 iflink6 登录pod所在节点,查看编号为 6 的网卡信息

bash
[root@master ~]# ip link show | grep '11: ' -A1 11: calidbf6882f897@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8981 qdisc noqueue state UP mode DEFAULT group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 5

最后就可以通过该网卡进行抓包了。

bash
root@kind-worker:/# tcpdump -i calid74d2a12d3d -nn -s0 -w /tmp/calid74d2a12d3d.pcap

通过 ip link

容器内部查看容器网卡信息,注意看3: eth0@if8,其中3是eth0网卡的index,8是和它成对的veth的index。

bash
[root@master1 ~]# kubectl exec -it redis-968b459c9-5kzls /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. /data # ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 3: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 8e:57:11:a2:64:cd brd ff:ff:ff:ff:ff:ff

到运行此容器的宿主机上,执行如下命令,就能找到对应的 8 的veth网卡是哪一个了。

bash
[root@master2 ~]# ip link show|grep 8 8: veth13c5ce87@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default link/ether 26:c4:8f:04:7a:66 brd ff:ff:ff:ff:ff:ff link-netnsid 0

通过 ethtool 查找

在容器中执行:ethtool -S eth0 命令,eth0为容器中的网卡的名字。

bash
root@336043b07211:/# ethtool -S eth0 NIC statistics: peer_ifindex: 8

到运行此容器的宿主机上,执行如下命令,就能找到对应的 8 的veth网卡是哪一个了。

bash
[root@master2 ~]# ip link show|grep 8 8: veth13c5ce87@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default link/ether 26:c4:8f:04:7a:66 brd ff:ff:ff:ff:ff:ff link-netnsid 0

进入容器网络命名空间内部(推荐)

  1. 找到容器ID

连到运行此容器的宿主机上通过 docker ps 命令找到容器编号,还是以 redis 示例为例。

image.png

执行以下命令,可以看到 redis 容器编号是 fa78537331d1。

bash
[root@master1 ~]# ssh master2 [root@master2 ~]# docker ps|grep redis fa78537331d1 a70d80b7cdb0 "docker-entrypoint.s…" 2 days ago Up 2 days k8s_redis_redis-968b459c9-5kzls_default_81aa239b-4578-4711-bf6c-a7225012f48b_2 3ecfef7dbe7c 10.20.32.201:80/library/pause:3.4.1 "/pause" 2 days ago Up 2 days k8s_POD_redis-968b459c9-5kzls_default_81aa239b-4578-4711-bf6c-a7225012f48b_21 [root@master2 ~]#

注意 1,之后进入容器时候使用容器编号 fa78537331d1 或 3ecfef7dbe7c 都可以,他们是同一个 Pod, 共享容器网络命名空间。

  1. 找到容器网络命名空间编号

通过 'docker inspect --format "{{.State.Pid}}" 容器编号' 命令找到容器网络命名空间编号。

bash
[root@master2 ~]# docker inspect --format "{{.State.Pid}}" fa78537331d1 16712
  1. 进入容器网络命名空间并查看网卡信息

通过 'nsenter -n -t 网络命名空间编号' 命令进入当前容器网络命名空间,并通过 ip link 命令查看当前容器网卡信息,注意看3: eth0@if8,其中3是eth0网卡的index,8是和它成对的veth 的index。

bash
[root@master2 ~]# nsenter -n -t 16712 [root@master2 ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 3: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP mode DEFAULT group default link/ether 8e:57:11:a2:64:cd brd ff:ff:ff:ff:ff:ff link-netnsid 0
  1. 查找docker容器中的网卡外联的veth pair的另一张网卡

那么只需要到运行此容器的宿主机上,执行如下命令,就能找到对应的 8 的veth网卡是哪一个了。

bash
[root@master2 ~]# ip link show|grep 8 8: veth13c5ce87@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default link/ether 26:c4:8f:04:7a:66 brd ff:ff:ff:ff:ff:ff link-netnsid 0
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:liulei

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!