我有一个Linux进程,它在没有在/run/netns中注册的情况下创建了一个网络命名空间。该进程还拥有自己的PID命名空间。网络命名空间没有名称,我只能看到名称空间的id:
# ip netns list-id
nsid 0
nsid 1是否有可能为网络命名空间指定名称,以便我可以使用方便的ip命令来显示和管理名称空间?
我找到了一篇文章如何访问未命名的网络命名空间,但它对我不起作用,因为我的进程有自己的PID命名空间,所以我看不到根命名空间中的进程。
发布于 2021-04-19 16:22:45
在名称空间的低级处理中不存在实际名称。所有这些都是由iproute2套件中的每个命令所做的共同操作或期望来处理的。
为现有的匿名网络命名空间分配名称确实意味着:让iproute2工具相信它们在创建此网络命名空间时做了通常的设置。
那么,ip netns add foo到底在做什么呢?它将共享到一个新的网络命名空间,并且为了保持这个名称空间存在,即使没有进程使用它,也要挂载它。在通常的*nix哲学中,名称空间有一个inode号,表示伪文件系统nsfs中的伪文件。几乎不能对文件执行任何操作(甚至不能读取它),但是可以打开它作为命名空间操作的标记(例如setns(2)),也可以作为绑定挂载安装。
唉,链接nsid是不可直接使用的:它不是一个表示其他名称空间的全局值,而是一个本地的(本地唯一的,但可回收的,而不是全局唯一的) ID,它代表到另一个名称空间的链接。多个值意味着:指向多个其他名称空间的链接,两次相同的值意味着:指向同一个其他名称空间的两个链接。
如果您必须找到仅从此开始的其他名称空间,我请您检查我在另一个问答中的回答的答案。还有一个方便的映射工具:plotnetcfg,它可以映射所有的网络命名空间。虽然它确实知道iproute2方法,但它似乎并没有单独给出一个进程id,而是在它没有被iproute2“命名”时从它命名一个带有PID的命名空间。编辑后的示例(需要jq),以根用户身份运行:
# unshare -n -- sleep 999 &
[1] 677451
# plotnetcfg -f json | jq '.namespaces[].name'
""
[...]
"PID 268150 (systemd)"
"PID 345878 (systemd)"
[...]
"PID 677451 (sleep)"在这里,""表示初始命名空间,两个systemd来自两个LXC实例,sleep命令也在运行。
为解决两种常见情况提供帮助:
一旦您通过任何方法在预期的网络命名空间中找到一个可用的进程,您就可以模仿iproute2工具所做的事情。他们到底做了什么可能取决于他们的确切版本。从strace矿场看来是这样的:
mkdir -p /run/netns然后将其挂载到自己上,以便将其设置为共享传播:
mount --bind --make-shared /run/netns /run/netns以上只应做如果没有做,只有一次。若要让工具为您执行此操作(仅在需要时),只需创建和删除一个虚拟命名空间:
ip netns add dummy && ip netns delete dummy现在选择一个名称,例如foo,创建一个空文件并将其模式更改为1000(这不是必需的,而是模拟iproute2):
touch /run/netns/foo
chmod 0 /run/netns/foo最后,根据进程的PID (例如以前的sleep:677451)挂载进程的命名空间:
mount --bind /proc/677451/ns/net /run/netns/foo就这样。即使sleep命令结束,命名空间现在仍然存在。现在所有的iproute2工具都将它命名为foo。例如,如果有一个veth接口连接到它,ip link将用foo替换链接nsid的编号。
如果您想要删除这个网络名称空间,ip netns del foo现在将这样做(注意:与往常一样,一旦不再使用它的资源,实际的网络名称空间就会消失,比如这个睡眠命令)。
关于iucute2‘S的进一步文档,我的其他答案中网络命名空间的特定附加特性。
https://unix.stackexchange.com/questions/633919
复制相似问题