容器有网络接口但主机没有,如何将eth0暴露给容器

容器有网络接口但主机没有,如何将eth0暴露给容器

我正在构建一个带有只读 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 描述一些用例。

答案2

详细阐述弗罗斯特舒茨的评论。

  • 您可以按照此处的说明允许容器在有或没有 --privileged 模式的情况下访问 USB 设备:指示(但是,由于这是一个网络设备,它很可能需要驱动程序)

  • 如果您使用 USB 直通,并且可以看到容器内的设备,那么只需在容器内对该设备的内核模块执行 modprobe,然后重新启动容器即可。然后当然是设置网络。

  • 当适合您的用例时,下页讨论中找到的信息应该会对您有所帮助。 (请记住,关于它的最后一个声明没有在全新启动时显示,是因为它尚未设置为这样做,但您应该从那里获得它,因为驱动程序现在应该可以工作。)

相关内容