切換到網路命名空間不會改變 /sys/class/net?
網路命名空間 (7)的 Linux 手冊頁說:
網路命名空間提供與網路相關的系統資源的隔離:
$$ … $$, /sys/class/net 目錄,$$ … $$.
然而,簡單地切換到不同的網路命名空間似乎並沒有改變
/sys/class/net
(見下文如何重現)的內容。我只是誤以為setns()
進入網路名稱空間已經足夠了嗎?是否總是需要重新掛載/sys
才能正確/sys/class/net
匹配目前加入的網路命名空間?還是我在這裡錯過了其他東西?重現的例子
拿一個 *ubuntu 系統,找到 rtkit-daemon 的 PID,進入 daemon 的網路命名空間,顯示它的網路介面,然後檢查
/sys/class/net
:$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2` $ sudo nsenter -t $PID -n # ip link show 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 # ls /sys/class/net docker0 enp3s0 lo lxcbr0 ...
請注意,雖然
ip link show
正確只顯示lo
,/sys/class/net
顯示在“根”網路命名空間(和“根”掛載命名空間)中可見的所有網路介面。在
rtkit-daemon
也進入它的掛載命名空間的情況下沒有區別:sudo nsenter -t $PID -n -m
然後ls /sys/class/net
仍然顯示網路命名空間中不存在的網路介面。“使固定”
感謝@Danila Kiver解釋了 Linux 核心幕後的真實情況。
sysfs
在加入正確的網路命名空間時重新安裝將顯示正確的條目/sys/class/net
:$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2` $ sudo nsenter -t $PID -n # MNT=`mktemp -d` # mount -t sysfs none $MNT # ls $MNT/class/net/ lo # umount $MNT # rmdir $MNT # exit
所以這現在產生了正確的結果
/sys/class/net
。
讓我們看看
man 5 sysfs
:/sys/class/net Each of the entries in this directory is a symbolic link representing one of the real or virtual networking devices that are visible in the network namespace of the process that is accessing the directory.
所以,根據這個手冊頁, 的輸出
ls /sys/class/net
必須依賴於ls
程序的網路命名空間。但是…實際行為似乎與本手冊中的描述不同。關於它是如何工作的,有一個很好的核心文件。每個
sysfs
掛載都有一個與之關聯的命名空間標籤。這個標籤是在 sysfs 被掛載時設置的,它依賴於呼叫程序的網路命名空間。每個 sysfs 條目(例如 中的條目/sys/class/net
)也可能具有與其關聯的名稱空間標記。當您遍歷 sysfs 目錄時,核心會獲取sysfs mount 的命名空間標籤,然後它會遍歷條目,過濾掉具有不同命名空間標籤的條目。
因此,事實證明,迭代的結果
/sys/class/net
取決於啟動/sys
掛載的程序的網路命名空間,而不是目前程序的網路命名空間,因此,您必須始終掛載/sys
在目前的網路命名空間中(來自任何屬於到此命名空間)以查看正確的結果。