Networking
如何在特定的網路命名空間中使用 ss
在調查容器中的一些 TCP 網路問題時,我試圖用來
ss
窺探容器網路 TCP 堆棧。我們在 AWS 中執行 Amazon Linux:
# uname -a Linux 4.14.173-137.229.amzn2.x86_64 #1 SMP Wed Apr 1 18:06:08 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
ss
有以下 cli 開關:-N NSNAME, --net=NSNAME Switch to the specified network namespace name.
lsns
給我以下輸出:# lsns | grep net 4026531993 net 225 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 21 4026532284 net 2 26244 root /pause
這是
pause
為每個Kubernetes
pod 創建的容器——它是創建網路命名空間的容器。嘗試通過執行以下命令查看 pod 網路命名空間
ss
:# ss -tp -N 4026532284 Cannot open network namespace "4026532284": No such file or directory
有趣的是
ip netns list
不返回任何網路命名空間:# ip netns list #
有什麼方法可以從根網路命名空間(即 netns 1)查看 K8s pod 網路命名空間?
# ss --version ss utility, iproute2-ss180129 # lsns --version lsns from util-linux 2.30.2 # rpm -qi iproute Name : iproute Version : 4.15.0 Release : 1.amzn2.0.4 Architecture: x86_64 Install Date: Sat 07 Mar 2020 03:42:24 AM UTC Group : Applications/System Size : 1321292 License : GPLv2+ and Public Domain Signature : RSA/SHA256, Fri 21 Feb 2020 09:00:29 PM UTC, Key ID 11cf1f95c87f5b1a Source RPM : iproute-4.15.0-1.amzn2.0.4.src.rpm Build Date : Fri 21 Feb 2020 07:56:50 PM UTC Build Host : build.amazon.com Relocations : (not relocatable) Packager : Amazon Linux Vendor : Amazon Linux URL : http://kernel.org/pub/linux/utils/net/iproute2/ Summary : Advanced IP routing and network device configuration tools
更新:2020 年 12 月 1 日星期二 11:35:39 UTC
經過一番掙扎,我終於下定了決心
strace
。事實證明這
ss
是一個很棒的工具,但是當它與容器一起使用時,它還有一點不足之處,但我覺得涉及的“罪魁禍首”不止一個。
ss
無需查找創建網路名稱空間的程序的實際 PID,而是直接檢查/var/run/netns
:openat(AT_FDCWD, "/var/run/netns/4026532284", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) write(2, "Cannot open network namespace \"4"..., 70Cannot open network namespace "4026532284": No such file or directory ) = 70
現在,我懷疑這是由於包是如何
iproute
創建network namespaces
的,即考慮到包ss
是隨iproute
包一起提供的,關於網路命名空間的假設ip
是:“嘿,所有網路 ns 都應該在/var/run/netns
目錄中找到,因為,為什麼不,這也會使生活iproute
開發容易,或者其他什麼。事實證明,這是在
ss
/iproute
方面做出的錯誤假設,或者在現代容器工具和互操作性上缺乏“協議”iproute
,但這在某種程度上解釋了來自ip netns list
因此,創建網路命名空間的方式(
ip
因此它們可以被.ss``iproute
更通用的方法是使用
nsenter(1)
.nsenter -t ${PID_FOO} -muni ss -tpi
一種方法是使用類似以下的東西,當需要執行臨時的東西時,不一定支持
unshare(2)
/setns(2)
內置。docker run -it --rm --security-opt=seccomp:unconfined \ --security-opt=apparmor:unconfined \ --privileged --pid=host --userns=host \ debian:jessie@sha256:51cd80bb935b76fbbf49640750736abc63ab7084d5331e198326b20063e7f13c \ nsenter -t ${PID_FOO} -m -u -n -i -F ss -tpi