オーバーレイネットワークの利用

読む時間の目安: 4 分

overlayネットワークドライバーは、複数の Docker デーモンホスト間での分散ネットワークを生成します。 このネットワークは、ホストに固有のものとして構築されたネットワークの最上位に位置(overlay)するものです。 このネットワークに対しては、コンテナー(Swarm サービスコンテナーを含む)が接続可能です。 暗号化が有効になっていれば、安全な通信を行うことができます。 Docker は、各パケットの送受信経路を透過的に取り扱い、その送受信先となる Docker ホストデーモンやコンテナーを適切に認識します。

Swarm の初期化を行うとき、あるいは Docker ホストを既存の Swarm に参加させるときには、そのホスト上に 2 つのネットワークが生成されます。

  • 1 つはingressと呼ばれるオーバーレイネットワークです。 これは Swarm サービスに関する制御とデータトラフィックを取り扱います。 Swarm サービスを生成する際に、ユーザー定義のオーバーレイネットワークへの接続を指定しない限り、デフォルトではingressネットワークに接続されます。
  • もう 1 つはdocker_gwbridgeと呼ばれるブリッジネットワークです。 これは、個々の Docker デーモンを、Swarm 内に参加している別のデーモンに接続するものです。

ユーザー定義のoverlayネットワークはdocker network createを使って生成することができます。 ユーザー定義のbridgeネットワークを生成する方法と同じです。 サービスやコンテナーは、一度に複数のネットワークに接続できます。 サービスやコンテナーがネットワーク通信を行うことができるのは、互いに接続されている場合だけです。

Swarm サービスとスタンドアロンコンテナーは、どちらもオーバーレイネットワークに接続することができます。 ただしデフォルトの動作や設定が目指しているものは、まったく異なります。 そこで、これ以降のトピックでは操作説明を以下のように分けます。 オーバーレイネットワークに対する全般的な操作、Swarm サービスネットワークに対する操作、スタンドアロンコンテナーにおいて利用されるオーバーレイネットワークに対する操作です。

オーバーレイネットワークに対する全般的な操作

オーバーレイネットワークの生成

前提条件

  • オーバーレイネットワークを使った Docker デーモン用のファイアーウォールルール

    オーバーレイネットワーク上に参加する Docker ホスト間でのトラフィックのやりとりのため、以下のポートを公開する必要があります。

    • TCP ポート 2377、クラスター管理に関する通信用。
    • TCP と UDP のポート 7946、ノード間の通信用。
    • UDP ポート 4789、オーバーレイネットワークトラフィック用。
  • オーバーレイネットワークを生成する前には、docker swarm initを使って Docker デーモンを Swarm マネージャーとして初期化するか、あるいはdocker swarm joinを使って既存の Swarm にホストを追加しておく必要があります。 どちらの場合でも、デフォルトのingressオーバーレイネットワークが生成されます。 このネットワークは、デフォルトで Swarm サービスが利用するものです。 Swarm サービスを利用するつもりがなくても、これを行っておくことが必要です。 この後には、ユーザー定義のオーバーレイネットワークを追加生成することができます。

Swarm サービスに対して利用するオーバーレイネットワークを生成するには、以下のようなコマンドを実行します。

$ docker network create -d overlay my-overlay

オーバーレイネットワークを生成する目的が、Swarm サービスにおいて利用するだけでなく、スタンドアロンコンテナー においても 利用することが必要な場合で、他の Docker デーモン上で動作する他のスタンドアロンコンテナーとも通信を行う必要がある場合は、--attachableフラグを加えます。

$ docker network create -d overlay --attachable my-attachable-overlay

IP アドレス範囲、サブネット、ゲートウェイ、その他のオプションを指定することができます。 詳しくはdocker network create --helpを確認してください。

オーバーレイネットワーク上のトラフィック暗号化

Swarm サービスの管理トラフィックは、デフォルトにおいて、GCM モードの AES アルゴリズム を使ってすべて暗号化されます。 Swarm 内のマネージャーノードは、ゴシップデータ(gossip data)の暗号化に利用する鍵を 12 時間ごとにローテートして利用します。

アプリケーションデータを暗号化するには、オーバーレイネットワークの生成時に--opt encryptedを指定します。 これにより vxlan レベルの IPSEC 暗号化が実現します。 この暗号化を利用すると、性能劣化が無視できない程度に発生します。 したがって本番環境での利用を行うには、あらかじめ十分にテストを行っておく必要があります。

オーバーレイにおいて暗号化を有効にすると、Docker はノード間のすべてに IPSEC トンネルを生成して、 オーバーレイネットワークにアタッチされたサービスに応じて、タスクをスケジューリングします。 このトンネルは GCM モードでの AES アルゴリズムを利用するので、マネージャーノードは 12 時間ごとに鍵のローテートを自動的に行います。

