web-dev-qa-db-ja.com

Dockerコンテナイメージ内にtunインターフェースを作成するにはどうすればよいですか?

Linux、Mac、Windowsホストマシンでイメージを使用できるように、/dev/net/tunデバイスでDockerイメージを作成しようとしています。デバイスはホストのネットワークインターフェイスにアクセスする必要はありません。

--device /dev/net/tun:/dev/net/tundocker 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ステップ内からファイルシステムノードを作成していると思いますか?これは可能ですか?

4
moof2k

私は、それを必要とするソフトウェアで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);

次に、プログラムのティアダウンで一時ファイルを閉じて削除します。

残っている問題の1つは、このプログラムにはcap_net_admin,cap_net_raw機能。回避できるもう1つの問題。

1
moof2k

/devディレクトリは特別であり、Dockerのビルドステップでは実際に何も置くことができません。 質問56346114への回答 にも記載されています。

どうやら/devのデバイスは、データが入っているファイルではなく、プレースホルダー、アドレス、ポインター、アクセスされたときに何かを実行するメモリ内のドライバーコードへのリンクです。メモリ内のそのようなドライバーコードは、Dockerイメージが保持するものではありません。

実際に実行したいアプリをラップする.shスクリプトにコマンドラインコードを配置することで、コンテナーでデバイスを作成しました。

0
codelion