วิธีค้นหาเนมสเปซของกระบวนการเฉพาะ


25

ฉันได้ถามคำถามเกี่ยวกับวิธีการแสดงรายการ namespaces ทั้งหมดใน Linuxแต่ไม่มีคำตอบที่ถูกต้องและแน่นอนดังนั้นฉันต้องการค้นหาวิธีที่สามารถช่วยฉันค้นหา namespace ของ PID ของกระบวนการหรือกลุ่มของ กระบวนการ จะทำอย่างไรใน Linux?

คำตอบ:


39

ฉันจะลองตอบคำถามทั้งสองนี้และคำถามก่อนหน้าของคุณเนื่องจากพวกเขาเกี่ยวข้องกัน

ประตู namespaces เป็นไฟล์ในและ/proc/*/ns/*/proc/*/task/*/ns/*

เนมสเปซถูกสร้างขึ้นโดยกระบวนการที่ไม่เปิดเผยฮับสเปซ namespace นั้นจะสามารถทำให้ถาวรโดยผูกติดnsไฟล์บางสถานที่อื่น ๆ

นั่นคือสิ่งที่ip netnsจะทำเช่นสำหรับเนมสเปซสุทธิ มัน unshares ของnetnamespace และผูกม้าไป/proc/self/ns/net/run/netns/netns-name

ใน/procเมาท์ในเนมสเปซ pid รูทคุณสามารถแสดงรายการเนมสเปซทั้งหมดที่มีกระบวนการในรูมได้โดยทำดังนี้

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

ตัวเลขในวงเล็บเหลี่ยมคือหมายเลขไอโหนด

เพื่อรับสิ่งนั้นสำหรับกระบวนการที่กำหนด:

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

ตอนนี้อาจมีเนมสเปซถาวรที่ไม่มีกระบวนการใด ๆ ในพวกเขา การค้นหาพวกเขาออกมาอาจเป็นเรื่องที่ยุ่งยากมาก

ก่อนอื่นคุณต้องจำไว้ว่าอาจมีเนมสเปซเมานต์หลายรายการ

# 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

บรรดา/mnt/1/a, /run/netns/aอาจจะเป็นไฟล์ namespace

เราสามารถรับหมายเลขไอโหนด:

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

แต่นั่นไม่ได้บอกอะไรเรามากไปกว่ามันไม่ได้อยู่ในรายการที่คำนวณข้างต้น

เราสามารถลองและป้อนเป็นประเภทต่างๆ:

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

ตกลงนั่นคือnetไฟล์เนมสเปซ

ดังนั้นดูเหมือนว่าเรามีวิธีการในการแสดงรายการชื่อพื้นที่: รายการnsไดเรกทอรีของงานทั้งหมดจากนั้นหาprocจุดเมานท์ทั้งหมดในทั้งหมด/proc/*/task/*/mountinfoและหาประเภทของพวกเขาโดยพยายามป้อน


19

หากคุณมีutil-linux v2.28 ขึ้นไปคุณสามารถใช้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

การแก้ไข: lsns ไม่สามารถใช้ได้ใน util-linux v2.27 ตามคำตอบนี้ ดูhttps://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes


นอกจากนี้ยังมีสคริปต์ python ที่ดีที่ฉันพบสำหรับผู้ใช้บน linux รุ่นเก่า opencloudblog.com/?p=251
Neil McGill

lsnsมีประโยชน์มาก แต่จะแสดง PID ที่ต่ำที่สุดในแต่ละเนมสเปซ - เช่นไม่สามารถบอกเนมสเปซสำหรับ PID ที่กำหนดเองได้ +1 อยู่ดีเพราะนี่ยังเป็นคำตอบที่มีประโยชน์แม้ว่าจะไม่ได้ตอบคำถามโดยตรง
cas

9
$ ip netns identify $PID

โดยที่$PIDเป็น ID กระบวนการของกระบวนการซึ่งคุณสามารถรับได้หลายวิธี

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


1
โปรดทราบว่ามันเป็นเพียงสำหรับเนมสเปซเครือข่ายและมีเพียงรายการที่สร้างขึ้นโดยใช้ip netns(หรืออย่างน้อยสร้างโดยบางสิ่งที่ผูกติดกับเนมสเปซประตูใน / run / netns เช่นip netnsนั้น) มันเป็นพื้นในลักษณะ / วิ่ง / netns /proc/$PID/ns/netสำหรับไฟล์ที่เป็นเช่นเดียวกับ
Stéphane Chazelas

อะไร? /run/netnsไม่มีแม้แต่ในคอมพิวเตอร์ของฉัน
Ken Sharp

/run/netnsหรือที่ใดก็ตามที่ipเชื่อมโยงไฟล์พิเศษเนมสเปซ findmnt -t nsfsอาจบอกคุณว่ามันอยู่ในระบบของคุณ OTOH ถ้าคุณทำunshare -n sleep 1000 & ip netns identify "$!"คุณจะไม่ได้อะไรเลย
Stéphane Chazelas

findmnt -t nsfs- ไม่มีอะไร unshare -n sleep 1000 & ip netns identify "$!"- ยกเลิกการแชร์: ยกเลิกการแชร์ไม่สำเร็จ: ไม่อนุญาตให้ใช้งาน
Ken Sharp

คุณต้องมีสิทธิ์ผู้ใช้ขั้นสูง (ความสามารถ CAP_SYS_ADMIN) เพื่อสร้าง netns ใหม่ findmnt -t nsfsไม่มีอะไรส่งกลับแสดงให้เห็นว่าคุณไม่มีเน็ตบนเครื่อง ATM ของคุณ
Stéphane Chazelas

9

psตอนนี้มีตัวเลือกออกสำหรับชนิดที่แตกต่างกันของ namespaces ที่เกี่ยวข้องกับกระบวนการ: ipcns, mntns, netns, pidns, และuserns utsnsสำหรับคำถามนี้อย่างใดอย่างหนึ่งที่เกี่ยวข้องคือ namespace PID pidnsหรือ

ดังนั้นหากคุณต้องการค้นหา PID namespace id สำหรับเช่น pid 459:

# ps -h -o pidns -p 459
4026532661

และเพื่อแสดงรายการกระบวนการทั้งหมดในเนมสเปซนั้น:

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

หรือด้วยpgrep, คุณสามารถไปจาก PID โดยตรงไปยังรายการกระบวนการทั้งหมดที่แชร์เนมสเปซ PID เดียวกัน:

pgrep -a --ns 459

ซึ่งแตกต่างps, pgrepสามารถ จำกัด การส่งออกไปยัง namespace เฉพาะ (ถ้าคุณรู้ว่า PID หนึ่งของกระบวนการในนั้น) แต่มีการจัดรูปแบบการส่งออกความสามารถที่ จำกัด มาก (PIDs เท่านั้นหรือ PIDs และบรรทัดคำสั่งของพวกเขา)

คุณสามารถไพพ์เอาต์พุตของpgrep --ns 459ถึงxargs ps -fแม้ว่าเพื่อดึงข้อมูลที่คุณต้องการเกี่ยวกับกระบวนการ


0

Namespace-Lister :

คุณสามารถใช้listns.py

การใช้งาน: ./listns.pyหรือpython2 listns.pyเพื่อตอบคำถามนี้อย่างแม่นยำคุณสามารถ grep ผลลัพธ์เช่นนี้python2 listns.py | grep $PID(แทนที่ตัวแปร pid)

ที่มา: github-mirrorและบทความมอบ เครดิตให้กับRalf Trezeciak

เนมสเปซเครือข่าย :

สำหรับเนมสเปซเครือข่ายip netns identify $PIDสามารถใช้ได้

Nsutils

จัดเตรียมpidnslistที่ส่งคืน pid เนมสเปซของกระบวนการ

$ pidnslist -ss 8782
pid:[4026531836] 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.