Compose のネットワーク機能

注釈

ここに示す内容は Compose ファイルフォーマットの バージョン 2それ以降 に適用されます。 ネットワーク機能は (古い)バージョン 1 ではサポートされません。

デフォルトで Compose は、アプリ向けに単一の ネットワーク を設定します。 1 つのサービスを構成する各コンテナは、そのデフォルトのネットワークに参加するので、ネットワーク上の他のコンテナからのアクセスが可能です。 さらにコンテナ名と同等のホスト名を用いてコンテナの識別が可能となります。

たとえばアプリが myapp というディレクトリにあって、docker-compose.yml が以下のような内容であるとします。

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

docker-compose up を実行すると以下の結果になります。

  1. myapp_default というネットワークが生成されます。
  2. web に関する設定に従って 1 つのコンテナが生成されます。 そしてそのコンテナは web という名前でネットワーク myapp_default に参加します。
  3. db に関する設定に従って 1 つのコンテナが生成されます。 そしてそのコンテナは db という名前でネットワーク myapp_default に参加します。

各コンテナはこれ以降、ホスト名 webdb を認識できるようになり、コンテナの IP アドレスも適切に取得できるようになります。 たとえば web のアプリケーション・コードでは、URL postgres://db:5432 を使ってのアクセスが可能となり、Postgres データベースの利用ができるようになります。

HOST_PORTCONTAINER_PORT の違いについては理解しておくことが重要です。 上の例の db では、HOST_PORT8001、コンテナ・ポートが 5432 (postgres のデフォルト) になっています。 ネットワークにより接続されているサービス間の通信は CONTAINER_PORT を利用します。 HOST_PORT を定義すると、このサービスはスウォームの外からもアクセスが可能になります。

web コンテナ内では、db への接続文字列は postgres://db:5432 といったものになります。 そしてホストマシン上からは、その接続文字列は postgres://{DOCKER_IP}:8001 となります。

コンテナの更新

サービスに対する設定を変更して docker-compose up により更新を行うと、それまでのコンテナは削除されて新しいコンテナがネットワークに接続されます。 このとき IP アドレスは異なることになりますが、ホスト名は変わりません。 コンテナの実行によってホスト名による名前解決を行い、新たな IP アドレスへ接続します。 それまでの古い IP アドレスは利用できなくなります。

古いコンテナに対して接続を行っていたコンテナがあれば、その接続は切断されます。 この状況を検出するのは各コンテナの責任であって、ホスト名を探して再接続が行われます。

複数ホストによるネットワーク

注釈

ここに示す手順は、かつての Docker Swarm の操作に基づいています。 したがってかつてのスウォーム・クラスタを対象とする場合にのみ動作します。 Compose によるプロジェクトを、最新の統合されたスウォーム・モードにデプロイするには、Docker Stacks に示すドキュメントを参照してください。

Compose アプリケーションをスウォーム・クラスタにデプロイする 際には、ビルトインの overlay ドライバを利用して、コンテナ間で複数ホストによる通信を行うことが可能です。 Compose ファイルやアプリケーションコードへの変更は必要ありません。

複数ホストによるネットワークをはじめよう を参考に、スウォーム・クラスタの構築方法を確認してください。 デフォルトでクラスタは overlay ドライバを用います。 ただし明示的にこれを指定することもできます。 詳しくは後述します。

独自のネットワーク設定

デフォルトのアプリ用ネットワークを利用するのではなく、独自のネットワークを指定することができます。 これは最上位の networks キーを使って行います。 これを使えば、より複雑なネットワーク・トポロジを生成したり、独自のネットワーク・ドライバ とそのオプションを設定したりすることができます。 さらには、Compose が管理していない、外部に生成されたネットワークに対してサービスを接続することもできます。

サービスレベルの定義となる networks キーを利用すれば、サービスごとにどのネットワークに接続するかを指定できます。 指定する値はサービス名のリストであり、最上位の networks キーに指定されている値を参照するものです。

以下において Compose ファイルは、独自のネットワークを 2 つ定義しています。 proxy サービスは db サービスから切り離されています。 というのも両者はネットワークを共有しないためです。 そして app だけがその両者と通信を行います。

version: "3"
services:

  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    # 独自ドライバーの利用
    driver: custom-driver-1
  backend:
    # 所定のオプションを用いる独自ドライバーの利用
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

接続するネットワークのそれぞれは、ipv4_address または ipv6_address を使ってスタティック IP アドレスを設定することができます。

ネットワーク設定に関して利用可能なオプションについては、以下のリファレンスを参照してください。

デフォルト・ネットワークの設定

独自のネットワーク設定は行わずに、あるいはそれを行った上でさらに、アプリに対するデフォルトネットワークの設定を変更することができます。 これは networks のもとに default という項目を定義して行います。

version: "3"
services:

  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # 独自のドライバを利用
    driver: custom-driver-1

既存ネットワークの利用

コンテナを既存のネットワークに接続したい場合は external オプション を利用します。

networks:
  default:
    external:
      name: my-pre-existing-network

Compose は [projectname]_default という名前のネットワークを生成しようとはせず、my-pre-existing-network というネットワークを探し出して、アプリのコンテナをそこに接続します。

参考

Networking in Compose
https://docs.docker.com/compose/networking/