bagaimana cara mengetahui namespace dari proses tertentu?

25

Saya sudah mengajukan pertanyaan tentang cara membuat daftar semua ruang nama di Linux , tetapi tidak ada jawaban yang benar dan tepat, jadi saya ingin mencari metode yang dapat membantu saya menemukan namespace PID dari beberapa proses atau kelompok proses. Bagaimana itu bisa dilakukan di Linux?

zerospiel
sumber

Jawaban:

39

Saya akan mencoba dan menjawab ini dan juga pertanyaan Anda sebelumnya karena mereka terkait.

Pintu ke ruang nama adalah file di /proc/*/ns/* dan /proc/*/task/*/ns/*.

Namespace dibuat oleh proses yang tidak membagikan namespace-nya. Namespace kemudian dapat dibuat permanen dengan bind-mount yang nsberkas ke tempat lain.

Itulah yang ip netnsdilakukan misalnya untuk ruang nama bersih . Itu unshares netnamespace dan bind-mounts /proc/self/ns/netke ./run/netns/netns-name

Di /procmount di namespace pid root, Anda bisa daftar semua namespaces yang memiliki proses di dalamnya dengan melakukan:

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

Angka dalam tanda kurung adalah nomor inode.

Untuk mendapatkannya untuk proses tertentu:

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

Sekarang mungkin ada ruang nama permanen yang tidak memiliki proses di dalamnya. Menemukan mereka bisa menjadi AFAICT yang jauh lebih rumit.

Pertama, Anda harus ingat bahwa mungkin ada beberapa mount namespaces.

# 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

Itu /mnt/1/a,/run/netns/a mungkin file namespace.

Kami bisa mendapatkan nomor inode:

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

Tapi itu tidak memberi tahu kita banyak selain itu tidak ada dalam daftar yang dihitung di atas.

Kita dapat mencoba dan memasukkannya sebagai salah satu dari berbagai jenis:

# 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
#

OKE, itu a net file namespace.

Jadi sepertinya kita memiliki metode untuk membuat daftar ruang nama: daftarkan nsdirektori semua tugas, lalu temukan semua procmountpoint di semua /proc/*/task/*/mountinfodan cari tahu tipenya dengan mencoba memasukkannya.

Stéphane Chazelas
sumber
19

Jika Anda memiliki util-linux v2.28 atau lebih baru, Anda dapat menggunakan 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

Koreksi: lsns tidak tersedia di util-linux v2.27 seperti jawaban yang biasa dikatakan. Lihat https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

Rfraile
sumber
Ada juga skrip python bagus yang saya temukan, bagi mereka yang menggunakan linux lama. opencloudblog.com/?p=251
Neil McGill
lsnssangat berguna tetapi hanya menunjukkan PID terendah di setiap namespace - yaitu tidak bisa memberi tahu Anda namespace untuk setiap PID sewenang-wenang. +1 tetap karena ini masih merupakan jawaban yang berguna bahkan jika itu tidak langsung menjawab pertanyaan.
cas
9
$ ip netns identify $PID

di mana $PIDID proses dari proses, yang bisa Anda dapatkan dengan berbagai cara.

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

Ken Sharp
sumber
1
Perhatikan bahwa ini hanya untuk ruang nama jaringan dan hanya yang dibuat menggunakan ip netns(atau setidaknya dibuat oleh sesuatu yang mengikat mount pintu namespace di / run / netns seperti yang ip netnsdilakukan). Ini pada dasarnya terlihat di / run / netns untuk file yang sama dengan /proc/$PID/ns/net.
Stéphane Chazelas
Apa? /run/netnsbahkan tidak ada di komputer saya.
Ken Sharp
/run/netnsatau di mana pun ipmengikat mount file khusus namespace. findmnt -t nsfsdapat memberi tahu Anda di mana itu pada sistem Anda. OTOH, jika kamu melakukannya unshare -n sleep 1000 & ip netns identify "$!", kamu tidak akan mendapatkan apa-apa.
Stéphane Chazelas
findmnt -t nsfs- tidak ada. unshare -n sleep 1000 & ip netns identify "$!"- unshare: unshare gagal: Operasi tidak diizinkan
Ken Sharp
Anda perlu hak superuser (kapabilitas CAP_SYS_ADMIN) untuk membuat jaringan baru. findmnt -t nsfsmengembalikan apa pun menunjukkan bahwa Anda tidak memiliki jaring di ATM mesin Anda.
Stéphane Chazelas
9

pskini memiliki pilihan output untuk berbagai jenis ruang nama yang terkait dengan proses: ipcns, mntns, netns, pidns, userns, dan utsns. Untuk pertanyaan ini, yang relevan adalah namespace PID, atau pidns.

jadi jika Anda ingin mengetahui id namespace PID untuk, misalnya, pid 459:

# ps -h -o pidns -p 459
4026532661

dan untuk membuat daftar semua proses di namespace itu:

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

atau dengan pgrep, Anda bisa langsung dari PID ke daftar semua proses berbagi yang namespace PID yang sama:

pgrep -a --ns 459

Tidak seperti ps, pgrepdapat membatasi output ke namespace tertentu (jika Anda tahu PID dari salah satu proses di dalamnya), tetapi memiliki kemampuan format output yang sangat terbatas (hanya PID, atau PID dan baris perintah mereka)

Anda selalu dapat menyalurkan output pgrep --ns 459ke xargs ps -fmeskipun untuk mengambil informasi yang Anda butuhkan tentang proses.

cas
sumber
0

Namespace-Lister :

Anda dapat menggunakan listns.py

Penggunaan: ./listns.pyatau python2 listns.pyUntuk menjawab pertanyaan ini dengan tepat, Anda dapat menangkap hasilnya seperti inipython2 listns.py | grep $PID (ganti variabel pid)

Sumber: github-mirror dan artikel semua kredit untuk Ralf Trezeciak

Ruang nama jaringan :

Untuk namespace jaringan, ip netns identify $PIDbisa digunakan.

Nsutils

Berikan pidnslistyang mengembalikan namespace pid dari suatu proses

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