Windows ノードは暗号化されたオーバーレイネットワークにアタッチしないでください。

オーバーレイネットワークの暗号化は Windows 上においてはサポートされていません。 暗号化されたオーバーレイネットワークに Windows ノードを接続しようとすると、エラーは発生しませんが、ただしそのノードは通信することができません。

Swarm モードのオーバーレイネットワークとスタンドアロンコンテナー

オーバーレイネットワーク機能を利用する際に--opt encrypted --attachableを同時に指定すれば、このネットワークに対して、管理外にあったコンテナーをアタッチさせることができます。

$ docker network create --opt encrypted --driver overlay --attachable my-attachable-multi-host-network

デフォルトの ingress ネットワークのカスタマイズ

ほとんどのユーザーにとってingressネットワークをカスタマイズする必要はありません。 ただし設定を変更することは可能です。 たとえば自動的に設定されるサブネットが、ネットワーク上にすでにあるものとコンフリクトした場合には、設定が必要になります。 また MTU のような低レベルのネットワーク設定を行う場合にも必要です。

ingressネットワークをカスタマイズするには、いったん削除して再生成することが必要です。 通常は Swarm 上にサービスを生成する前に、これを行います。 ポートを公開しているサービスがある場合は、ingressネットワークを削除する前に、そのサービスを削除しておく必要があります。

ingressネットワークが存在していない間、ポートを公開していないサービスであれば機能しますが、ただし負荷分散は行われません。 この状況は、WordPress サービスのようにポート 80 を公開しているサービスに影響を及ぼします。

  1. docker network inspect ingressを実行してingressネットワークを調べます。 そして、これに接続しているコンテナーのサービスをすべて削除します。 このサービスとは WordPress サービスにように、ポートを公開しているものです。 こういったサービスを停止し忘れていると、次の作業が失敗します。

  2. 既存のingressネットワークを削除します。

    $ docker network rm ingress
    
    WARNING! Before removing the routing-mesh network, make sure all the nodes
    in your swarm run the same docker engine version. Otherwise, removal may not
    be effective and functionality of newly created ingress networks will be
    impaired.
    Are you sure you want to continue? [y/N]
    
  3. --ingressフラグを使って、新たなオーバーレイネットワークを生成します。 カスタマイズしたいオプションがあれば設定しておきます。 以下の例では MTU を 1200、サブネットを10.11.0.0/16、ゲートウェイを 10.11.0.2にそれぞれ指定しています。

    $ docker network create \
      --driver overlay \
      --ingress \
      --subnet=10.11.0.0/16 \
      --gateway=10.11.0.2 \
      --opt com.docker.network.driver.mtu=1200 \
      my-ingress
    

    メモ

    生成するingressネットワークの名前はingress以外にすることも可能です。 ただし生成できるのは 1 つだけであり、2 つめを生成しようとしても失敗します。

  4. 1 つめの手順で停止させていたサービスを再起動します。

docker_gwbridge インターフェースのカスタマイズ

docker_gwbridgeは仮想ブリッジであり、(ingressネットワークを含む)オーバーレイネットワークを、個々の Docker デーモンにおいて稼動する物理ネットワークに接続します。 Docker では、Swarm を初期化するとき、あるいは Docker ホストを Swarm に参加させるときに、この仮想ブリッジを自動生成します。 ただしこれは Docker のデバイスではありません。 Docker ホストのカーネル内に存在するものです。 これに対する設定が必要な場合は、Docker ホストを Swarm に参加させる前、あるいはホストを一時的に Swarm から削除してから設定を行う必要があります。

  1. Docker を停止します。

  2. 既存のdocker_gwbridgeインターフェースを削除します。

    $ sudo ip link set docker_gwbridge down
    
    $ sudo ip link del dev docker_gwbridge
    
  3. Docker を起動します。 Swarm への参加、あるいは初期化は行いません。

  4. docker_gwbridgeブリッジへのカスタマイズを行った上で、これを手動で再生成します。 これはdocker network createコマンドを使って行います。 以下の例では、サブネットを10.11.0.0/16に指定しています。 カスタマイズ可能なオプションについては、ブリッジドライバーのオプション を参照してください。

    $ docker network create \
    --subnet 10.11.0.0/16 \
    --opt com.docker.network.bridge.name=docker_gwbridge \
    --opt com.docker.network.bridge.enable_icc=false \
    --opt com.docker.network.bridge.enable_ip_masquerade=true \
    docker_gwbridge
    
  5. Swarm の初期化、あるいは Swarm への参加を行います。 ブリッジが存在するので、Docker は自動設定にもとづくブリッジの生成は行いません。

Swarm サービスに対する操作

オーバーレイネットワーク上でのポート公開

