Networking

如何匹配虛擬乙太網鏈路的兩端?

  • March 10, 2018

我執行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@if13容器中的 。反過來,eth0@if13對應於容器中的標籤,在主機上12引用。vethc225476@if12我不知道這是否是巧合 - 如果不是,第一列標籤ip link對應什麼?

正如您所懷疑的那樣,@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

在上面,我們創建了一個 veth pair,可以看到兩端都顯示了另一端的名稱。然後我們創建一個名為 netnsexamplens並將 veth2 移入其中。現在 ip 不再知道 veth1 的對等方的名稱,但仍然有 ifnumber,所以它顯示的是 (if32),我們可以看到它在移動之前是什麼。我們還看到該連結在 netnsid (nsid) 2 中,我們看到它被命名為 examplens。

列出 examplens 中的連結顯示 veth2,其對等方在 netnsid 0 中具有 ifnumber 33。

不幸的是,當 nsid 未綁定和進入時,ip 實用程序無法幫助您找到它的位置/var/run/netns(這是ip實用程序綁定掛載其創建的 netns 以為其命名的位置)。許多(大多數?全部?)其他實用程序似乎沒有這樣做,包括 docker,因此從主機查找另一端並沒有太多幫助,使使用者手動搜尋其他網路名稱空間(例如,通過查找/proc/*/ns/net 中的所有唯一條目)。

簡而言之,當你知道容器的連結列表時,這有助於在主機上找到連結,但當你知道主機的連結列表時,這對找到容器沒有多大幫助。

關於nsids 的最後一點說明:它們對於每個 netns 都是唯一的。nsid 0例如,主機的名稱nsid 0空間與我的範例中的 examplens 名稱空間不同。

引用自:https://serverfault.com/questions/818784