
Während ich einige TCP-Netzwerkprobleme in Containern untersuchte, habe ich versucht, ss
einen 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
ss
hat dafür folgenden CLI-Schalter:
-N NSNAME, --net=NSNAME
Switch to the specified network namespace name.
lsns
gibt 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 pause
der 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 list
dass 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.
ss
macht 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 iproute
Pakete erstellt werden . network namespaces
Da das Paket ss
mitgeliefert wird, wird hinsichtlich der Netzwerk-Namespaces iproute
folgende Annahme ip
getroffen: „Hey, alle Netzwerk-Namespaces sollten im /var/run/netns
Verzeichnis gefunden werden, weil, also, warum nicht, und außerdem würde dies das Leben der iproute
Entwickler einfacher machen, oder was auch immer.“
Es stellt sich heraus, dass dies eine falsche Annahme auf ss
/ iproute
Seite oder das Fehlen einer "Einigung" über moderne Container-Tools und iproute
Interoperabilität ist, aber es erklärt irgendwie die leere Ausgabe von
ip netns list
Die Art und Weise, wie ip
Netzwerk-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 iproute
Paket-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, ss
gehen Sie wie folgt vor:
Finden Sie die PID des Containerprozesses heraus
ps aux
oderps -ef
sollten Sie die Antwort erhaltenErstellen Sie den folgenden symbolischen Link
ln -s /proc/PID/ns/net /var/run/netns/mycontainer
- 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#