Docker の基本学習 ~ コンテナ間のリンク

  • 159
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

コンテナ間のリンク機能を調べてみた。ざっと見た感じ、同一ホスト上の他のコンテナのネットワーク情報(IPアドレスなど)が取得できるというもの。大した機能でない気がしたが、コンテナのIPアドレスは固定でないため、コンテナ間でネットワーク通信するためにはに必要な機能と思われる。ただ、リンクは同一ホスト上のコンテナ間でしか機能しないので、将来は複数ホストにまたがった方法が出てくるのかも。

(更新: 2015/11/08)
Docker 1.9 では、複数ホストにまたがる仮想ネットワーク機能が正式版としてリリースされました。
Docker : マルチホスト間での仮想ネットワーク

コンテナ間の通信

通常、コンテナ間でネットワーク通信をするには、ホスト側にマッピングしたポートを経由して接続をする。

例えば以下のような構成で、

Network1.jpg

図中の Container 1 が

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

のように起動されていた場合、Container 2 と 3 からは

http://10.0.0.10:12345

で Container 1 上の httpdにアクセスできる。

同一ホスト上の Container 2 からであれば、Container 1内に割り当てられた IPと Listenしているポートを使って

http://172.17.0.3:80

で直接アクセスできる。

なので、同一ホスト上のコンテナ間で通信したいだけであれば、コンテナ起動時に -p を使ってポートをホスト側へマッピングする必要は無い。

リンクとは?

同一ホスト上のコンテナ間で通信する際に、接続したい相手のネットワーク情報(IPアドレスなど)を取得する仕組み。次の2つの形で情報を取得できる。
・環境変数
・/etc/hosts ファイル

その1

まずは、簡単のために、接続先のコンテナを -p をつけて起動してみる
(ここで起動するコンテナは、ずっと ping を送るだけで、実際にポート80や22222をListenしているわけではない)。

docker run -d -p 80:80 -p 11111:22222 --name Container1 centos ping localhost

次に、接続元のコンテナを --link オプションを使って起動する。--link は、<接続先コンテナ名:エイリアス名>という形式で指定する。

docker run -it --name Container2 --link Container1:c1 centos /bin/bash

接続元コンテナ内から環境変数を表示すると、エイリアス名のついた環境変数が作られて、接続先の情報が入っていることが分かる。

[root@6e141d314d6e /]# env | grep C1 | sort
C1_NAME=/Container2/c1
C1_PORT=tcp://172.17.0.28:80
C1_PORT_22222_TCP=tcp://172.17.0.28:22222
C1_PORT_22222_TCP_ADDR=172.17.0.28
C1_PORT_22222_TCP_PORT=22222
C1_PORT_22222_TCP_PROTO=tcp
C1_PORT_80_TCP=tcp://172.17.0.28:80
C1_PORT_80_TCP_ADDR=172.17.0.28
C1_PORT_80_TCP_PORT=80
C1_PORT_80_TCP_PROTO=tcp

また、/etc/hosts に接続先のエントリが追加される。

[root@14607f30b721 /]# cat /etc/hosts
(中略・・・)
172.17.0.28     c1 ab33c4d9897b Container1

その2

その1では、コンテナ内のポートをホスト側へマッピングしたが、今度はマッピングしないで試してみる。

まずは、接続先イメージ用のDockerfileを作成する。EXPOSE でポート 80 を指定する。

FROM centos:6.6
RUN yum install httpd -y
ENTRYPOINT /usr/sbin/apachectl -DFOREGROUND
EXPOSE 80

ビルドする。

docker build -t arturias/test .

接続先コンテナを起動。今度は -p や -P は指定しない。

docker run -d --name Container1 arturias/test

接続元コンテナを起動。

docker run -it --name Container2 --link Container1:c1 centos /bin/bash

環境変数を表示すると接続先の情報が見える。

[root@202f8d6ba925 /]# env | grep C1
C1_NAME=/trusting_mclean/c1
C1_PORT=tcp://172.17.0.26:80
C1_PORT_80_TCP=tcp://172.17.0.26:80
C1_PORT_80_TCP_ADDR=172.17.0.26
C1_PORT_80_TCP_PORT=80
C1_PORT_80_TCP_PROTO=tcp

接続元コンテナから httpdにアクセスしてみる(c1 は /etc/hosts に追加されたエントリ)。

curl c1

なお、ホスト側にポートをマッピングしていないので、別ホスト上のコンテナからはhttpdにアクセスできない。

その3

接続元から取得できるのはネットワーク情報だけでなく、接続先で定義された環境変数も取得できる。

例えば、接続先コンテナを以下のように起動。-e オプションで環境変数を2つ指定している。

docker run -d --name Container1 -e PARAM1=100 -e PARAM2=200 centos ping localhost

接続元コンテナを起動して、環境変数を表示(今回は、env コマンドを実行してすぐに終了するようにしてみた)。

[ec2-user@ip-10-0-0-73 ~]$ docker run --rm --link Container1:c1 centos env
(中略・・・)
C1_ENV_PARAM1=100
C1_ENV_PARAM2=200