大人の学びなおしDocker(3)~ネットワーク編~
はじめに
前回はDockerの基礎の中身について書きました。
今回はさらにDockerのネットワーク部分について調べたいと思います。
Dockerの内部ネットワークはどうなっているのか
ホストとコンテナ・ネットワークの関係は以下のようになっています。
引用:https://github.com/KamranAzeem/learn-docker/blob/master/docs/images/docker-bridge-network-1.png
docker network ls
でネットワーク一覧を表示すると、bridgeという名前のネットワークがデフォルトで作成されています。上の構成図で2つのコンテナが接続しているブリッジです。
指定されない限りすべてのコンテナはこのデフォルトネットワークに接続されます。
使用しているマシンがMacの場合は、ifconfigコマンドでdocker0というインターフェスを確認できます。これは先ほどdocker network lsコマンドで確認したデフォルトブリッジネットワークです。
このインターフェースは現状では status: inactive
となっています。そして任意のコンテナを立ち上げると、このステータスはinactiveのままです。なんでや。
(コンテナを立ち上げて接続したらアクティブになるのかと思っていたのですが違うようです。ネットワーク弱い勢なのでよくワカラナイ。また今度調べようと思います)
気を取り直して、ネットワークの状態を見るために適当なコンテナを2〜3個立ち上げます。イメージはなんでもいいのですが、すぐに終了してもらっては困るのでhttpdのイメージを使います。コンテナの名前は自分が分かりやすいものにしてもらえれば、なんでも良いです。
$ docker run --name test-httpd httpd
$ docker run --name test-httpd-second httpd
dcker network inspect bridge
というコマンドを叩くと、ネットワークの詳細を確認できます。
なんかいろいろ情報が表示されていますが、172.17.0.0/16のサブネットが自動で割り当てられ、同じネットワークに先ほど作成した test-httpd
と test-httpd-second
のコンテナが接続されているのが分かります。
また、立ち上がったコンテナにはそれぞれ仮想的なMACアドレスが割り当てられています。ただしデフォルトのブリッジネットワークにはサービスディスカバリの機能がありません。
本当にサービスディスカバリの機能が無いのか検証
サービスディスカバリ機能が無いということは、ホスト名やポートの判別ができないということです。以下のコマンドで片方のコンテナに入り、もう一方のコンテナにPINGを送ってみましょう・・・と思っていましたが適当にhttpdコンテナを選んだせいでPINGコマンドが入っていません。ついでにインストールしましょう。
$ docker exec -it test-httpd /bin/bas
---ここからコンテナ内---
$ apt-get update
$ apt-get install -y iputils-ping
$ ping test-httpd-second httpd
-> ping: httpd: Name or service not known
PINGコマンドを打っても「そんなサービス無いよ」と言われてしまいます。
そもそも疎通が取れているのか?を確認するために、さっきifconfigで確認したコンテナ(test-httpd-second)のIPでもう一度PINGしてみます。
今度はちゃんと応答がありました。疎通自体は取れていることが分かります。
でもComposeではサービス名を使うよね?
docker composeなどを使う場合にはサービス名を定義して、それを多用します。でも今確認したらサービスディスカバリがない。
というのも、デフォルトのブリッジネットワークを使う時に限りサービスディスカバリが効かないようです。ユーザーが独自で作ったユーザー定義のネットワークではサービスディスカバリの機能が使えます。
そのため、コンテナ名(サービス名)を使った通信も可能です。ちなみにこのサービスディスカバリの機能はDocker Engineの中に含まれているようですが、Dockerとdocker composeのネットワークの違いやサービスディスカバリの詳細についてはまた別の機会に調べたいと思います。
まとめ
- dockerにはdocker0ともよばれるデフォルトブリッジネットワークがある
- 通常、コンテナはこのdocker0に接続される
- ただしdocker0にはサービスディスカバリが無いため、サービス名を使った通信は不可
- デフォルトではなく自分で定義したネットワークの場合はサービスディスカバリできる
最後に
普段のPCを立ち上げるのが面倒でゲーミングPCの方で試そうとしたら、OSがWindowsだったこともありインターフェース名の確認ができませんでした。Windowsで同じことを試そうとすると???となるケースがあるのでお気をつけください。私は諦めてMacを立ち上げました。
参照:https://github.com/KamranAzeem/learn-docker/blob/master/docs/docker-networking-deep-dive.md
Discussion