Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

DockerコンテナからUSBデバイスを利用する(MacOS)

More than 1 year has passed since last update.

はじめに

Dockerゲスト(コンテナ)OSにLinuxを利用したい場合、DockerホストOSはLinuxでなければならない。その為、Docker for MacではmacOS上に仮想マシンを用意し、その上に軽量のLinuxOSを動作させる。

しかしデフォルトで用意されているハイパーバイザ(HyperKit)はホストOS(macOS/Windows)で認識しているUSBデバイスを認識させることができない。Dockerはこのハイパーバイザを変更することができるため、ホストOSのUSBデバイスを認識できるハイパーバイザであるVirtualBoxを利用してDockerコンテナにUSBデバイスを認識させる。

環境

以下の環境で検証した。

% vboxmanage --version
6.0.8r130520

% docker --version
Docker version 18.09.2, build 6247962

% docker-machine --version
docker-machine version 0.16.1, build cce350d7

概要

以下の手順でDockerコンテナにUSB機器を認識させる。

  1. VirtualBox+拡張パックインストール
  2. DockerホストOS用仮想マシン(DockerVM)作成
  3. DockerVMにUSBを認識させる為の設定追加
  4. DockerホストOSでUSBを認識していることを確認
  5. DockerコンテナOSで認識できていることを確認

1. VirtualBox+拡張パックインストール

以下のURLにアクセスし、最新のバイナリを取得、インストールする。

Downloads – Oracle VM VirtualBox

2019-06-12現在の最新は以下が最新。

  • VirtualBox 6.0.8 platform packages
  • VirtualBox 6.0.8 Oracle VM VirtualBox Extension Pack

2. DockerホストOS用仮想マシン(DockerVM)作成

DockerホストOS用仮想マシンをdocker-machineコマンドで作成する。

% docker-machine create -d virtualbox docker-host-default

3. DockerVMにUSBを認識させる為の設定追加

このセクションでは、手順を汎用的かつ簡略化するために、設定の1つである「USB Device Filter」に条件が空のフィルターを登録している。
このフィルターを登録することで、DockerホストOS側で全てのUSB機器を認識できる。

但し、使用しているPCで複数のUSBデバイスを利用している場合、USB機器を抜き差ししたタイミングなどでDockerホストOSに権限を奪われてしまうため、意図せずホストOS側でUSB機器が利用できなくなる。よって、環境に応じてフィルタは適切に設定することを推奨する。

フィルタに条件に設定する場合は、USB機器の情報(例えばVendorIdやProductId)を % vboxmanage list usbhost で確認する。macOSであれば % system_profiler SPUSBDataType でも確認できる。

vboxmanageコマンド (CLI) で設定

% docker-machine stop docker-host-default
Stopping "docker-host-default"...
Machine "docker-host-default" was stopped.

% vboxmanage modifyvm docker-host-default --usb on 
% vboxmanage modifyvm docker-host-default --usbehci on
% vboxmanage usbfilter add 0 --target docker-host-default --name 'All Devices'

% docker-machine start docker-host-default

VirtualBox Manager (GUI) で設定

  1. docker-machineコマンドでVMを停止する。
  2. VM(docker-host-default) > Settings > Ports > USB の設定画面で以下のチェックボックスを有効にする。
    • Enable USB Controller
    • USB 2.0 (EHCI) Controller
  3. 同画面の「USB Device Filters」の右の新規作成アイコンを押下し、条件が空のフィルターを作成する。
  4. フィルタが作成されたら、当該デバイスフィルタをダブルクリックし、名前を「All Devices」に変更する。
  5. docker-machineコマンドでVMを起動する。

4. DockerホストOSでUSBを認識していることを確認

% docker-machine ssh docker-host-default
   ( '>')
  /) TC (/   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-/)           www.tinycorelinux.net

docker@docker-host-default:~$ udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

※機器をPCに接続すると以下のようなメッセージが出力されることを確認する。
※例として接続したデバイスはUSBシリアル通信機器。

…
KERNEL[4332.894758] add      /devices/pci0000:00/0000:00:06.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial)
…
UDEV  [4332.897138] add      /devices/pci0000:00/0000:00:06.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial)
…
KERNEL[4332.910588] bind     /devices/pci0000:00/0000:00:06.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial)
…
UDEV  [4332.914260] bind     /devices/pci0000:00/0000:00:06.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial)
…

^C (確認できたらCtrl+Cでモニタリング終了)

接続が確認できたら、対応するデバイスファイルが存在することも確認し、ログアウトする。
複数のUSBシリアルデバイスを接続している場合は、ttyUSBXのXの部分の数字が異なる場合があるため注意する。

docker@docker-host-default:~$ ls -l /dev/ttyUSB0
crw-rw----    1 root     staff     188,   0 Jun 12 06:32 /dev/ttyUSB0

docker@docker-host-default:~$ exit
logout
%

5. DockerコンテナOSで認識できていることを確認

まずはじめに、dockerコマンドが先ほど作成したDockerVMを利用できるようにするために環境設定を行う。

DockerイメージやコンテナはDockerVM毎に別々に管理されているため、
このコマンドを忘れるとデフォルトのHyperkitを利用したDockerコンテナを起動することになるので注意する。

% eval $(docker-machine env docker-host-default)

続いて、DockerコンテナOSで確認するために適当なLinuxOSイメージを取得する。

% docker pull debian:9.9-slim
9.9-slim: Pulling from library/debian
fc7181108d40: Pull complete
Digest: sha256:9490c476443a3869e39c2897fa66c91daf5dcbbfca53c976dac7bbdc45775b28
Status: Downloaded newer image for debian:9.9-slim

USB機器を接続し、コンテナを起動する。

その際 --device でDockerホストOSが認識しているデバイスファイルをDockerコンテナOS上で読み書き可能にする。

% docker run --rm --device /dev/ttyUSB0 -it debian:9.9-slim /bin/bash
root@2a8988dafd77:/# ls -l /dev/ttyUSB0
crw-rw---- 1 root staff 188, 0 Jun 12 05:46 /dev/ttyUSB0
root@2a8988dafd77:/# exit
exit

USB機器を接続していない場合は以下のようにエラーが出力される。

% docker run --rm --device /dev/ttyUSB0 -it debian:9.9-slim /bin/bash
docker: Error response from daemon: linux runtime spec devices: error gathering device information while adding custom device "/dev/ttyUSB0": no such file or directory.
ERRO[0000] error waiting for container: context canceled

おわりに

USB Device Fileterの設定を検証している際、ホストOS側で認識していたUSB機器を抜き差しすることでホストOS側から機器が利用できなくなったり、フィルタの設定を変更しても、DockerホストOSが起動しているVMを再起動しないとそれが反映されなかったりと、設定の影響を確認するのに手間取った。

また記事に直接関係ないが、DockerホストOSでシステムの情報を確認しようとすると、OSがTinycorelinuxだったり、基本的なコマンドがGNU版ではなくBusyBoxだったりして、少し戸惑った。BusyBoxは調べてみると歴史は古いようで、Linuxの奥深さに触れるいい機会になった。

macOSでしか検証していないけど、おそらくWindowsでも同じ手順で認識させることができそう。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away