容器网卡背景信息
选择目标容器
# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox-7868487dfd-7rndh 1/1 Running 0 41m
busybox-7868487dfd-gjkq6 1/1 Running 0 41m
busybox-7868487dfd-h5x52 1/1 Running 0 41m
这里以 busybox-7868487dfd-7rndh
进行分析,登录到调度的 node 节点
进入容器的 network namespace
# docker ps |grep busybox-7868487dfd-7rndh
7133522c199f busybox "/bin/sh -c 'sleep 9…" 43 minutes ago Up 43 minutes k8s_busybox_busybox-7868487dfd-7rndh_default_a630fdc7-48b6-4e4e-a2ac-b261feb9a113_0
8e68caadcac1 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1 "/pause" 43 minutes ago Up 43 minutes k8s_POD_busybox-7868487dfd-7rndh_default_a630fdc7-48b6-4e4e-a2ac-b261feb9a113_0
找到 POD 对应的容器 ID 7133522c199f
的 PID
# docker inspect 7133522c199f |grep -iw pid
"Pid": 39554,
创建 netns 链接
# ln -s /proc/39554/ns/net /var/run/netns/mybox1-netns
# ls -lh /var/run/netns/mybox1-netns
lrwxrwxrwx 1 root root 18 Apr 26 16:17 /var/run/netns/mybox1-netns -> /proc/39554/ns/net
进入容器进程的 network namespace
nsenter --net=/var/run/netns/mybox1-netns bash
或
ip netns exec mybox1-netns bash
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 8e:4e:71:5f:31:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.244.0.3/24 brd 10.244.0.255 scope global eth0
valid_lft forever preferred_lft forever
找veth网卡对-容器内 ifindex 编号
找到网卡的 ifindex 编号
方法1:使用 ethtools
# ethtool -S eth0
NIC statistics:
peer_ifindex: 7
方法2:ip add 查看 查看网卡名 eth0@if7
# ip addr show eth0
3: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 8e:4e:71:5f:31:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.244.0.3/24 brd 10.244.0.255 scope global eth0
valid_lft forever preferred_lft forever
方法3:登录到容器中查看iflink
# docker exec -it 7133522c199f bash
cat /sys/class/net/eth0/iflink
7
以上三种方法都可以查看并确认该容器的 veth 对的 iflink 是 7 。
找veth网卡对-容器外 vethXXX 对应的网卡
方法1
以 7:
开头的网卡就是 iflink 的对端的网卡
# ip addr show |grep -w "^7:"
7: vethcd30ef34@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP group default
方法2
过滤所有网卡网卡,查找有 7
的文件
# find /sys/devices/virtual/net -type f -name "ifindex" |xargs grep "7"
/sys/devices/virtual/net/vethcd30ef34/ifindex:7
这里可以看到路径中 vethcd30ef34
为绑定在网桥上的虚拟网卡的的名称
# ip addr show |grep vethcd30ef34
7: vethcd30ef34@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP group default
在宿主机上可以看到该 虚拟 vethXXX 最下面的 ID 同样为 7:
确认 vethXX 绑定的虚拟网桥
找到宿主机上的 vethXX 网卡信息中有其所属的网桥
# ip addr show |grep vethcd30ef34
7: vethcd30ef34@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP group default
上面信息中 master cni0
表示该网卡绑定到 cni0 网桥上
查看网桥上的网络列表
方法1:
# ip link show master cni0
6: veth0fd7e97f@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether 7e:9a:3c:4a:5a:67 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: vethcd30ef34@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether 5e:19:d8:c0:04:1b brd ff:ff:ff:ff:ff:ff link-netns mybox1-netns
8: veth2e8c88c8@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether d2:90:e3:e1:68:ef brd ff:ff:ff:ff:ff:ff link-netns busybox1-netns
9: veth82348966@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether 7a:74:b9:18:34:cd brd ff:ff:ff:ff:ff:ff link-netnsid 3
*方法2:
# brctl show
bridge name bridge id STP enabled interfaces
cni0 8000.263025c98cbd no veth0fd7e97f
veth2e8c88c8
veth82348966
vethcd30ef34
docker0 8000.0242b4dbdeda no
由 brctl show
可以看到该机器上有2个网桥,而要查找的 vethcd30ef34 链接到 cni0
上
提示:
brctl 命令需要安装
yum install -y bridge-utils
流量走向分析
容器内默认路由
# ip netns exec mybox1-netns bash
# ip route
default via 10.244.0.1 dev eth0
10.244.0.0/24 dev eth0 proto kernel scope link src 10.244.0.3
10.244.0.0/16 via 10.244.0.1 dev eth0
容器内默认的默认路由都是由网卡 eth0 发送给网关 10.244.0.1
。数据的走向就是上文分析的通过:
容器内eth0 <--> 主机虚拟网卡vethcd30ef34 --> cni0网桥 --> 10.244.0.1
这里的 10.244.0.1 是网桥 cni0 的 IP 地址。
这时容器内的数据包就可以发送到宿主机上了。
cni0 转发 给 flannel.1
容器内出来的数据包根据以下路由会转发给 flannel.1 网卡
aaa
进入容器的数据包,根据路由会转发给 cni0
# ip route
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1
Flannel.1网卡的和 flanneld 进程组成 overlay 网络的设备,用来进行 vxlan 报文的处理(封包和解包)。不同 node 之间的 pod 数据流量都从 overlay 设备以隧道的形式发送到对端。