太长了;博士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-nspawn
,ip netns
因为我的测试似乎表明它们可能并不是真正的同一件事?也许这个词有歧义?
更新
手册页的这一部分systemd-nspawn
表明恕我直言,但是实际上两者都iproute
指systemd-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-nspawn
和ip-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]
模板中是有意义的,以便默认命名容器的网络命名空间。