WindowsのデクストップPCにDockerを入れて、ちょっとした定例作業をするためのサーバーを動かしています。
ただ、開発も同じPCでやっているので、開発での作業の影響を本番に与えたくないため、開発と本番でDocker Serverを動かすマシンを分けています。
その、Docker Serverを複数立ち上げる方法に関する手順メモです。また、Docker ServerへのアクセスはPowerShellではなく、WSLを通じて行っているので、その設定も合わせてメモしておきます。
手順
「Docker Machine」を使うと、Dockerが動く仮想マシンを手軽に追加することができきるのでそれを使います。
PowerShellを管理者権限で起動します
PowerShellのコンソールの文字コードをUTF-8にします
chcp 65001
docker-machineで新しいDocker Serverの仮想端末を作成します
docker-machine create ` —driver hyperv ` —hyperv-memory 2048 ` —hyperv-virtual-switch "既定のスイッチ" ` devVM
これで新しく「devVM」というDocker Serverが追加されます。
「MobyLinuxVM」というのは後述しますが、Docker Desktopをインストールした時に作成される、デフォルトのDocker Serverです。
WindowsのDockerに関して簡単に解説
上記の作業内容について簡単に説明します。
Dockerはクライアント・サーバーモデルで動いています。WindowsのDockerは、Hyper-VでLinuxの仮想端末を作成し、その仮想端末上でDocker Serverを動かしてDockerの実行を行なっています。
つまり、WindowsネイティブにDockerが動いているのではなく、Windows上で作成されたLinux上でDockerが動いていて、PowerShellやコマンドプロンプト、WSLなどのクライアントから、そのLinuxにアクセスしているに過ぎません。(Windowsネイティブに動くWindowsコンテナというものもあるのですが、今回は説明から省きます)
Hyper-Vの仮想端末がインターネットにアクセスできるようにするには、仮想端末が使うスイッチを「既定のスイッチ」にする必要があり、「—hyperv-virtual-switch」オプションで指定します。ただし、「既定のスイッチ」は日本語で、そのままではコマンド引数に渡せないため、「chcp 65001」でPowerShellの端末の文字コードをUTF-8に変更しています。
WSLからDockerにアクセスする
デフォルトのDocker ServerにWSLからアクセスする
WIndowsのDocker Desktopをインストールした際にインストールされる、デフォルトのDocker ServerにWSLからアクセスするには、Docker Desktopの設定で
- [General]-[Expose daemon on tcp://localhost:2375 without TLS]にチェック
で行えます。
追加したDocker ServerにWSLからアクセスする
追加したDocker Serverにアクセスするには一手間必要です。
先述のとおり、Dockerはクライアント・サーバーモデルなので、WSL(Dockerクライアント)の向き先を、デフォルトのDocker Serverから、作成したDocker Serverに変えることにより行います。
向き先の設定は「DOCKER_HOST」「DOCKER_CERT_PATH」「DOCKER_TLS_VERIFY」の環境変数により行います。
- 「DOCKER_CERT_PATH」が示すDocker Serverの認証に関するファイルは、Docker Machine作成時に生成され、「/mnt/c/Users/<Windowsユーザー名>/.docker/machine/machines/<Docker_Server名>」ディレクトリに保存されます。
- Docker ServerのIPアドレスは、Hyper-Vマネージャの作成した仮想端末の「ネットワーク」から調べます。
これらの情報を元に、下記のように環境変数を設定すると、以後、Dockerコマンドは追加したDocker Serverに対して発行され、アクセスできるようになります。
export DOCKER_HOST=tcp://<ip_address>:2376 export DOCKER_CERT_PATH=/mnt/c/Users/<user_name>/.docker/machine/machines/<docker_server_name> export DOCKER_TLS_VERIFY=1
デフォルトのDocker Serverにアクセスを戻す
下記のように、設定した環境変数を削除すれば、以後、デフォルトのDocker Serverにアクセスできるようになります。
export DOCKER_HOST=tcp://0.0.0.0:2375 unset DOCKER_CERT_PATH unset DOCKER_TLS_VERIFY
Docker Composeを使う際の注意
Docker Composeは、デフォルトではTLSのバージョン1.0を使うため、追加したDocker Serverに対して、WSLでDocker Composeを使うと、セキュリティー上の問題により下記のようなエラーがでます。
ERROR: SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version
そんな時は、下記のように、環境変数でDocker ComposeのTLSのバージョンを1.2にセットするとエラーが出なくなります。
export COMPOSE_TLS_VERSION=TLSv1_2
ちなみに、デフォルトのDocker Serverは、WSLからのアクセス設定で「without TLS」としているので、TLSのバージョンに関わらずエラーは出ません。
Docker ServerのIPアドレスを固定する
「既定のスイッチ」を使うと、追加したDocker ServerはDHCPで適当なIPアドレスが割りあてられます。
そのままでは、PCを起動する度にIPが変わってしまい不便ですので、IPアドレスを固定します。
情報収集
IPアドレス固定に必要な情報は下記です。
- IPアドレス
- ネットマスク
- ゲートウェイ
- DNS
ネットマスク・ゲートウェイ・DNS
[コントロールパネル]-[ネットワークと共有センター]-[アダプターの設定の変更]で「vEthernet(既定のスイッチ)」があるので、 [右クリック]-[状態の表示]-[詳細]を開きます。
- 「IPv4 アドレス」が「ゲートウェイ」と「DNS」になります。
- 「IPv4 サブネット マスク」が「ネットマスク」になります。
- 「IPアドレス」は、「IPv4 アドレス」と「IPv4 サブネット マスク」から求まる、任意の「ホスト部」で設定できます。(前述で設定したIPアドレスのままでも構いません)
情報をDocker Serverに設定
「Hyper-Vマネージャー」から、追加したDocker Serverをダブルクリクしてログインします。
Docker Server起動時に「/var/lib/boot2docker/bootlocal.sh」が呼ばれるので、「bootlocal.sh」ファイルを作成して下記を記載します。
bootlocal.sh
ifconfig eth0 <IPアドレス> netmask <ネットマスク> up echo nameserver <DNS> >> /etc/resolv.conf route add default gw <ゲートウェイ>
シャットダウンして、再度Docker Serverを起動します
するとDocker Serverが新しい指定したIPアドレスになり、PCを立ち上げなおしても指定したIPアドレス固定になります。
認証の再構築
認証はIPアドレスと紐付いているため、IPアドレスが変わるとDocker Machine構築時に作成された認証が使えなくなるので、管理者権限で実行したPowerShellから下記コマンドで再構築します。
docker-machine regenerate-certs <マシン名>
Docker Serverの切り替え
「.bashrc」などに下記のようなエイリアスを作っておくと、切り替えが楽になるかと思います。
alias machine_default='export DOCKER_HOST=tcp://0.0.0.0:2375 && unset DOCKER_CERT_PATH && unset DOCKER_TLS_VERIFY' alias machine_dev='export DOCKER_HOST=tcp//<ip_address>:2376 && export DOCKER_CERT_PATH="/mnt/c/Users/<user_name>/.docker/machine/machines/<machine_name>" && export DOCKER_TLS_VERIFY=1'
感想
Hyper-V周りはややこしくてハマりました…。常に仮想端末が動いているのは精神衛生上よろしくなく、WSLだけでDockerが動いてくれたらこんな苦労しなくて済むんですが…。
追記
WSL2ではDockerが動くようになるみたいですね。
Windows10 Homeでも使えるし、WSL2はHyper-Vだけど、通常のVMと違って高速みたいなので、様子見しようかと思ってたけど気になってきました。
Insider で降ってきたWindows build 18917にWSL 2が入ってた。VMで動くけどUtilityVMなのでHyper-Vマネージャーにからは見えない(画像のはDocker DesktopのVM)。起動は一瞬でござるね。 pic.twitter.com/XEDzBsrkMI
— Toru Makabe (@tmak_tw) 2019年6月13日