Cómo usar ss en un espacio de nombres de red específico

Cómo usar ss en un espacio de nombres de red específico

Mientras investigaba algunos problemas de la red TCP en contenedores, intenté utilizar sspara 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

sstiene el siguiente interruptor cli para eso:

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

lsnsme 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 pauseun contenedor creado para cada Kubernetespod; 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 listno 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 straceesto.

Resulta que sses 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.

ssno 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 iproutese crea el paquete network namespaces, es decir, dado que ssse envía con iprouteel paquete, la suposición ipque se hace sobre los espacios de nombres de red es: "oye, todos los ns de red deben encontrarse en /var/run/netnsel directorio, porque, por qué no, y también esto mejorará la vida de iproutedesarrolladores fáciles, o lo que sea.

Resulta que es una suposición falsa hecha por ssel iproutelado o la falta de "acuerdo" sobre las herramientas modernas de contenedores y iproutela interoperabilidad, pero en cierto modo explica el resultado vacío de

ip netns list

Entonces, la forma en ipque 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 iproutelas 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 sspara echar un vistazo a un espacio de nombres de contenedor en particular, así es como lo hace:

  1. Descubra el PID del proceso del contenedor ps auxo ps -efdebería darle la respuesta

  2. Crea el siguiente enlace simbólico

ln -s /proc/PID/ns/net /var/run/netns/mycontainer
  1. 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# 

información relacionada