我正在构建一个带有只读 rootfs 的系统。
该 rootfs 在主机和创建的容器之间共享。
主机不能有任何网络相关的服务或文件,这意味着我无法桥接主机连接。
我目前正在使用 USB 网络适配器。
如何仅启动该设备和容器内的网络服务?
任何容器都可以为 /etc /var 等设置新的 RW 挂载点,这样,所需的任何文件都可以在另一个分区中访问。但主机仍然是 RO 并且文件有限。
答案1
忘记网卡作为一个特定的硬件。假设您有一个网络接口,并且必须将其移动到容器中。这不是 USB 或 PCI 直通。我们称之为接口传递,它是由网络命名空间逻辑例如使用ip link
:
网络网络名称|PID
将设备移动到与 name 关联的网络命名空间网络名称或过程PID。有些设备不允许更改网络命名空间:环回、桥接、ppp、无线。这些是网络命名空间本地设备。在这种情况下,ip 工具将返回“无效参数”错误。可以通过检查来查明设备是否位于单个网络名称空间的本地
netns-local
输出中的标志ethtool
:ethtool -k DEVICE
要更改无线设备的网络命名空间
iw
可以使用工具。但它只允许更改物理设备和进程的网络命名空间PID。
该界面最初必须出现在主机上,但您可以将其移动到容器中。没有选项可以让它在插入时直接出现在容器中(当然在容器启动时,通过容器的特定配置,可以移动界面,见下文),但它可能可以使用udev
.此外,内核在主机和容器之间是唯一的,即使根本不使用网络,主机当然也必须编译所有必需的网络选项,并且仍然负责在需要时加载相关的内核模块(通常是透明完成的) )。
因此,如果最终您的卡eth0
在主机上被调用并且确实是以太网(不是无线),则此命令会将其移动到目标命名空间:
ip link set eth0 netns NETNSNAME
其中 NETNSNAME 可以是目标网络命名空间中进程的 pid,也可以是“安装”并由其处理的网络命名空间,ip netns add NETNSNAME
如上所述。
对于两种常见的容器技术 LXC 和 Docker,以下是如何将 NETNSNAME 替换为名为 的目标容器containername
:
LXC:
ip link set eth0 netns $(lxc-info -H -p -n containername)
码头工人:
ip link set eth0 netns $(docker inspect --format '{{.State.Pid}}' containername)
对于无线,(没有很好的记录)命令将是如果只有一个无线接口,则明确与以下相关联phy0
:
iw phy phy0 set netns $(lxc-info -H -p -n containername)
但这只有在驱动程序支持的情况下才有效,显示如下:
# iw phy0 info|grep netns
* set_wiphy_netns
这大概应该是不能手动完成使用上面的命令,但使用特定容器的配置(LXC、Docker...)。例如,对于 LXC 3.0(语法从 LXC 2.x 更改),配置文件将包含以下行:
lxc.net.1.type = phys
lxc.net.1.link = eth0
相同的配置将处理以太网或无线。
并且每当容器启动时,该接口就会被容器吞掉。当容器(更准确地说是其网络命名空间)停止时,接口将返回到主机(无法直接将其返回到其他容器)。
Wireguard 描述一些用例。