コンテナのネットワーク
複数のコンテナを連携させるとき、コンテナ同士はどうやって相手を見つけて通信するのでしょうか。Dockerは既定でbridgeという仮想ネットワークを用意しますが、実務ではユーザ定義ネットワークを作り、コンテナ名で名前解決させるのが定石です。ここではコンテナ間通信の仕組みと、外部公開のためのポートマッピングとの違いを整理し、Composeが裏で何をしているのかも見ていきます。
複数のコンテナを組にして動かせるようになると、次に必ずつまずくのがネットワークだ。webコンテナからdbコンテナへ、どうやってつなげばいいのか。
ここでIPアドレスを直接書いてしまうと、コンテナを作り直すたびにIPが変わって動かなくなる。実務ではIPを直書きせず、コンテナ名やサービス名で相手を呼べる仕組みを使う。
🌉 既定のbridgeネットワーク
Dockerをインストールすると、既定でbridgeという名前の仮想ネットワークが1つ用意される。docker runで特に指定せずにコンテナを起動すると、このbridgeネットワークに接続される。
bridgeネットワークに参加したコンテナは、ホストとは独立した仮想のネットワーク空間の中でIPアドレスを1つずつ割り当てられる。コンテナ同士はこのネットワークを介して通信できるが、既定のbridgeには弱点がある。名前解決の機能が限定的で、コンテナ名を指定しても相手を見つけられないことが多い。
🏷️ ユーザ定義ネットワークと名前解決
この弱点を解消するのが、docker network createで自分で作るユーザ定義ネットワークだ。ユーザ定義ネットワークに参加したコンテナ同士は、コンテナ名(または--nameで付けた名前)をそのままホスト名として使い、お互いを見つけられる。
🔌 コンテナ間通信とポート公開の関係
ここで整理しておきたいのが、コンテナ間の通信と、ホストへの公開(-pオプション)の違いだ。同じネットワークに参加しているコンテナ同士は、-pでポートを公開していなくても、コンテナが持つポート番号に直接アクセスできる。
-pオプションは、あくまで「ホストの外側からコンテナの中へ」アクセスするための穴を開けるものだ。コンテナ同士の内側の会話には、この穴は関係ない。
🔍 ネットワークを覗く——ls・inspect
いま存在するネットワークの一覧はdocker network lsで確認できる。既定で用意されているbridge・host・noneに加え、自分で作ったネットワークがここに並ぶ。
特定のネットワークの詳細、つまりどのコンテナが参加していて、それぞれどんなIPを持っているかは、docker network inspect ネットワーク名で確認できる。トラブルシューティングのときによく使うコマンドだ。
🧩 composeは自動でネットワークを作る
前のトピックで扱ったDocker Composeは、実はこのユーザ定義ネットワークの仕組みを裏側で自動的に使っている。compose.yamlでservicesを定義してdocker compose upすると、Composeはそのプロジェクト専用のネットワークを自動生成し、全サービスをそこに参加させる。
だからこそ、compose.yamlの中でサービス名(web・dbなど)をそのままホスト名として書くだけで通信できていたわけだ。裏では毎回docker network createと同じことが自動で行われている。
コンテナ同士が名前で会話できる仕組みが分かったところで、次は作ったイメージを他の場所へ届ける方法、レジストリとタグの話に進もう。