So verwenden Sie SS in einem bestimmten Netzwerk-Namespace

So verwenden Sie SS in einem bestimmten Netzwerk-Namespace

Während ich einige TCP-Netzwerkprobleme in Containern untersuchte, habe ich versucht, sseinen Blick in den TCP-Stack des Containernetzwerks zu werfen.

Wir führen Amazon Linux in AWS aus:

# 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

sshat dafür folgenden CLI-Schalter:

       -N NSNAME, --net=NSNAME
              Switch to the specified network namespace name.

lsnsgibt mir folgende Ausgabe:

# lsns | grep net
4026531993 net       225     1 root      /usr/lib/systemd/systemd --switched-root --system --deserialize 21
4026532284 net         2 26244 root      /pause

Dies ist pauseder für jeden Pod erstellte Container Kubernetes. Es ist der Container, der den Netzwerk-Namespace erstellt.

Ich versuche, einen Blick in den Pod-Netzwerk-Namespace zu werfen, indem ich Folgendes ausführe ss:

# ss -tp -N 4026532284
Cannot open network namespace "4026532284": No such file or directory

Interessant ist, ip netns listdass keine Netzwerk-Namespaces zurückgegeben werden:

# ip netns list
#

Gibt es eine Möglichkeit, wie man sich die K8s-Pod-Netzwerk-Namespaces vom Root-Netzwerk-Namespace aus, also von NetNS 1 aus, ansehen kann?

# 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

Aktualisiert: Dienstag, 1. Dezember 2020, 11:35:39 UTC

Nach einigem Hin und Her habe ich mich schließlich dazu entschlossen strace.

Es stellt sich heraus ss, dass es ein fantastisches Tool ist, aber wenn es um die Verwendung mit Containern geht, lässt es ein wenig zu wünschen übrig, aber ich denke, dass mehr als ein „Übeltäter“ daran beteiligt ist.

ssmacht sich nicht die Mühe, die tatsächliche PID des Prozesses nachzuschlagen, der die Netzwerk-Namespaces erstellt, sondern prüft direkt /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

Nun vermute ich, dass dies an der Art und Weise liegt, wie iproutePakete erstellt werden . network namespacesDa das Paket ssmitgeliefert wird, wird hinsichtlich der Netzwerk-Namespaces iproutefolgende Annahme ipgetroffen: „Hey, alle Netzwerk-Namespaces sollten im /var/run/netnsVerzeichnis gefunden werden, weil, also, warum nicht, und außerdem würde dies das Leben der iprouteEntwickler einfacher machen, oder was auch immer.“

Es stellt sich heraus, dass dies eine falsche Annahme auf ss/ iprouteSeite oder das Fehlen einer "Einigung" über moderne Container-Tools und iprouteInteroperabilität ist, aber es erklärt irgendwie die leere Ausgabe von

ip netns list

Die Art und Weise, wie ipNetzwerk-Namespaces erstellt werden (damit sie überprüft werden können ss), stimmt offensichtlich nicht mit der Art und Weise überein, wie sie von Kubernetes und ähnlichen Programmen erstellt werden, was iproutePaket-Dienstprogramme im Großen und Ganzen nahezu nutzlos macht.

Antwort1

Eine allgemeinere Möglichkeit besteht darin,nsenter(1).

nsenter -t ${PID_FOO} -muni ss -tpi

Ein guter Ansatz ist die Verwendung von etwas wie dem Folgenden, wenn Ad-hoc-Sachen ausgeführt werden müssen, die nicht unbedingt Unterstützung fürunshare(2)/setns(2)eingebaut.

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

Antwort2

Wenn Sie einen Blick auf einen bestimmten Container-Namespace werfen möchten, ssgehen Sie wie folgt vor:

  1. Finden Sie die PID des Containerprozesses heraus ps auxoder ps -efsollten Sie die Antwort erhalten

  2. Erstellen Sie den folgenden symbolischen Link

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

Antwort3

Wenn Sie eine aktuelle Version vonlsnskönnen Sie Optionen verwenden-n -o NSFSum einen Namespace-Inode in die vom Netzwerksubsystem verwendete ID zu konvertieren.

Nehmen wir beispielsweise an, Sie haben das Netz NS 4026536974. Sie können Folgendes ausführen:

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# 

Oder alles in einem:

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# 

verwandte Informationen