ブリッジ・ネットワークの使用

ネットワーク機能(networking)におけるブリッジ・ネットワーク(bridge network)とは、ネットワーク・セグメント間にトラフィックを転送するリンク層の装置(Link Layer device)です。ブリッジとは、ハードウェア装置もしくはホストマシンのカーネル内で稼働するソフトウェア装置です。

Docker におけるブリッジ・ネットワークとは、ソフトウェア・ブリッジを使い、同じブリッジ・ネットワークにあるコンテナに接続できるようにします。また、コンテナに対するネットワークの隔離も提供しますので、同じブリッジ・ネットワークに接続していないコンテナとは接続しません。Docker のブリッジ・ドライバはホストマシン上にルールを自動設定しますので、異なるブリッジ・ネットワーク上のコンテナは、相互に直接通信できません。

ブリッジ・ネットワークの対象は、 同じ Docker デーモンホスト上で動作するコンテナです。異なる Docker デーモンホスト上で動作しているコンテナ間で通信をするには、OS レベルでルーティングを管理するか、 オーバレイ・ネットワーク を利用できます。

Docker を起動すると、 デフォルト・ブリッジ・ネットワークbridge とも呼びます)が自動的に作成されます。また、新しく起動するコンテナでネットワークの指定が無い蹴れば、このデフォルト・ブリッジ・ネットワークに接続します。 このデフォルト ``bridge`` ネットワークよりも、ユーザ定義ブリッジ・ネットワークの方が優先です

ユーザ定義ブリッジとデフォルト・ブリッジとの違い

  • ユーザ定義ブリッジ・ネットワークは、コンテナ間の DNS 名前解決を自動で提供

    過去の機能(レガシー)と考えられている --link オプション を使わなければ、 デフォルト・ブリッジ・ネットワーク上のコンテナは IP アドレスを使わないとお互いに通信できません。ユーザ定義ブリッジ・ネットワーク上であれば、コンテナはお互いに名前もしくはエイリアス(別名)で名前解決できます。

    ウェブ・フロントエンドとデータベース・バックエンドのアプリケーションを想定しましょう。コンテナの名前が webdb であれば、 web コンテナは db コンテナに対して db という名前で接続でき、Docker ホスト上でどのようなアプリケーションが稼働していても気にかける必要がありません。

    デフォルト・ブリッジ・ネットワーク上で同じアプリケーション・スタックを動かす場合は、コンテナ間のリンクを手動で作成する(過去の機能 --link フラグを使う)必要があります。このリンクは双方向に作成する必要があるため、2つ以上のコンテナ間で通信が必要になれば、より複雑です。あるいは、コンテナ内の /etc/hosts ファイルを手で書き換えられますが、デバッグが大変になる問題を生み出します。

  • 隔離のためには、ユーザ定義ブリッジがより望ましい

    コンテナに --network を指定しなければ、コンテナはデフォルト・ブリッジ・ネットワークに接続(attach)します。これは関係のないスタックや、サービス、コンテナと通信可能になるため、リスクを引き起こします。

    ユーザ定義ネットワークを利用するのであれば、コンテナが通信できるネットワークは、そのコンテナが接続しているユーザ定義ネットワーク範囲内にとどまります。

  • ユーザ定義ネットワークであれば、コンテナの接続・切断を直ちに行えます

    コンテナが稼働中であれば、ユーザ定義ネットワークへの接続や切断を直ちに行えます。ただし、デフォルト・ブリッジ・ネットワークからコンテナを削除するには、コンテナの停止が必要であり、さらに異なるネットワーク・オプションでコンテナを再作成する必要があります。

  • それぞれのユーザ定義ネットワークは、設定可能なブリッジを作成

    コンテナがデフォルト・ブリッジ・ネットワークを使う場合、設定は可能ですが、 MTU や iptables ルールなど、全てのコンテナで同じ設定を使います。付け加えておくと、デフォルト・ブリッジ・ネットワークの設定は Docker 外での処理のため、Docker の再起動が必要です。

    ユーザ定義ブリッジ・ネットワークは docker network create を使って作成と設定ができます。アプリケーションのグループごとに異なるネットワーク要件があれば、それぞれ別々にユーザ定義ネットワークを作成し、設定ができます。

  • デフォルト・ブリッジ・ネットワーク上でリンクしたコンテナ間では、環境変数を共有します

    当初、2つのコンテナ間で環境変数鄔共有するには --link フラグ を使い、コンテナ間をリンクする方法しかありませんでした。ユーザ定義ネットワークであれば、このような変数共有は不可能です。しかしながら、環境変数を共有するよりも優れた方法がいくつかあります。

    • Docker ボリュームを使い、複数のコンテナで共有情報を含むファイルやディレクトリを共有。
    • docker-compose を使い複数のコンテナを同時に起動し、 compose ファイルで共有変数を定義する。
    • スタンドアロン・コンテナではなく、 swarm サービスを使えば、 シークレットコンフィグ を利用できる。

同じユーザ定義ブリッジ・ネットワーク上に接続するコンテナは、事実上すべてのポートをお互いに公開しています。異なるネットワーク上のコンテナや Docker 外のホストからポートにアクセスできるようにするには、 -p--publish フラグを使ってポートの公開( published )が必須です。

