如何匹配虚拟以太网链路的两侧?

如何匹配虚拟以太网链路的两侧?

我运行的docker容器都连接到我自己的网桥(不是标准docker0网桥)。从主机角度来看,它看起来是这样的(我只留下了与虚拟桥接和以太网相关的信息):

root@srv ~# ip link
(...)    
8: br-7b20560b3603: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:7c:70:e1:47 brd ff:ff:ff:ff:ff:ff
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether 02:42:f1:70:4f:a6 brd ff:ff:ff:ff:ff:ff
11: veth1fb5957@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 4e:38:69:b2:db:ef brd ff:ff:ff:ff:ff:ff link-netnsid 2
13: vethc225476@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 56:1d:d5:96:68:ac brd ff:ff:ff:ff:ff:ff link-netnsid 1
377: veth7fcee93@if376: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 62:06:5d:c7:31:7b brd ff:ff:ff:ff:ff:ff link-netnsid 4
431: vethd0879bb@if430: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether 0a:f8:aa:02:a9:f4 brd ff:ff:ff:ff:ff:ff link-netnsid 3
245: veth4a8ecb1@if244: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7b20560b3603 state UP mode DEFAULT group default
    link/ether d6:86:f1:8b:73:ab brd ff:ff:ff:ff:ff:ff link-netnsid 0

当连接到其中一个容器时,我看到

root@vpnin ~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:0a:c8:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0

拓扑结构是这样的,在主机上,br-7b20560b3603有多veth*个子节点,每个子节点都连接到一个容器 — — 另一侧成为容器的eth0

我怎样才能找出veth*主机上哪个与 eth0@<something>容器中对应?

我可以看到主机上的第一列有,这与容器中的13类似。反过来,对应于容器中的标签,在主机上引用为。我不知道这是否是巧合 - 如果不是,那么 中的第一列标签对应于什么?eth0@if13eth0@if1312vethc225476@if12ip link

答案1

正如您所怀疑的, 确实@if13引用了第一列中的数字,即数字ifindex(至少,“ifindex”是 libnl 公开的变量的名称,用于与内核通信以获取此类信息)。当数字存在于同一命名空间中时,ip 实用程序会显示与数字关联的名称,而不是数字(例如myvlan@eth0)。

您还可以看到字段“link-netnsid”,它是另一个整数,用于标识保存链接的命名空间(可以是 veth 对的另一端,如您在此处所见,也可以是处理设备的另一端,例如其 IP 地址用于隧道设备的命名空间)。您可以使用列出这些ip netns list-id(至少在 iproute2 的最新版本上)。如果命名空间安装在通常的位置,它将在 ID 旁边显示网络命名空间的名称。

例子:

$ sudo ip link add name veth1 type veth peer name veth2
$ ip link show | grep veth
32: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
33: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group

$ sudo ip netns add examplens
$ sudo ip link setns examplens dev veth2
$ ip link show | grep -a1 veth
33: veth1@if32: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default
link/ether e2:99:ce:05:64:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 2

$ ip netns list-id
nsid 0 
nsid 1 
nsid 2 (iproute2 netns name: examplens)

$ sudo ip -n examplens link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
32: veth2@if33: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3a:89:30:01:4a:49 brd ff:ff:ff:ff:ff:ff link-netnsid 0

在上面,我们创建了一个 veth 对,可以看到两端都显示另一端的名称。然后,我们创建一个名为 netnsexamplens并将 veth2 移入其中。现在 ip 不再知道 veth1 对等体的名称,但仍然有 ifnumber,因此它显示为 if32,我们可以看到这是移动之前的名称。我们还看到链接位于 netnsid (nsid) 2 中,我们看到它名为 examplens。

列出 examplens 中的链接显示 veth2,其对等体在 netnsid 0 中具有 ifnumber 33。

不幸的是,当 nsid 未绑定到并进入时/var/run/netns(这是ip实用程序 bind 挂载其创建的 netns 以为其命名的地方),ip 实用程序无法帮助您找到 nsid 的位置。许多(大多数?所有?)其他实用程序似乎都没有这样做,包括 docker,因此在从主机查找另一端方面没有太大帮助,使用户手动搜索其他网络命名空间(例如,通过查找 /proc/*/ns/net 中的所有唯一条目)。

简而言之,当您知道容器的链接列表时,这有助于在主机上找到链接,但当您拥有主机的链接列表时,这并不能很好地找到容器。

关于 s 的最后一点说明nsid:它们对于每个 netns 都是唯一的。例如,nsid 0主机的命名空间与我的示例中的 examplens 命名空间中的命名空间不同。nsid 0

答案2

Docker 将条目存储在中/var/run/docker/netns,因此您将看不到所有使用 的 netns 名称ip netns list-id。(该(iproute2 netns name: ***)部分将为空。)

根据手册页,# IP 网络列表This command displays all of the network namespaces in /run/netns

我创建了一个工具来说明 veth 之间的关系,希望它能够帮助到某些人 :D

https://github.com/t1anz0ng/iftree

相关内容