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

WoJ*_*WoJ 4 networking virtualization bridge linux-networking

我运行的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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

如何找出veth*主机上的哪个对应于 eth0@<something>容器中的?

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

小智 6

正如您所怀疑的,@if13确实指的是第一列中的数字,即ifindex数字(至少,“ifindex”是 libnl 公开的变量的名称,用于与内核进行 netlink 通信以获取此类信息) 。当该号码存在于同一命名空间中时,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
Run Code Online (Sandbox Code Playgroud)

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

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

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

简而言之,当您知道容器的链接列表时,这有助于查找主机上的链接,但当您拥有主机的链接列表时,这对查找容器没有太大帮助。

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