Как создать интерфейс Tun внутри образа контейнера Docker? - PullRequest
1 голос
/ 23 декабря 2019

Я пытаюсь создать образ Docker с устройством /dev/net/tun, чтобы его можно было использовать на хостах Linux, Mac и Windows. Устройство не нуждается в доступе к сетевому интерфейсу хоста.

Обратите внимание, что передача --device /dev/net/tun:/dev/net/tun в docker run нежелательна, поскольку это работает только в Linux.

После запуска контейнера яможно вручную добавить устройство, запустив:

$ sudo mkdir /dev/net
$ sudo mknod /dev/net/tun c 10 200
$ sudo ip tuntap add mode tap tap

, но когда я добавляю эти строки в 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

Я считаю, что суть здесь заключается в создании файловой системыузел из шага docker build? Это возможно?

1 Ответ

0 голосов
/ 24 декабря 2019

Мне удалось обойти эту проблему, программно создав устройство 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);

, а затем в закрытой программе закрыть и удалить временный файл.

Осталась одна проблема: эта программа работает только при запуске от имени пользователя root, поскольку программа не имеет cap_net_admin,cap_net_raw возможностей. Еще одно раздражение, которое можно обойти.

...