如何在 Docker 容器镜像中创建 tun 接口?

moo*_*f2k 5 mknod tun docker dockerfile

我正在尝试使用/dev/net/tun设备创建 Docker 映像,以便可以在 Linux、Mac 和 Windows 主机上使用该映像。设备不需要访问主机的网络接口。

请注意,传递--device /dev/net/tun:/dev/net/tuntodocker run是不可取的,因为这仅适用于 Linux。

容器启动后,我可以通过运行手动添加设备:

$ sudo mkdir /dev/net
$ sudo mknod /dev/net/tun c 10 200
$ sudo ip tuntap add mode tap tap
Run Code Online (Sandbox Code Playgroud)

但是当我将这些行添加到 Dockerfile 时,它​​会导致错误:

Step 35/46 : RUN mkdir /dev/net
 ---> Running in 5475f2e4b778
Removing intermediate container 5475f2e4b778
 ---> c6f8e2998e1a
Step 36/46 : RUN mknod /dev/net/tun c 10 200
 ---> Running in fdb0ed813cdb
mknod: /dev/net/tun: No such file or directory
The command '/bin/sh -c mknod /dev/net/tun c 10 200' returned a non-zero code: 1
Run Code Online (Sandbox Code Playgroud)

我相信这里的关键是从一个docker build步骤中创建一个文件系统节点?这可能吗?

moo*_*f2k 2

我设法通过在需要它的软件中以编程方式创建 TUN 设备(主要是单元测试)来解决这个问题。在程序的设置中,我们可以创建一个主/次代码为 10/200 的临时文件节点:

        // Create a random temporary filename. We are not using tmpfile() or the
        // usual suspects because we need to create the temp file using mknod(),
        // below.
        snprintf(tmp_filename_, IFNAMSIZ, "/tmp/ect_%d_%d", rand(), rand());

        // Create a temporary file node for use as a TUN interface.
        // Device 10, 200 is the device code for a TAP/TUN device.
        // See https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
        int result = mknod(tmp_filename_, S_IFCHR | 0644, makedev(10, 200));
        if (result < 0) {
            perror("Failed to make temporary file");
        }
        ASSERT_GE(result, 0);
Run Code Online (Sandbox Code Playgroud)

然后在程序的拆卸中我们关闭并删除临时文件。

剩下的一个问题是该程序仅在以 root 用户身份运行时才有效,因为该程序没有cap_net_admin,cap_net_raw功能。另一个可以解决的烦恼。