匿名网络命名空间

匿名网络命名空间

太长了;博士Linux 有命名空间,特别是network namespaces.似乎-n在运行时通过标志创建的命名空间systemd-nspwawn在使用时不会显示ip netns list(无论是在主机中还是在假定创建的命名空间中)。它要么实际处理 Linux 命名空间,systemd-nspawn要么ip netns不处理 Linux 命名空间(我认为是这样的:https://lwn.net/Articles/531114/#series_index)?

更长的故事:
我使用以下命令从我的 Arch Linux 中运行 Arch Linux 的“轻量级容器”:

systemd-nspawn -nbUD /mntpointArchLinuxSysFs

数据/mntpointArchLinuxSysFs已被引导,并且“运行/引导”良好。男人systemd-nspawn告诉我-n选项标志的含义是:

-n,--network-veth

veth在主机和容器之间创建虚拟以太网链路(“ ”)。以太网链路的主机端将作为网络接口使用,该网络接口以容器名称(由 指定 --machine=)命名,前缀为“ ve-”。以太网链路的容器端将被命名为“ host0”。该--network-veth选项意味着 --private-network.

反过来,隐含的--private-network解释是这样的

--private-network

Disconnect networking of the container from the host. This makes all network interfaces unavailable in the container, with the

环回设备以及 --network-interface=用 指定和配置的设备除外--network-veth。如果指定此选项,则该CAP_NET_ADMIN功能将添加到容器保留的功能集中。后者可以通过使用 来禁用--drop-capability=。如果未指定此选项(或由下面列出的选项之一暗示),容器将具有对主机网络的完全访问权限。

这似乎是通过以下方式实现的壮举Linux 命名空间, 尤其Linux 网络命名空间,这表明启动的进程(即init容器的进程/mntpointArchLinuxSysFs/bin/init和所有子进程都位于不同的网络命名空间中,即并且--private-network仅具有veth(虚拟以太网对)作为与命名空间/系统的剩余连接host

使用LSNS表明确实systemd-nspawn创建了一个命名空间

root@host$> lsns | grep net
4026531992 net       183     1 root     /sbin/init
4026532332 net         1   824 rtkit    /usr/lib/rtkit-daemon
4026532406 net         7  4697 vu-mnt-0 /usr/lib/systemd/systemd

ip netns list拒绝“配合”:

root@host$> ip netns list
root@host$>

然后,为了理解,我是通过ip netns这样创建一个虚拟名称空间

root@host$> ip netns add dummy_netns
root@host$> ip netns list
dummy_netns
root@host$>

然而,讽刺的是,网络命名空间在lsns.

总之,似乎不清楚术语“网络命名空间”是如何在 中使用的systemd-nspawnip netns因为我的测试似乎表明它们可能并不是真正的同一件事?也许这个词有歧义?

更新

手册页的这一部分systemd-nspawn表明恕我直言,但是实际上两者都iproutesystemd-nspawn的是同一件事网络命名空间

--network-namespace-path= 获取表示容器应在其中运行的内核网络命名空间的文件的路径。指定的路径应引用(可能是绑定安装的)网络命名空间文件,如下面的内核所公开的/proc/$PID/ns/net。这使得容器进入给定的网络命名空间。典型的用例之一是给出/run/netns由 所创建的网络命名空间ip-netns(8),例如--network-namespace-path=/run/netns/foo。请注意,此选项不能与其他网络相关选项一起使用,例如 --private-network 或 --network-interface=。

尽管最后一部分指出它不能--private-network再次与该选项一起使用似乎暗示了某种区别。这里发生了什么?

答案1

两者systemd-nspawnip-netns使用命名空间,特别是网络命名空间。差异,如中所解释的ip-netns 手册,是ip-netns处理命名的网络命名空间。

按照惯例,命名网络命名空间是一个/var/run/netns/NAME可以打开的对象。打开后产生的文件描述符/var/run/netns/NAME引用指定的网络命名空间。保持文件描述符打开可以使网络命名空间保持活动状态。

匿名网络命名空间

命名空间(7) 手册解释说,一般来说,命名空间是与其中进程的生命周期相关的抽象:

每个进程都有一个/proc/[pid]/ns/子目录,其中包含每个命名空间的一个条目,支持通过setns(2)...打开此目录中的文件之一(或绑定安装到这些文件之一的文件)会返回相应命名空间的文件句柄pid指定的进程。只要此文件描述符保持打开状态,命名空间就会保持活动状态,即使命名空间中的所有进程都终止也是如此。

在我的系统上,最近启动的systemd进程 ( pgrep -f -n systemd\$) 是使用默认模板单元启动的容器的 init 进程[email protected],它启用--network-veth,因此--private-network(它还添加--private-users)。此命令显示容器的匿名网络命名空间与根网络命名空间不同,并且由容器的根用户拥有:

# ls -l /proc/1/ns/net /proc/$(pgrep -f -n systemd\$)/ns/net
lrwxrwxrwx 0 root           /proc/1/ns/net -> net:[4026532008]
lrwxrwxrwx 0 vu-container-0 /proc/700/ns/net -> net:[4026532656]

当容器终止时,这个匿名网络命名空间就会消失。但是,如果我想让它成为一个可以ip-netns在容器生命周期内进行管理的命名网络命名空间,我可以将其绑定挂载在以下位置/run/netns

# mount --bind /proc/$(pgrep -f -n systemd\$)/ns/net /run/netns/container
# ip netns list
container (id: 1)

使用 systemd 创建命名网络名称空间

您还指出了systemd-nspawn--network-namespace-path选项,这相当于NetworkNamespacePath=中记录的设置系统单元(5)。它只能将容器和单元分配给已存在的网络命名空间。由于进程只能位于一个命名空间中,因此与创建匿名网络命名空间并隔离其中的容器--network-namespace-path等选项不兼容。--private-network

看起来systemd 将获得一个Namespace=设置在 v246 之后的某些未来版本的 systemd 中(v245 于 2020 年 3 月发布)。这将允许单元创建自己的命名网络命名空间,而不是使用 分配给现有命名空间NetworkNamespacePath=或创建新的匿名命名空间PrivateNetwork=。合并此功能后,将其Namespace=%i添加到[email protected]模板中是有意义的,以便默认命名容器的网络命名空间。

相关内容