LoginSignup
35
36

More than 5 years have passed since last update.

Docker の基本学習 ~ マルチホストでのコンテナ間通信

Last updated at Posted at 2015-06-14

複数のホストに配置されたコンテナ間のネットワーク通信についてまとめてみる。

(更新: 2015/11/08)
Docker 1.9 では、複数ホストにまたがる仮想ネットワーク機能が正式版としてリリースされました。今後は、この記事で書かれている方法より、そちらの機能を使うほうが主流になるかもしれません。
Docker : マルチホスト間での仮想ネットワーク

マルチホストにおける Docker のネットワークの課題

以下の図で、ホスト1上のContainer1からホスト2上のContainer2(httpdが動作)に接続したいとする。

docker-multi-host-network.png

Container2 が次のように起動している場合、

docker run -d -p 80:80 <イメージ名>

Containe1 からは、「ホスト2のアドレス」を使って 10.0.0.2:80 にアクセスすれば Container2 の httpd と通信ができる。

これはとても単純な方法だがいつくか課題がある。

1. 接続先のコンテナが別のホストで起動された場合、接続先のアドレスが変わってしまう

仮想マシン(VM)の場合は VM自体に割り当てられたIPアドレスに接続するため、VM 別のホストに移動しても接続先のアドレスは変わらない。しかし、上記のコンテナの接続方法では、ホストが変わる度に接続先のアドレスが変わり、接続元コンテナの設定を変えたりコンテナの再起動が必要になる。これは実用に耐えない。

2. コンテナ名で接続できない

同一ホスト間のコンテ間通信であれば Link の機能を使いコンテナ名で接続をすることができたが、マルチホストではIP/ポートの指定が必要になってしまう。

解決方法

かなり多くの手法があるようで把握できてないが、例えば次ようなものがあるらしい。

  • 別ホストへ接続するための専用コンテナを介して接続をする
    • Ambassador パターン (Static)
    • Ambassador パターン (Dynamic)
  • コンテナに DHCP や Static IP で IP アドレスを割り当てる
  • コンテナ間を接続する仮想ネットワークを構築する

Ambassador パターン(Static) ~ 概要

ここでは、Docker の公式ドキュメントでも紹介されている基本パターンの Ambassador パターンをまとめる。 これは、他のホストと接続する Proxy の役割をするコンテナ(Ambassasdor と呼ばれる)を立てて、それを介して通信する。

ambassador_static.png

Ambassadorは接続先(ホストのIPとポート)を知っており、http client コンテナは Ambassador と Link 接続して、Ambassador に HTTPリクエストを送るとそれが接続先に転送される。

これにより、例えば http client コンテナは接続先を知らなくてもよくなり、また、Ambassador のコンテナ名を使ってHTTPリクエストを送れるようになる。 しかし、Ambassador が接続先ホストを知っている必要がある(Static に紐付けられている)ため、Ambassador だけ再起動すれば済むようにはなったが依然として問題は残る。

いちおう、Ambassador パターンを試す手順を以下にまとめておく。

Ambassador パターン(Static) ~ 手順

事前準備

接続先(ホスト2)で、テスト用イメージ(Webサーバー)を作成。
Dockerfile を作る。

FROM centos:6.6
MAINTAINER arturias <arturias@example.com>
RUN yum install httpd -y
EXPOSE 80
ENTRYPOINT /usr/sbin/apachectl -DFOREGROUND

イメージをビルド。

$ docker build -t arturias/httpd .

接続先(ホスト2)でのコンテナ起動

作成したWeb サーバーのイメージから、コンテナを起動。
※ -p や -P は指定してないことに注意。

$ docker run -d --name web arturias/httpd

次に、Ambassador を起動。Ambassador として動作するイメージ(svendowideit/ambassador)が公開されているのでそれを使っている。
※ なお、ここでは -p でポート80を公開する。

$ docker run -d --link web:web -p 80:80 --name web_amb svendowideit/ambassador

接続元(ホスト1)でのコンテナ起動

Ambassador を起動。--export でHTTPクライアントに公開するポート、-e で接続先の Ambassador を指定。

$ docker run -d --name web_amb --expose 80 -e WEB_PORT_80_TCP=tcp://10.0.0.2:80 svendowideit/ambassador

HTTPクライアントとなるコンテナを起動して接続する。

$ docker run -it --link web_amb:web centos /bin/bash

LINK 機能により環境変数がセットされるため、それを使って Ambassador にリクエストを送る。

[root@2778fe65cd9b /]# env
WEB_PORT=tcp://172.17.0.3:80
WEB_PORT_80_TCP=tcp://172.17.0.3:80
WEB_PORT_80_TCP_ADDR=172.17.0.3
WEB_PORT_80_TCP_PORT=80
(略)

[root@2778fe65cd9b /]# curl http://${WEB_PORT_80_TCP_ADDR}:${WEB_PORT_80_TCP_PORT}
35
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
36