web-dev-qa-db-ja.com

Dockerとのデバイス(ウェブカメラ、USBドライブなど)の共有

ホストLinuxマシン上の/devの特定のデバイスをdockerコンテナと共有する必要があります。

--privilegedフラグは、/devが呼び出されたときに存在するdocker run内のデバイスを共有するために機能しますが、その後追加または削除されたデバイスはコンテナーに伝播しません。

docker run -v=/dev:/dev ...を試してみましたが、/ dev/ptsなどのファイルのアクセス権と所有権が台無しになり、ホストマシンが新しい擬似端末を作成できなくなりました。

--deviceフラグも試しましたが、まだ存在しないデバイスを共有することはできません。

最後に、-v=/dev/video0:/dev/video0などのデバイスのボリュームを共有しようとしましたが、実行前に/ dev/video0が存在しない場合、dockerはそこにディレクトリを作成し、Webカメラはプラグイン時に/ dev/video0を取得しません。

このサポートされている機能を取得するより良い方法はありますか?

24
Ryan

フラグ--device

   --device=[]
      Add a Host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)

ごきげんよう!

14
Auzias

理論的には、これは--privilegedフラグ。これにより、すべてのホストデバイスにアクセスできるようになります。 usbutilsなどを(イメージの配布に応じて)インストールすると、lsusbの実行時に特権コンテナがホットプラグされたデバイスを見ることができることがわかります。残念ながら、/ devの下には表示されません。これらの記述子の作成をスクリプト化し、/ devの下のソフトウェアで適切に処理させると、残念ながらかなり複雑になる可能性があります。ただし、デバイスでそのようにする必要はありません。

最初の試みとしてできることは、mknodを使用してそれらを作成することです。私はHTC電話でこれを試してみましたが、うまくいきました(詳細はここでは関係ありません)、単にlsusbのホットプラグされたデバイスの行を確認してください:

Bus 003 Device 002: ID 0bb4:0f25 HTC (High Tech Computer Corp.) One M8

記述子の正しいフォルダーに移動します。

cd /dev/bus/usb/003

既存の記述子からカーネルのusbドライバーのメジャーバージョンを確認します。

root@1a11f7c329a9:/dev/bus/usb/003# ls -la
total 0
drwxr-xr-x 2 root root      160 Dec 26 13:40 .
drwxr-xr-x 6 root root      120 Dec 26 13:30 ..
crw-rw-r-- 1 root root 189, 256 Dec 26 13:30 001
crw-rw-r-- 1 root root 189, 258 Dec 26 13:30 003
crw-rw-r-- 1 root root 189, 259 Dec 26 13:30 004
crw-rw-r-- 1 root root 189, 260 Dec 26 13:30 005
crw-rw-r-- 1 root root 189, 261 Dec 26 13:30 006

=> 189 :) => nodを作成し、その間にマイナーバージョン0を使用します。

mknod 002 c 189 0

=>少なくともlsusb -vは、デバイスを開くことができるようになりました。いくつかの例外を除いて、ほとんどのハードウェアimoでも同じように動作します。

Dockerとコンテナー化の精神では、おそらくより遅いが確かに安全でありますが、代替手段としてできることは、デバイスをホットマウントし、ビデオアプリを実行しているメインコンテナーとデバイスを共有するときにコンテナーにアクセスすることですtcp経由のsocat tty経由。

ホストで/ dev/video0をホットプラグすると、そのイベントでこのデバイスがマウントされている新しいコンテナーを起動できます。このコンテナ(socatがインストールされている)は実行できます:

socat tcp-l:54321,reuseaddr,fork file:/dev/video0,nonblock,waitlock=/var/run/video0.lock

このもののホスト名がvideo0-serverであると仮定すると、次の方法でクライアントでvideo0の記述子を作成できます。

socat pty,link=/dev/video0,waitslave tcp:video0-server:54321

これで、デバイスを問題なく使用できるはずです。多くのデバイスでは、socatのオーバーヘッドは問題になりません。ネットワーク経由でメインコンテナと動的に通信する複数のコンテナを使用してこれをスクリプト化することがオプションであり、パフォーマンスがオーバーヘッドによって意味のある方法で影響を受けない場合、後者のオプションは--privileged私の意見ではモード。

10
Armin Braun

システムの実行中にデバイスを配置することは困難です(USB検出)。検出されたデバイスを配置するスクリプトを作成し、-rmを実行する必要があります(したがって、マシンを終了するたびに削除され、デバイスをインポートする新しい機会)

0