我使用的是 Ubuntu 12.04,该ip
实用程序没有ip netns identify <pid>
选项,我尝试安装新的iproute
,但仍然有该选项确认似乎不起作用!
如果我要编写一个脚本(或代码)来列出网络命名空间中的所有进程,或者给定 PID,显示它属于哪个网络命名空间,我应该如何进行? (我需要一些进程的信息,以检查它们是否正确netns
)
答案1
你可以这样做:
netns=myns
find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/"$netns" | cut -d/ -f5
或者与zsh
:
print -l /proc/[1-9]*/task/*/ns/net(e:'[ $REPLY -ef /run/netns/$netns ]'::h:h:t)
它检查符号链接指向的文件的索引节点与in/proc/*/task/*/ns/net
绑定安装的文件的索引节点。基本上就是这样或ip netns add
/run/netns
ip netns identify
ip netns pid
在新版本的iproute2
do 中。
这适用于linux-image-generic-lts-trusty
Ubuntu 12.04 上的软件包中的 3.13 内核,但不适用于 12.04 第一个版本中的 3.2 内核,其中/proc/*/ns/*
没有符号链接,并且net
每个进程和任务中的每个文件都会获得不同的索引节点,这无法帮助确定命名空间会员资格。
对此的支持由那个承诺2011 年,这意味着您需要内核 3.8 或更高版本。
对于较旧的内核,您可以尝试运行一个程序,侦听命名空间中的抽象套接字,然后尝试输入每个进程的命名空间,看看是否可以连接到该套接字,如下所示:
sudo ip netns exec "$netns" socat abstract-listen:test-ns,fork /dev/null &
ps -eopid= |
while read p; do
nsenter -n"/proc/$p/ns/net" socat -u abstract:test-ns - 2> /dev/null &&
echo "$p"
done
答案2
ps $(ip netns pids myns)
myns
你的命名空间在 哪里
答案3
这个问题特别提到了 Ubuntu 12.04,但我注意到,在 16.04 这样的较新发行版上,有一个命令可以执行此操作:ip netns pids <nsname>
答案4
当在容器内部而不是外部运行时,我发现 -samefile 技巧遗憾地不起作用。不知道为什么,因为它是同一个索引节点。不管怎样,这确实有效,以防万一它对任何人有用:
netns=mynamespace
inode=$(ls -i /var/run/netns/$netns | cut -f1 -d" ")
pids=$(find -L /proc/[1-9]*/task/*/ns/net -inum $inode | cut -f3 -d"/" | uniq)
ps -p $pids