概要
今さらですがようやく Docker を使いはじめてみたのですが、VPN 接続をすると Docker ホストやコンテナへ接続できず、必要に応じて VPN を有効/無効しなければならないため非常に不便でした。
VPN 環境下でも ループバックアドレスへはアクセスできるため、ループバックアドレスから Dockerホストや Docker コンテナへポートフォワーディングで Docker を使用することにしました。ポートフォワーディングを使用した結果、docker-machine コマンドでは Docker ホストへ通信できなかったため、docker コマンドと Kitematic を使用しています。
手順ですが、最初に Docker クライアントと Docker daemon の通信方法の設定、次にホストOS の Windows から Docker コンテナへの通信方法の設定の順に設定していきます。
環境
Windows 8.1 Pro
Docker Toolbox 1.11.2
VirtualBox 5.0.20
Docker ホストへの通常の接続方法
Windows 上で Docker を使用する場合には、Docker client から VirtualBox の Host Only Adapter 経由で Docker daemon へ接続します。docker-machine コマンドでは TLS を使用した暗号化された通信だけしかできず、docker コマンドや Kitematic では TLS を使用しない平文でも通信をするようです。
VPN 環境下での Docker ホストへの接続方法
私はVPN クライアントとして Cisco AnyConnect Secure Mobility Client と OpenVPN GUI を使用して頻繁に VPN 接続をします。ネットワークについては疎いため原理は分かりませんが、VPN を使用すると Windows から Host Only Adapter 経由で仮想マシンへアクセスすることができません。ループバックアドレスへはアクセスできるため、ループバックアドレスから仮想マシンへポートフォワーディングすることで、Windows から仮想マシンへアクセスできるように設定します。
また、ポートフォワーディングを使うことにより、Docker クライアントは Windows へ接続する事となるため、Docker ホストの証明書が無効となります。証明書を作れれば TLS を使用した暗号化された通信が可能となりますが、このあたりも詳しくないため平文での通信で妥協して、暗号化通信は今後の課題としました。
docker-machine では暗号化された通信しかダメでなようなので、上記の妥協により docker-machine を使っていません。
Docker では、暗号化された通信は 2376 ポートを、平文の通信は 2375 ポートを使うのが慣習のようです。そのため、暗号化の無効に伴い、リッスンポートも変更します。
VPN 環境で Docker クライアントから Docker daemon へのアクセス方法は下図のようになります。
Docker daemon のリッスンポートの変更と暗号化の無効は Docker daemon の設定ファイルを修正します。次に、ループバックアドレスから Docker ホストへのポートフォワーディング(上図の紫の線)は VirtualBox の設定画面上で設定します。最後に Docker クライアントが平文で通信する設定をすれば設定は完了です。
Docker daemonの設定
Docker daemonの設定ファイルは VirtualBox 上で行います。デフォルトでは Docker ホストの仮想マシンはデタッチモードという画面が無いモードで起動しています。Oracle VM VirtualBox マネージャ で仮想マシンを選択し、上にある[表示(H)]ボタンを押すと画面が出てきます。この画面上で vi コマンドを使用し /var/lib/boot2docker/profileを下記のとおり修正します。
#DOCKER_HOST='-H tcp://0.0.0.0:2376'
DOCKER_HOST='-H tcp://0.0.0.0:2375'
#DOCKER_TLS=auto
ポートフォワーディングの設定
次にポートフォワーディングの設定も同様に VirtualBox 上で行います。Oracle VM VirtualBox マネージャ で仮想マシンを選択し、上にある[設定(S)]ボタンを押して設定ダイアログを表示します。ネットワークを選択すると、デフォルトではアダプター1 が NAT になっているはずです。[高度(D)]を押すと[ポートフォワーディング(P)]ボタンが出てくるので押すと[ポートフォワーディング ルール]ダイアログが表示されます。
VirtualBox の設定画面ではすでに ssh のポートフォワーディングがあるので、右側の+を押して新しいルールを追加し、下記の Insecure Docker のとおりに設定します。
Docker クライアントの設定
最後に Docker クライアントの通信先と認証ファイルのパスを設定します。この設定は Windows の環境設定でおこないます。下記にコマンドプロンプトでの設定例を記載しますが、システムのプロパティから設定しています。
set DOCKER_HOST=tcp://docker.local:2375
set DOCKER_CERT_PATH=C:\Users\<ユーザ名>\.docker\machine\machines\default
DOCKER_TLS_VERIFY を設定すると TLS を使用した暗号化をして通信をするようになってしまうため、これは設定してはいけません。
これで、VPN 環境下でも Windows 上の Docker クライアントから Docker daemon へ通信ができます。
ホストOS からコンテナへの接続方法
ここまでの設定をすることで VPN 環境下でも Docker コンテナを実行することができるようになりました。次は、Windows から、Docker コンテナで動いているミドルウェアへアクセスする設定が必要です。今回はミドルウェアとして Oracle WebLogic Server 12.2.1 を実行しています。
VPN を使用していなければ、コンテナの実行時に Docker ホストから Docker コンテナへポートフォワーディングを指定し、Windows から Host Only Adapter 経由で Docker コンテナへアクセスできます。
VPN 環境下では、コンテナの実行時に Docker ホストから Docker コンテナへポートフォワーディングと VirtulBox の ポートフォワーディングの組み合わせで Windows から Docker コンテナへアクセスします。
Windows から Docker コンテナへのネットワークは下図のとおりになります。
Windows 上のブラウザで 127.0.0.1:7001 へアクセスすると、Docker ホストの 32772 番ポートへフォワードされ、最終的に Docker コンテナの 8001 番ポートに到達します。
Docker コンテナと Docker ホストのポートフォワーディングの設定(下図の赤い部分)は Kitematic を使用して設定し、Docker ホストと Windows のポートフォワーディング(下図の紫の部分)は VirtualBox で設定します。
Docker ホストから Docker コンテナへのポートフォワーディング
Kitematic を使用して設定します。Docker ホストの 32772 番ポートから、Docker コンテナの 8001 番ポートへ転送します。Docker コンテナが停止している時に設定しないといけないようです。
Kitematic を使用しない場合には docker コマンドの run コマンドで -p オプションで同様に指定して下さい。
ホストOS から Docker ホストへのポートフォワーディング
VirtualBox を使用して先ほど同様に設定します。今回は、Windows の 7001 番ポートから Docker ホストの 32772 番ポートへ転送します。
Windows から Docker コンテナへのポートフォワーディングはこれで完了です。
設定の確認
設定が完了したので、きちんと転送されるかを確認してみましょう。
localhost:7001 へアクセスすると、Docker コンテナ上で動いている WebLogic サーバへアクセスできていることが確認できます。