リモートホスト(FreeBSD 11.1)にbhyve
を使った仮想マシンとしてUbuntuをホストさせ,そこでdockerd
をセットアップし,そこにIPv6 TCP通信を介してローカルマシン(FreeBSD 11.1)から接続した記録です.
動機
FreeBSD上でDockerを動かす試みはあるものの,未だに試験的存在の域を離れず,満足に動作するとは言い難い状況にある.
とはいえコンテナエコシステムはdockerが圧倒的優位で,(Docker以外はコンテナじゃないよね〜という驕りは許せないが,)イメージを指定したら適当に拾ってコンテナが立つ便利さを知ってしまうとjail
では不満が残る.
そこでdocker-machine
の要領でlinuxマシンを仮想的に動作させ,その上でdockerd
を起動することにした.
FreeBSDで利用できる仮想化環境としてbhyve
があるため,これの上でUbuntu Serverをセットアップした.
開発環境であるローカルマシンの負荷を上げて開発に支障をきたさぬよう,bhyve
はリモートホストで動作させることにした.
登場人物
- bhyve
- FreeBSDにおける仮想化ハイパーバイザ.LinuxのKVMみたいなやつ.カーネルで動く.
- https://www.slideshare.net/syuu1228/bhyve-12239043
- Docker
- 言わずと知れたコンテナツール.覇権になった.
- vm-bhyve
- 面倒なbhyveの操作を簡単にしてくれるshラッパー.
- IPv6
- みんなの夢
結論
ネットワークを介したファイルシステムのマウントの煩雑さを除けば,十分実用できそうである.
bhyveをインストールする
bhyve
は単体では使いにくいので,ラッパーであるところのvm-bhyve
を使います.
仮想マシンを動かしたいホストで以下のようにします.ちなみにOSはFreeBSD 11.1です.
だいたい公式ページのQuick startの通りにしていれば動きます.
必要に応じてsudo
とか使うとよさそう.
# vm-bhyve入れる. pkg install vm-bhyve # bhyveとvm-bhyveが使う領域を確保する.ISOとかイメージファイルとかが入るので大きめ推奨. zfs create POOL_NAME/vm # プール名はよしなに環境に合わせて設定する.vm部分も変更できる. # 起動時にvm-bhyveが有効になるようにする echo 'vm_enable="YES"' >> /etc/rc.conf # vm-bhyveが使う領域を指定する.ふつうのディレクトリを指定することもできる.(割愛) echo 'vm_dir="zfs:POOL_NAME/vm"' >> /etc/rc.conf # 上掲の領域に構成ディレクトリを掘ったり,vmmカーネルモジュールを有効化したりする. vm init # 仮想マシンのスペックを決めるテンプレートファイルをサンプルからコピってくる. cp /usr/local/share/examples/vm-bhyve/* /mountpoint/for/pool/vm/.templates/ # 仮想マシンがぶら下がるための仮想スイッチを'public'という名前で作成する. vm switch create public # igb0を仮想スイッチに接続する. vm switch add public igb0 # LAN側NICを指定した.NIC名はよしなに環境に合わせる.
ここまでbhyveのインストール.ここから仮想マシンのインストールである.ここまでの操作は2つ目の仮想マシンを立てる際は不要.
# インストールに使うISOイメージを拾ってこさせる.今回はUbuntu serverを使う. vm iso http://cdimage.ubuntu.com/releases/18.04/release/ubuntu-18.04-server-amd64.iso # 「ubuntu-dev」として仮想マシンを作成する. # -tで上掲のテンプレートを指定する.ubuntuテンプレートもサンプルにあるので,これを使った. # -sで仮想マシンのために作成するディスクイメージのサイズを指定する.ひとまず50GiBにする. vm create -t ubuntu -s 50G ubuntu-dev # 仮想マシンが起動するとシャットダウンするまでホストに戻れないので,tmuxなどを起動しておく. tmux # installコマンドでISOを起動し,インストール作業を行う. # -fオプションで仮想マシンをフォアグラウンドで起動する. # フォアグラウンドで起動しなくても,vm consoleコマンドで仮想マシンにアタッチできる. vm install ubuntu-dev -f ubuntu-18.04-server-amd64.iso
ほぼ公式の手順を踏んでUbuntuをインストールしようとしてきたが,ここまで来て起動しない.
ちょっと調べたところ,bhyveでlinuxを起動するにはbhyve用のGRUBを入れないといけないようだ. https://blog.bixr.com/2016/07/1178/
pkg install grub2-bhyve
するとうまくインストーラが起動した.
# インストーラを再び起動する vm install -f ubuntu-dev ubuntu-18.04-server-amd64.iso
今回はリモートホストでbhyveを利用しているので,仮想ホストを使うたびにリモートに接続するのはおっくうだ.
インストールの過程で,sshd
を起動するように設定しておいたほうがよい.ここは単にインストーラ中に操作するだけなので割愛する.
また,鍵の生成やsshdの設定も忘れずに行う.
ちなみに,自分の環境ではリモートホストがルータとしても動作しているので,ローカルマシンからそのまま仮想マシンに接続できるようになる.
dockerのセットアップ
インストールした仮想マシンを起動しておく.
vm start ubuntu-dev
ここからは仮想マシンでの操作である.
ssh ADDRESS_OF_ubuntu-dev
通常のDockerのインストールと特に変わった点はない.自分の環境固有かもしれないが,うまくレポジトリを 見付けられずにdocker-ce
を発見できないことがあった.適当にネットサーフィンして解決したが,bhyveとは特に関係ないので割愛する.
さてDockerがセットアップされたら,DockerデーモンがTCPポートをリッスンするように設定する.
dockerd
がTCPをリッスンするには,dockerd
の起動時にdockerd -H tcp://0.0.0.0:2375
のように指定してやればよい.
dockerd
は自分の環境ではsystemd
によって起動していたので,/etc/systemd/system/multi-user.target.wants/docker.service
を編集する.
vi /etc/systemd/system/multi-user.target.wants/docker.service
ExecStart
の箇所にdockerd
の起動オプションが記述されているので,ここに前述のオプションを書き足す.
自分の環境ではIPv6を使用したいので,IPv6でURIを記述した.アドレスはユニークローカルを指定している.
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://[fdda:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:2375
dockerd
を再起動する.
systemctl restart dockerd
ネットワーク越しに接続するために,2375番ポートを開放する.今回はローカルなLAN内で行ったので開放のみを行っているが, インターネットに露出しうる環境ではポートがインターネットに露出しないように気をつける必要がある.場合によってはIPアドレスによる制限などをかける必要がある. とはいえ今回はユニークローカルアドレスのみをリッスンさせている.
ufw allow 2375
ローカルマシンでのdockerのセットアップ
ローカルマシンもリモートホスト同様FreeBSD11.1である.dockerはクライアントとサーバデーモンがREST APIを通じて分離しているので,
クライアントだけをインストールしてリモートのdockerd
と交信することができる.リモートのdockerd
を使う場合であってもローカルのDockerfile
やdocker-compose.yml
を利用できる.コンテナはリモートに作成される.
dockerクライアントにdockerd
のエンドポイントを指示するには,DOCKER_HOST
環境変数を設定するか,直接docker -H tcp://...
のように-H
オプションを使う.
pkg install docker docker-compose export DOCKER_HOST=tcp://[fdda:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:2375
ただし,ボリュームマウントでローカルのファイルシステムを読み書きすることはできない.例えば,-v /hoge:/fuga
のように指定しても,ローカルの/hoge
がバインドされるわけではなく,仮想マシンから見た/hoge
をコンテナの/fuga
にバインドしようとする.
ひとまずこれでbhyve上のdockerdを使ってhello-worldができるようになった.
docker run hello-world Hello from Docker! ...