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
はホストから完全に隔離されたネットワークなんだそうで、コンテナ間通信だけが必要な場合に使用する。
host
はVagrantでいうpublic_network
みたいなものという認識だけど、あっているかな。。。
bridge
を使用する場合、iptablesの機能でNATするためにhost
と比べてパフォーマンスが落ちることがあるようだ。
詳しくはこちらの記事が大変参考になります。