Wie kann man den Namespace eines bestimmten Prozesses herausfinden?

25

Ich habe bereits eine Frage zum Auflisten aller Namespaces unter Linux gestellt , aber es gab keine korrekten und genauen Antworten. Daher möchte ich eine Methode finden, mit der ich den Namespace von PID eines Prozesses oder einer Gruppe von Prozessen ermitteln kann prozesse. Wie geht das unter Linux?

Nullspiel
quelle

Antworten:

39

Ich werde versuchen, sowohl diese als auch Ihre frühere Frage zu beantworten, da sie miteinander zusammenhängen.

Die Türen zu Namespaces sind Dateien in /proc/*/ns/*und /proc/*/task/*/ns/*.

Ein Namespace wird von einem Prozess erstellt, der seinen Namespace freigibt . Ein Namensraum kann dann permanent gemacht werden , indem bind-Montag die nsDatei an einem anderen Ort.

Das ip netnsgilt zum Beispiel für Net Namespaces. Es gibt seinen netNamespace frei und bindet Mounts /proc/self/ns/netan ./run/netns/netns-name

In einem /procim Root-PID bereitgestellten Namespace können Sie alle Namespaces auflisten, in denen sich ein Prozess befindet.

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

Die Zahl in eckigen Klammern ist die Inode-Nummer.

So erhalten Sie das für einen bestimmten Prozess:

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

Möglicherweise gibt es permanente Namespaces, in denen sich kein Prozess befindet. Das herauszufinden, kann viel schwieriger sein.

Zunächst muss beachtet werden, dass es mehrere Mount- Namespaces geben kann.

# 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

Diejenigen /mnt/1/a, /run/netns/akönnen Namespace - Dateien sein.

Wir können eine Inode-Nummer bekommen:

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

Aber das sagt uns nicht viel anderes als es ist nicht in der oben berechneten Liste.

Wir können versuchen, es als einen der verschiedenen Typen einzugeben:

# 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, das war eine netNamespace-Datei.

Es scheint also, als hätten wir eine Methode ns, um die procNamensräume aufzulisten : Listen Sie die Verzeichnisse aller Tasks auf, suchen Sie dann alle Mountpunkte in allen /proc/*/task/*/mountinfound ermitteln Sie ihren Typ, indem Sie versuchen, sie einzugeben.

Stéphane Chazelas
quelle
19

Wenn Sie util-linux v2.28 oder höher haben , können Sie lsns verwenden :

# 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

Korrektur: lsns ist in util-linux v2.27 nicht verfügbar, wie diese Antwort zu sagen pflegte. Siehe https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

Rfraile
quelle
Es gibt auch ein nettes Python-Skript, das ich für ältere Linux-Benutzer gefunden habe. opencloudblog.com/?p=251
Neil McGill
lsnsDies ist sehr nützlich, zeigt jedoch nur die niedrigste PID in jedem Namespace an, dh, es kann nicht der Namespace für eine beliebige PID angegeben werden. +1 auf jeden Fall, weil dies immer noch eine nützliche Antwort ist, auch wenn es die Frage nicht direkt beantwortet.
cas
9
$ ip netns identify $PID

wo $PIDist die Prozess-ID des Prozesses, die Sie auf verschiedene Arten erhalten können.

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

Ken Sharp
quelle
1
Beachten Sie, dass dies nur für Netzwerk-Namespaces und nur für solche gilt, die mit ip netns(oder zumindest mit etwas erstellt wurden, das die Namespace-Türen in / run / netns bindmountet ip netns). Grundsätzlich wird in / run / netns nach Dateien gesucht, die mit identisch sind /proc/$PID/ns/net.
Stéphane Chazelas
Was? /run/netnsexistiert nicht einmal auf meinem Computer.
Ken Sharp
/run/netnsoder wo immer ipdie Namespace-Sonderdateien gebunden werden. findmnt -t nsfskann Ihnen sagen, wo es auf Ihrem System ist. OTOH, wenn du das tust unshare -n sleep 1000 & ip netns identify "$!", bekommst du nichts.
Stéphane Chazelas
findmnt -t nsfs- nichts. unshare -n sleep 1000 & ip netns identify "$!"- Freigabe aufheben: Freigabe fehlgeschlagen: Operation nicht zulässig
Ken Sharp
Sie benötigen Superuser-Berechtigungen (CAP_SYS_ADMIN-Fähigkeit), um neue Netze zu erstellen. findmnt -t nsfsWenn Sie nichts zurückgeben, bedeutet dies, dass Sie keine Netze auf Ihrem Geldautomaten haben.
Stéphane Chazelas
9

psJetzt hat Ausgabeoptionen für die verschiedenen Arten von Namensräumen mit Prozessen verbunden: ipcns, mntns, netns, pidns, userns, und utsns. Bei dieser Frage handelt es sich um den PID-Namespace oder pidns.

Wenn Sie also die PID-Namespace-ID für z. B. pid 459 herausfinden möchten, gehen Sie wie folgt vor:

# ps -h -o pidns -p 459
4026532661

und um alle Prozesse in diesem Namespace aufzulisten:

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

oder mit pgrepkönnen Sie direkt von einer PID zu einer Liste aller Prozesse wechseln, die denselben PID-Namespace verwenden:

pgrep -a --ns 459

Im Gegensatz zu ps, pgrepkann die Ausgabe auf einen bestimmten Namensraum begrenzen (wenn Sie die PID eines der Prozesse in sie kennen), sondern hat nur sehr begrenzte Ausgabeformatierungsfunktionen (PIDs nur oder PIDs und ihre Befehlszeilen)

Sie können die Ausgabe immer pgrep --ns 459an xargs ps -fweiterleiten, um die Informationen abzurufen, die Sie über den Prozess benötigen.

cas
quelle
0

Namespace-Lister :

Sie können listns.py verwenden

Verwendung: ./listns.pyoder python2 listns.pyUm genau diese Frage zu beantworten, können Sie das Ergebnis wie python2 listns.py | grep $PIDfolgt anzeigen (ersetzen Sie die pid-Variable)

Quelle: Github-Spiegel und Artikel alle Dank an Ralf Trezeciak

Netzwerk Namespaces :

ip netns identify $PIDKann als Netzwerk-Namespace verwendet werden.

Nsutils

Stellen Sie sicher, pidnslistdass der pid-Namespace eines Prozesses zurückgegeben wird

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