ユーザ定義ブリッジの管理

ユーザ定義ブリッジ・ネットワークの作成には、 docker network create コマンドを使います。

$ docker network create my-net

サブネット、IP アドレスの範囲、ゲートウェイ、その他のオプションを指定できます。詳細は docker network create リファレンスか、 docker network create --help の出力をご覧ください。

ユーザ定義ブリッジ・ネットワークから削除得するには、 docker network rm コマンドを使います。コンテナがその時点でネットワークに接続中であれば、まず ネットワークからの切断 をします。

$ docker network rm my-net

ヒント

実際には何が起こっているのですか?

ユーザ定義ブリッジの作成や削除時、あるいは、ユーザ定義ブリッジへのコンテナの接続や切断時、Docker はオペレーティングシステムに特化したツールを使い、土台とするネットワーク基盤(Linux 上であればブリッジ・デバイスの追加や削除、 iptables のルール設定など)を管理します。これらの詳細は、実装上の詳細にあたります。自分用のユーザ定義ネットワークは、Docker を使って管理しましょう。

ユーザ定義ネットワークにコンテナを接続

新しいコンテナの作成時、1つまたは複数の --network フラグを指定できます。例として Nginx コンテナが my-net ネットワークに接続するものとします。また、外部のクライアントがポートに接続できるようにするため、コンテナ内のポート 80 を、Docker ホスト上のポート 8080 に公開します。 my-net ネットワークに接続するあらゆるコンテナは、 my-nginx コンテナ上の全てのポートに対してアクセス可能ですし、その逆もまた同様です。

$ docker create --name my-nginx \
  --network my-net \
  --publish 8080:80 \
  nginx:latest

実行中 のコンテナを既存のユーザ定義ブリッジに接続するには、 docker network connect コマンドを使います。以下のコマンドは、既に実行している my-nginx コンテナが稼働している既存の my-net ネットワークに接続します。

$ docker network connect my-net my-nginx

ユーザ定義ネットワークからコンテナを切断

ユーザ定義ブリッジ・ネットワークで実行中のコンテナを切断するには、 docker network disconnect コマンドを使います。以下のコマンドは my-net ネットワークから my-nginx コンテナを切断します。

$ docker network disconnect my-net my-nginx

IPv6 を使う

Docker コンテナで IPv6 のサポートが必要であれば、IPv6 ネットワークの作成やコンテナに IPv6 アドレスを割り当てる前に、 Docker デーモンで 有効化するオプション と、その設定の再読込が必要です。

ネットワークの作成時、 IPv6 を有効化するには --ipv6 フラグを使います。デフォルトの bridge ネットワークでは IPv6 サポートの無効化を選択できません。

Docker コンテナから外の世界への転送を有効化

デフォルトでは、デフォルト・ブリッジ・ネットワークに接続したコンテナからのトラフィックは、外の世界のネットワークに対して転送 されません 。転送を有効にするには、2つの設定を変更する必要があります。これらは Docker コマンドではなく、Docker ホスト上のカーネルに対して影響を与えます。

  1. Linux カーネルが IP フォワーディングを有効化する設定にします。

    $ sysctl net.ipv4.conf.all.forwarding=1
    
  1. iptables に対するポリシーを変更します。 FORWARD``ポリシーを ``DROP から ACCEPT にします。

    $ sudo iptables -P FORWARD ACCEPT
    

この設定は再起動後は有効ではありませんので、スタートアップスクリプトに追加する必要があるでしょう。

デフォルト・ブリッジ・ネットワークを使う

デフォルトの bridge ネットワークは Docker にとって過去の機能(レガシー)と考えられており、プロダクションでの利用は推奨されていません。なぜなら、設定は手動で行う必要がありますし、 技術的な欠点 があります。

デフォルト・ブリッジ・ネットワークへコンテナを接続

もしも --network フラグを使ってネットワークを指定せず、ネットワークドライバの指定がなければ、コンテナはデフォルトの bridge ネットワークに接続するのがデフォルトの挙動です。デフォルト bridge ネットワークに接続したコンテナは通信可能ですが、 古い機能の --link フラグ でリンクしていない限り、 IP アドレスのみです。

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

デフォルト bridge ネットワークの設定を変更するには、 daemon.json のオプション指定が必要です。以下はいくつかのオプションを指定した daemon.json の例です。設定に必要なオプションのみ指定ください。

{
  "bip": "192.168.1.5/24",
  "fixed-cidr": "192.168.1.5/25",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "10.20.1.1",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["10.20.1.2","10.20.1.3"]
}

Docker の再起動後、設定が有効になります。

デフォルト・ブリッジ・ネットワークで IPv6 を使う

Docker で IPv6 サポートを使う設定をしたら( IPv6 を使う をご覧ください)、デフォルト・ブリッジ・ネットワークもまた IPv6 を自動的に設定します。ユーザ定義ブリッジとは異なり、デフォルト・ブリッジ上では IPv6 の無効化を選択できません。

次のステップ

参考

Use bridge networks
https://docs.docker.com/network/bridge/