¿Cómo encontrar el espacio de nombres de un proceso en particular?

Respuestas:

39

Trataré de responder tanto a esta como a su pregunta anterior, ya que están relacionadas.

Las puertas a los espacios de nombres son archivos en /proc/*/ns/*y /proc/*/task/*/ns/*.

Un espacio de nombres es creado por un proceso que comparte su espacio de nombres. Un espacio de nombres se puede hacer permanente mediante el montaje del nsarchivo en otro lugar.

Eso es lo que ip netnshace, por ejemplo, para los espacios de nombres netos . Se unshares su netespacio de nombres y bind-montajes /proc/self/ns/neta ./run/netns/netns-name

En un /procespacio de nombres montado pid en la raíz, puede enumerar todos los espacios de nombres que tienen un proceso en ellos haciendo:

# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]

El número entre corchetes es el número de inodo.

Para obtener eso para un proceso dado:

# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid

Ahora, puede haber espacios de nombres permanentes que no tienen ningún proceso en ellos. Descubrirlos puede ser mucho más difícil.

Primero, debe tener en cuenta que puede haber varios espacios de nombres de montaje .

# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw

Esos /mnt/1/a, /run/netns/apueden ser archivos de espacio de nombres.

Podemos obtener un número de inodo:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a

Pero eso no nos dice mucho más que no está en la lista calculada anteriormente.

Podemos intentar ingresarlo como cualquiera de los diferentes tipos:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#

OK, ese era un netarchivo de espacio de nombres.

Por lo tanto, parece que tenemos un método para enumerar los espacios de nombres: enumere los nsdirectorios de todas las tareas, luego encuentre todos los procpuntos de montaje en todos /proc/*/task/*/mountinfoy descubra su tipo al intentar ingresarlos.

Stéphane Chazelas
fuente
19

Si tiene util-linux v2.28 o superior , puede usar lsns :

# lsns
        NS TYPE  NPROCS   PID USER             COMMAND
4026531836 pid       78     1 root             /sbin/init
4026531837 user      79     1 root             /sbin/init
4026531838 uts       78     1 root             /sbin/init
4026531839 ipc       78     1 root             /sbin/init
4026531840 mnt       75     1 root             /sbin/init
4026531857 mnt        1    12 root             kdevtmpfs
4026531957 net       79     1 root             /sbin/init
4026532393 mnt        1  1214 root             /lib/systemd/systemd-udevd
4026532415 mnt        1  2930 systemd-timesync /lib/systemd/systemd-timesyncd
4026532477 mnt        1 32596 root             -bash
4026532478 uts        1 32596 root             -bash
4026532479 ipc        1 32596 root             -bash
4026532480 pid        1 32596 root             -bash

Corrección: lsns no está disponible en util-linux v2.27 como solía decir esta respuesta. Ver https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

Rfraile
fuente
También encontré un buen script de Python, para aquellos en Linux anterior. opencloudblog.com/?p=251
Neil McGill
lsnses muy útil pero solo muestra el PID más bajo en cada espacio de nombres, es decir, no puede decirle el espacio de nombres para cualquier PID arbitrario. +1 de todos modos porque esta sigue siendo una respuesta útil, incluso si no responde directamente a la pregunta.
cas
9
$ ip netns identify $PID

donde $PIDestá el ID del proceso, que puede obtener de varias maneras.

http://man7.org/linux/man-pages/man8/ip-netns.8.html

Ken Sharp
fuente
1
Tenga en cuenta que es solo para espacios de nombres de red y solo los creados usando ip netns(o al menos creados por algo que une y monta las puertas del espacio de nombres en / run / netns como lo ip netnshace). Básicamente busca en / run / netns archivos que sean iguales a /proc/$PID/ns/net.
Stéphane Chazelas
¿Qué? /run/netnsNi siquiera existe en mi computadora.
Ken Sharp
/run/netnso donde sea que se ipunan los archivos especiales del espacio de nombres. findmnt -t nsfspuede decirle dónde está en su sistema. OTOH, si lo haces unshare -n sleep 1000 & ip netns identify "$!", no obtendrás nada.
Stéphane Chazelas
findmnt -t nsfs- nada. unshare -n sleep 1000 & ip netns identify "$!"- unshare: unshare falló: Operación no permitida
Ken Sharp
Necesita privilegios de superusuario (capacidad CAP_SYS_ADMIN) para crear una nueva red. findmnt -t nsfsno devolver nada sugiere que no tiene ninguna red en el cajero automático de su máquina.
Stéphane Chazelas
9

psahora tiene opciones de salida para los diferentes tipos de espacios de nombres asociados a los procesos: ipcns, mntns, netns, pidns, userns, y utsns. Para esta pregunta, el relevante es el espacio de nombres PID, o pidns.

así que si desea encontrar la identificación del espacio de nombres PID para, por ejemplo, pid 459:

# ps -h -o pidns -p 459
4026532661

y para enumerar todos los procesos en ese espacio de nombres:

ps -o pidns,pid,cmd | awk '$1==4026532661'

o con pgrep, puede pasar directamente de un PID a una lista de todos los procesos que comparten el mismo espacio de nombres PID:

pgrep -a --ns 459

A diferencia ps, pgreppuede limitar la salida a un espacio de nombres específico (si conoce el PID de uno de los procesos en él), pero tiene capacidades de formateo de salida muy limitadas (solo PID o PID y sus líneas de comando)

Sin embargo, siempre puede canalizar la salida de pgrep --ns 459to xargs ps -fpara recuperar la información que necesita sobre el proceso.

cas
fuente
0

Espacio de nombres-Lister :

Puedes usar listns.py

Uso: ./listns.pyo python2 listns.pyPara responder con precisión a esta pregunta, puede seleccionar el resultado de esta manera python2 listns.py | grep $PID(reemplace la variable pid)

Fuente: github-mirror y artículo, todo crédito a Ralf Trezeciak

Espacios de nombres de red :

Para el espacio de nombres de red, ip netns identify $PIDse puede utilizar.

Nsutils

Proporcione pidnslistque devuelva el espacio de nombres pid de un proceso

$ pidnslist -ss 8782
pid:[4026531836] 
intika
fuente