如何在特定網路命名空間中使用ss

如何在特定網路命名空間中使用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為每個 Pod 創建的容器Kubernetes——它是創建網路命名空間的容器。

嘗試透過執行以下命令來查看 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

更新: UTC 2020 年 12 月 1 日星期二 11:35:39

經過一番掙扎,我終於決定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)顯然與 kubernetes 等創建它們的方式不匹配,使得iproute套件實用程式在總體方案中毫無用處。

答案1

更通用的方法是使用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

答案2

如果您想使用ss檢視特定容器名稱空間,請執行下列操作:

  1. 找出容器進程的PID ps auxps -ef應該給你答案

  2. 建立以下符號連結

ln -s /proc/PID/ns/net /var/run/netns/mycontainer
  1. 利潤
ss -tpi -N mycontainer

答案3

如果您有最新版本LSNS,您可以使用選項-n -o NSFS將命名空間 inode 轉換為網路子系統所使用的 ID。

例如,假設您有網路 NS 4026536974。

sh-4.4# lsns --version
lsns from util-linux 2.32.1
sh-4.4# lsns -n -o NSFS 4026536974 | sort -u                                                                                                                                                                                                 
/run/netns/d0912eba-0fae-425c-94ba-cf270aa23c93
sh-4.4# basename /run/netns/d0912eba-0fae-425c-94ba-cf270aa23c93                                                                                                                                                                             
d0912eba-0fae-425c-94ba-cf270aa23c93
sh-4.4# ss -nltp -N d0912eba-0fae-425c-94ba-cf270aa23c93 | head -2                                                                                                                                                                           
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port                                                                                    
LISTEN    0         128                0.0.0.0:5000             0.0.0.0:*        users:(("nginx",pid=874035,fd=5),("nginx",pid=874028,fd=5))                    
sh-4.4# 

或合而為一:

sh-4.4# lsns -n -o NSFS 4026536974 | sort -u | xargs -rn1 basename | xargs -rn1 ss -nltp -N | head -2                                                                                                                                        
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port                                                                                    
LISTEN    0         128                0.0.0.0:5000             0.0.0.0:*        users:(("nginx",pid=874035,fd=5),("nginx",pid=874028,fd=5))                    
sh-4.4# 

相關內容