
Mientras investigaba algunos problemas de la red TCP en contenedores, intenté utilizar ss
para echar un vistazo a la pila TCP de la red de contenedores.
Estamos ejecutando Amazon Linux en AWS:
# 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
tiene el siguiente interruptor cli para eso:
-N NSNAME, --net=NSNAME
Switch to the specified network namespace name.
lsns
me da el siguiente resultado:
# lsns | grep net
4026531993 net 225 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 21
4026532284 net 2 26244 root /pause
Este es pause
un contenedor creado para cada Kubernetes
pod; es el contenedor que crea el espacio de nombres de la red.
Intentando echar un vistazo al espacio de nombres de la red pod ejecutando ss
:
# ss -tp -N 4026532284
Cannot open network namespace "4026532284": No such file or directory
Lo interesante es que ip netns list
no devuelve ningún espacio de nombres de red:
# ip netns list
#
¿Hay alguna forma de buscar los espacios de nombres de red de pods de K8 desde el espacio de nombres de la red raíz, es decir, desde netns 1?
# 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
Actualización: martes 1 de diciembre a las 11:35:39 UTC de 2020
Después de un poco de lucha, finalmente me decidí por strace
esto.
Resulta que ss
es una herramienta increíble, pero cuando se trata de usarla con contenedores deja un poco que desear, pero siento que hay más de un "culpable" involucrado.
ss
no se molesta en buscar el PID real del proceso que crea los espacios de nombres de la red, sino que va directamente a verificar /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
Ahora, sospecho que esto se debe a cómo iproute
se crea el paquete network namespaces
, es decir, dado que ss
se envía con iproute
el paquete, la suposición ip
que se hace sobre los espacios de nombres de red es: "oye, todos los ns de red deben encontrarse en /var/run/netns
el directorio, porque, por qué no, y también esto mejorará la vida de iproute
desarrolladores fáciles, o lo que sea.
Resulta que es una suposición falsa hecha por ss
el iproute
lado o la falta de "acuerdo" sobre las herramientas modernas de contenedores y iproute
la interoperabilidad, pero en cierto modo explica el resultado vacío de
ip netns list
Entonces, la forma en ip
que se crean los espacios de nombres de red (para que puedan ser inspeccionados por ss
) obviamente no coincide con la forma en que los crean kubernetes y similares, lo que hace que iproute
las utilidades de los paquetes sean casi inútiles en el gran esquema de las cosas.
Respuesta1
Una forma más genérica es utilizarnsenter(1)
.
nsenter -t ${PID_FOO} -muni ss -tpi
Un enfoque a seguir es usar algo como lo siguiente, cuando sea necesario ejecutar cosas ad hoc, que no necesariamente tienen soporte paraunshare(2)
/setns(2)
incorporado.
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
Respuesta2
Si desea utilizar ss
para echar un vistazo a un espacio de nombres de contenedor en particular, así es como lo hace:
Descubra el PID del proceso del contenedor
ps aux
ops -ef
debería darle la respuestaCrea el siguiente enlace simbólico
ln -s /proc/PID/ns/net /var/run/netns/mycontainer
- Ganancia
ss -tpi -N mycontainer
Respuesta3
Si tienes una versión reciente delsns, puedes usar opciones-n -o NSFSpara convertir un inodo de espacio de nombres en el ID utilizado por el subsistema de red.
Por ejemplo, digamos que tiene net NS 4026536974. Puede ejecutar:
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#
O todo en uno:
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#