同一のオーバーレイネットワークに接続された Swarm サービスは、全ポートを互いに公開します。 外部のサービスからアクセス可能な 1 つのポートがあるなら、そのポートはdocker service createdocker service updateを実行するときの-pまたは--publishフラグを使って、公開に しておかなければなりません。 指定の際には、かつてのコロン区切りの文法と、最新のカンマ区切りによる文法がともにサポートされます。 わかりやすくするために、長い文法を用いることが好まれています。

フラグ値 内容説明
-p 8080:80 または
-p published=8080,target=80
サービス上の TCP ポート 80 をルーティングメッシュ上のポート 8080 にマッピングします。
-p 8080:80/udp または
-p published=8080,target=80,protocol=udp
サービス上の UDP ポート 80 をルーティングメッシュ上のポート 8080 にマッピングします。
-p 8080:80/tcp -p 8080:80/udp または
-p published=8080,target=80,protocol=tcp -p published=8080,target=80,protocol=udp
サービス上の TCP ポート 80 をルーティングメッシュ上のポート 8080 にマッピングします。 またサービス上の UDP ポート 80 をルーティングメッシュ上のポート 8080 にマッピングします。

Swarm サービスにおけるルーティングメッシュの停止

ポートを公開している Swarm サービスは、デフォルトでルーティングメッシュ(routing mesh)を利用します。 Swarm ノードのいずれかの公開ポートに接続すると(指定のサービスが動作しているかどうかには関係なく)、そのサービスが動作しているワーカーノードにリダイレクトされます。 Swarm サービスに対して、Docker が効率よくロードバランサーのように動作します。 ルーティングメッシュを利用するサービスは、仮想 IP モード(virtual IP mode)として稼動します。 各ノード上に稼動する別サービスであっても(--mode globalフラグにより)ルーティングメッシュを利用します。 ルーティングメッシュを利用した場合、クライアントが要求するノードサービスがどれになるかは保証されません。

ルーティングメッシュを停止するには、サービスを DNS ラウンドロビン(DNS Round Robin; DNSRR)モードで起動します。 これは --endpoint-modednsrrを設定することで実現します。 サービスに対しては独自にロードバランサーを稼動させる必要があります。 Docker ホスト上のサービス名に対する DNS 問い合わせは、サービスを実行しているノードの IP アドレス一覧を返します。 ロードバランサーがこの一覧を解釈し、ノード間のトラフィックを調整するように設定を行ってください。

制御情報とデータのトラフィック分離

Swarm の管理に関連する制御情報のトラフィックと、アプリケーションの動作において発生するトラフィックは、同じネットワーク上でやりとりされます。 なお Swarm の制御情報トラフィックは暗号化されています。 Docker では、この異なる種類のトラフィックを、別々のネットワークインターフェースに分けて取り扱う設定が可能です。 Swarm の初期化時あるいは Swarm への参加時に--advertise-addr--datapath-addrをそれぞれ指定します。 Swarm に参加させるノードに対しては、必ずこれを行わなければなりません。

オーバーレイネットワーク上のスタンドアロンコンテナーに対する操作

オーバーレイネットワークへのスタンドアロンコンテナーのアタッチ

ingressネットワークを--attachableフラグの指定をせずに生成すると、Swarm サービスだけがこれを利用できるようになり、スタンドアロンコンテナーは利用できません。 スタンドアロンコンテナーの場合は、ユーザー定義のオーバーレイネットワークを--attachableフラグにより生成すれば、接続ができます。 このようにすれば、スタンドアロンコンテナーを、さまざまな Docker デーモン上に起動させることが可能であり、 個別のデーモンホスト上にルーティングを設定することなく、通信が行えるようになります。

公開ポート

フラグ値 内容説明
-p 8080:80 コンテナー上の TCP ポート 80 をオーバーレイネットワーク上のポート 8080 にマッピングします。
-p 8080:80/udp コンテナー上の UDP ポート 80 をオーバーレイネットワーク上のポート 8080 にマッピングします。
-p 8080:80/sctp コンテナー上の SCTP ポート 80 をオーバーレイネットワーク上のポート 8080 にマッピングします。
-p 8080:80/tcp -p 8080:80/udp コンテナー上の TCP ポート 80 をオーバーレイネットワーク上のポート 8080 にマッピングします。またコンテナー上の UDP ポート 80 をオーバーレイネットワーク上のポート 8080 にマッピングします。

コンテナーの検出

接続先を指定するには、たいていの場合サービス名を用います。 サービスが負荷分散されていたり、サービスのもとにあるコンテナー(「タスク」)のすべてによって取り扱われていたりするからです。 サービスのもとにあるタスク全一覧を取得するには、tasks.<サービス名>に対して DNS 問い合わせを行ってください。

次のステップ

network, overlay, user-defined, swarm, service