しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Docker で Windows Containers を使った時にコンテナホストから localhost でコンテナが見えない件

前に Windows Containers を使って IIS を立ち上げた時、コンテナホストから localhost でコンテナで動作しているはずの IIS を確認しようとしても出来なかったのですが、理由が分かったので書きます。

ちなみに Docker と Windows Containers については前のエントリを見てください。

世界の RD ことぶちぞうさんからは「お前の設定が悪い」みたいなことを Twitter で言われましたが、実際のところ内部で使われている WinNAT の制限で見れないだけでした。

あとから追記された感はありますが、ちゃんと IIS の Docker Hub に書いてありました。

With the current release, you can't use http://localhost to browse your site from the container host. This is because of a known behavior in WinNAT, and will be resolved in future. Until that is addressed, you need to use the IP address of the container.

https://hub.docker.com/r/microsoft/iis/

WinNAT については以下の記事にまとまっていました。コンテナ対応のために色々と追加されてますね。

Windows NAT (WinNAT) — Capabilities and limitations | Virtualization Blog

結局のところ、今は localhost を使ってアクセスは出来ないので、代わりにコンテナに割り当てられている IP アドレスを直接指定する必要があるみたいです。実際に Docker を使って試してみました。

まずは Docker を使って IIS を起動します。本来なら localhost:80 がコンテナにフォワーディングされるはずですが、今は対応していないということです。

docker run -d -p 80:80 microsoft/iis

念のためアクセスしておくと、コンテナホストにそのまま繋がっているような感じです。

f:id:shiba-yan:20161031193012p:plain

ここで docker inspect を使ってコンテナの IP アドレスを取得するコマンドを実行します。

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" CONTAINER_ID

実行すると IP アドレスが返ってきます。割り当てられる IP アドレスの範囲は docker network inspect コマンドを叩くことで確認することが出来ます。

f:id:shiba-yan:20161031192917p:plain

取得した IP アドレスを使うと、ちゃんと IIS のいつものページが表示されました。

ちゃんとコンテナホストからアクセスできることが確認できましたが、正直めんどくさいですね。

f:id:shiba-yan:20161031193045p:plain

起動ごとに IP アドレスは新しく振り直されるようなので、そのままだと毎回変わってしまって非常に扱いにくいですが、--ip オプションで IP アドレスを渡すことで一応固定は出来るみたいです。

docker run -d -p 80:80 --ip=172.29.72.198 microsoft/iis

指定できる IP アドレスはサブネット内じゃないとエラーになるので、予め docker network inspect を叩いて、サブネットを確認しておきましょう。

f:id:shiba-yan:20161031200537p:plain

デフォルトで nat というネットワークが作成されているので、このネットワークのサブネットを確認するだけです。どっちにしろめんどくさいので、早く WinNAT が対応されるように祈り続けたいと思います。