コンテナ間のリンク機能を調べてみた。ざっと見た感じ、同一ホスト上の他のコンテナのネットワーク情報(IPアドレスなど)が取得できるというもの。大した機能でない気がしたが、コンテナのIPアドレスは固定でないため、コンテナ間でネットワーク通信するためにはに必要な機能と思われる。ただ、リンクは同一ホスト上のコンテナ間でしか機能しないので、将来は複数ホストにまたがった方法が出てくるのかも。
(更新: 2015/11/08)
Docker 1.9 では、複数ホストにまたがる仮想ネットワーク機能が正式版としてリリースされました。
Docker : マルチホスト間での仮想ネットワーク
コンテナ間の通信
通常、コンテナ間でネットワーク通信をするには、ホスト側にマッピングしたポートを経由して接続をする。
例えば以下のような構成で、
図中の 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