dockerのAmbassadorパターンを理解する

前回前々回で「単一のコンテナの起動」と、「2台のコンテナの起動と接続」について、ある程度理解した。 今回は2台のホスト(VM)にまたがるコンテナの接続について試す。 2台のホストにまたがる場合は、--linkによる接続はできない。これはひとつのホストにのっているDockerの中でのみ使える機能だからである。

参照: Dockerコンテナ接続パターン (2014年冬)

まず定石はAmbassadorパターンというものらしい。 他のホストとの接続だけを担うプロキシ機能しか持たないコンテナで軽量なものらしい。 ほかにも、いろいろあるらしいが、ひとまず定石であるAmbassadorパターンを理解しよう。

ちゃんとした例を考えるのが面倒くさいので、 今回も前回に引き続きhttpdとclientを例に使う。

構成は以下

ホスト コンテナ名 役割 expose/publishするポート リンク
VM1 httpd apacheサーバ 80 なし
httpd-amb ambassador 8080(publish) httpdコンテナにリンク
VM2 httpdclient クライアント なし httpdclient-ambコンテナにリンク
httpd-amb ambassador 80(expose) なし
ホスト IP
VM1 192.168.11.11
VM2 192.168.11.12

構成図

VM1[ httpdclient --- 80/tcp ---> httpd-amb ] --- 8080/tcp --> VM2[ httpd-amb -- 80/tcp --> httpd]

VM1: apacheサーバ+ambassadorを構築する

apacheサーバコンテナ作成する

# docker run --privileged -d --expose 80 --name httpd centos:centos7 /sbin/init
# docker exec -it httpd /bin/bash
[root@a4522c59ed0c /]#
[root@a4522c59ed0c /]# yum install httpd -y
[root@a4522c59ed0c /]# systemctl enable httpd.service
[root@a4522c59ed0c /]# systemctl start httpd.service
[root@a4522c59ed0c /]# exit

Ambassadorコンテナを作成する

Ambassadorコンテナの作成はイメージを持ってきて、あとはhttpdコンテナにlinkするだけで他に設定は不要。超簡単。

# docker run -d --link httpd:httd-alias --name httpd-amb -p 8080:80 svendowideit/ambassador

これでAmbassadorが8080ポートで受けた接続はコンテナ内では80ポートで受けて、それをhttpdの80ポートへそのまま流すことができるようになる。

現状確認。2つコンテナが実行されている。

# docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                NAMES
c06aaa97b55a        svendowideit/ambassador:latest   "\"/bin/sh -c 'env |   30 seconds ago      Up 29 seconds       0.0.0.0:80->80/tcp   httpd-amb           
9c4495ffddfd        centos:centos7                   "/sbin/init"           4 minutes ago       Up 4 minutes        80/tcp               httpd 
# telnet localhost 8080
GET /

VM2: httpクライアント+ambassadorを構築する

Ambassadorコンテナを作成する

docker run -d --name httpd_ambassador --expose 80 -e HTTPD_PORT_80_TCP=tcp://192.168.11.11:8080 svendowideit/ambassador

環境変数HTTPD_PORT_80_TCP=tcp://192.168.11.11:8080を渡しているのが肝だと思われる。 多分Ambassadorは渡された環境変数をパースして自分がプロキシすべきポートを判断する。(かなり適当な予想なので間違えっているかも。)

httpdクライアントを作成する

# docker run --privileged -d --link httpd_ambassador:httpd_ambassador-alias --name httpdclient centos:centos7 /sbin/init

現状確認。2つのコンテナが実行されている。

# docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS               NAMES
bcabc10a7506        centos:centos7                   "/sbin/init"           14 minutes ago      Up 14 minutes                           httpdclient         
e526511520fa        svendowideit/ambassador:latest   "\"/bin/sh -c 'env |   17 minutes ago      Up 17 minutes       80/tcp              httpd_ambassador

VM2: httpdクライアントからAmbassadorの80番ポートにアクセスしてWebページをゲットする。

準備が整ったので、ホストを隔てたhttpdへのアクセスができるか試す。

流れ - VM2のhttpdclientコンテナの中でbashを実行する - 環境変数からAmbassadorのIPアドレスを取得する - Ambassadorの80ポートへcurlでアクセスする

# docker exec -it httpdclient /bin/bash

[root@bcabc10a7506 /]# env
HTTPD_AMBASSADOR_ALIAS_PORT_80_TCP=tcp://172.17.0.26:80
HOSTNAME=bcabc10a7506
HTTPD_AMBASSADOR_ALIAS_PORT=tcp://172.17.0.26:80
HTTPD_AMBASSADOR_ALIAS_ENV_HTTPD_PORT_80_TCP=tcp://192.168.11.11:8080
HTTPD_AMBASSADOR_ALIAS_PORT_80_TCP_PORT=80
LS_COLORS=
HTTPD_AMBASSADOR_ALIAS_PORT_80_TCP_PROTO=tcp
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
container_uuid=bcabc10a-7506-1b55-74a8-7c9f0d2ec7dc
SHLVL=1
HOME=/root
HTTPD_AMBASSADOR_ALIAS_NAME=/httpdclient/httpd_ambassador-alias
LESSOPEN=||/usr/bin/lesspipe.sh %s
HTTPD_AMBASSADOR_ALIAS_PORT_80_TCP_ADDR=172.17.0.26
_=/usr/bin/env

[root@bcabc10a7506 /]# curl -s http://172.17.0.26 | head -1

いけた! まぁあんまりAmbassadorのありがたみが無い感もある. どちらかというと、Ambassadorの使い方がわかっただけ。