如何找出特定进程的命名空间?

zer*_*iel 33 linux process namespace

我已经问过一个关于如何在 Linux 中列出所有命名空间的问题,但是没有任何正确和准确的答案,所以我想找到一种方法可以帮助我找出某个进程或组的 PID 的命名空间过程。如何在 Linux 中完成?

Sté*_*las 46

我会尝试回答这个问题你之前的问题,因为它们是相关的。

命名空间的大门是/proc/*/ns/*和中的文件/proc/*/task/*/ns/*

命名空间是由进程取消共享其命名空间创建的。命名空间然后可通过永久绑定安装ns文件到其他地方。

ip netns例如,这就是网络命名空间的作用。它取消共享其net命名空间并绑定挂载/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]
Run Code Online (Sandbox Code Playgroud)

方括号中的数字是 inode 编号。

要为给定的过程获得它:

# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Run Code Online (Sandbox Code Playgroud)

现在,可能存在没有任何进程的永久命名空间。找出它们可能会更加棘手 AFAICT。

首先,您必须记住,可以有多个挂载命名空间。

# 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
Run Code Online (Sandbox Code Playgroud)

那些/mnt/1/a,/run/netns/a可能是命名空间文件。

我们可以得到一个 inode 编号:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
Run Code Online (Sandbox Code Playgroud)

但这并没有告诉我们什么,除了它不在上面计算的列表中。

我们可以尝试将其输入为任何不同类型:

# 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
#
Run Code Online (Sandbox Code Playgroud)

好的,那是一个net命名空间文件。

因此,我们似乎有一种列出名称空间的方法:列出ns所有任务的目录,然后在所有任务中找到所有proc挂载点,/proc/*/task/*/mountinfo并通过尝试输入它们来找出它们的类型。


Rfr*_*ile 25

如果你有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
Run Code Online (Sandbox Code Playgroud)

更正: lsns 在 util-linux v2.27 中不可用,因为这个答案曾经说过。请参阅https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

  • `lsns` 非常有用,但它只显示每个命名空间中最低的 PID - 即它不能告诉您任何任意 PID 的命名空间。无论如何+1,因为即使它没有直接回答问题,这仍然是一个有用的答案。 (2认同)

cas*_*cas 15

ps现在具有用于与过程相关联的不同类型的命名空间的输出选择:ipcnsmntnsnetnspidnsuserns,和utsns。对于这个问题,相关的是 PID 命名空间,或pidns.

因此,如果您想找出 PID 命名空间 ID,例如 pid 459:

# ps -h -o pidns -p 459
4026532661
Run Code Online (Sandbox Code Playgroud)

并列出该命名空间中的所有进程:

ps -o pidns,pid,cmd | awk '$1==4026532661'
Run Code Online (Sandbox Code Playgroud)

或者使用pgrep,您可以直接从 PID 转到共享同一 PID 命名空间的所有进程的列表:

pgrep -a --ns 459
Run Code Online (Sandbox Code Playgroud)

与 不同pspgrep可以将输出限制为特定的命名空间(如果您知道其中一个进程的 PID),但具有非常有限的输出格式化功能(仅限 PID,或 PID 及其命令行)

您始终可以通过管道pgrep --ns 459传递xargs ps -fto的输出来检索您需要的有关该过程的信息。


Ken*_*arp 10

$ ip netns identify $PID
Run Code Online (Sandbox Code Playgroud)

$PID进程的 ID在哪里,可以通过多种方式获取。

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

  • 请注意,它仅适用于网络命名空间,并且仅适用于使用 `ip netns` 创建的命名空间(或至少由像 `ip netns` 那样在 /run/netns 中绑定安装命名空间门的东西创建)。它基本上在 /run/netns 中查找与 `/proc/$PID/ns/net` 相同的文件。 (2认同)