黒縁眼鏡は海を飛ぶ

IT中心にそこはかとなく

Dockerシングルホストでのコンテナ間通信 -その2-

前回またもレガシーなことをしてしまったみたいなので、ちゃんとドキュメントを読みながらナウでヤングなDockerネットワーク(ただしシングルホスト)を試していきたいと思います。


デフォルトネットワーク(brigeドライバ)で困ったこと

デフォルトネットワークのlink機能を使った場合、1点だけ困ったことがあった。

前回はbackendコンテナを立ち上げた後、proxyコンテナを--linkオプションで紐付けたけど、この場合コンテナの立ち上げ順を意識する必要がある。

# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
e2df163580d2        ryoana/nginx        "/bin/sh -c '/usr/sbi"   47 hours ago        Exited (0) 7 seconds ago                       proxy
7a994bad7e68        ryoana/nginx        "/bin/sh -c '/usr/sbi"   2 days ago          Exited (0) 4 seconds ago                       backend
# docker start proxy
Error response from daemon: Cannot link to a non running container: /backend AS /proxy/backend
Error: failed to start containers: proxy

linkしたbackendコンテナが落ちているのでproxyコンテナが起動できない。
今回のように数が少なければ問題ないけど、linkされたコンテナの数が多くなってくると非常にめんどくさそう。

これは試していないけど、デフォルトのbridgeネットワークではlink対象のコンテナを再起動することもできないらしい。


ユーザ定義ネットワーク

ドキュメントによると、ユーザ定義ネットワークを使うといいらしい。 Dockerをインストールした直後のネットワークは以下の通り。

# docker network ls
NETWORK ID          NAME                DRIVER
b2e5b76b57d7        none                null                
e5f4c8113d9a        host                host                
b08baa0ee5fa        bridge              bridge

hostネットワークドライバは置いておいて、bridgeを使ってユーザ定義のネットワークを作成してみる。

# docker network create --driver=bridge test_network
ffd167ec07114eb8927e18b02c964abca316611dd48118cb906ec2baa8197c97
# docker network ls
NETWORK ID          NAME                DRIVER
b08baa0ee5fa        bridge              bridge              
b2e5b76b57d7        none                null                
e5f4c8113d9a        host                host                
ffd167ec0711        test_network        bridge

test_networkが作成されていることが確認できる。

このネットワークを使って、proxyコンテナとbackendコンテナをたてなおしてみる。

# docker run -d --name backend --net test_network -v backend_html:/usr/share/nginx/html ryoana/nginx
# docker run -d --name proxy --net test_network -v proxy_config:/etc/nginx -v proxy_html:/usr/share/nginx/html -p 80:80 ryoana/nginx

proxyコンテナのnginx.confにbackendへのproxy_passが記載されているので、先にbackendコンテナを起動しているから結局backendから起動してるやんけ!とツッコミが入りそうだけど、そこはnginxの問題なので気にしない。

前回との違いは--linkオプションを使用していない点にある。
デフォルトネットワークでは--linkを指定しないと/etc/hostsにエントリが追加されず通信ができなかったけれど、ユーザ定義ネットワークの場合は--linkなしでも内蔵のDNSによって名前解決が可能になっているらしい。

では--linkオプションは不要になったのかというとそういうわけではなくて、変わらずエイリアスの設定用途で使用できる。
また、docker networkコマンドで作成した他のネットワークを動的に接続・切断が可能なんだそう。


Dockerのネットワーク

上述したnetworkの一覧をもう一度。

# docker network ls
NETWORK ID          NAME                DRIVER
b2e5b76b57d7        none                null                
e5f4c8113d9a        host                host                
b08baa0ee5fa        bridge              bridge

bridgeドライバはDockerがデフォルトで使用する。docker0インターフェースを使ってホスト内にコンテナ用の仮想ネットワークを形成する。

nullはホストから完全に隔離されたネットワークなんだそうで、コンテナ間通信だけが必要な場合に使用する。

hostVagrantでいうpublic_networkみたいなものという認識だけど、あっているかな。。。

bridgeを使用する場合、iptablesの機能でNATするためにhostと比べてパフォーマンスが落ちることがあるようだ。

詳しくはこちらの記事が大変参考になります。