dockerのAmbassadorパターンを理解する
前回と前々回で「単一のコンテナの起動」と、「2台のコンテナの起動と接続」について、ある程度理解した。 今回は2台のホスト(VM)にまたがるコンテナの接続について試す。 2台のホストにまたがる場合は、--linkによる接続はできない。これはひとつのホストにのっているDockerの中でのみ使える機能だからである。
まず定石は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の使い方がわかっただけ。