Update 2014-08-06
: DockerのHTTP Routing - Part9: xip.io と OpenResty で動的リバースプロキシUpdate 2014-08-07
: DockerのHTTP Routing - Part10: xip.io と Hipache で動的リバースプロキシ
以下のサイトを参考に、confdとNginxで動的リバースプロキシを作成してみます。
特にconfdは新しいテンプレートを使いたいので、0.6.0-alpha1
を利用しています。
- Experimenting with CoreOS, confd, etcd, fleet, and CloudFormation
- Automated Nginx Reverse Proxy for Docker
- confd 0.6.x
xip.ioのサブドメインにリバースプロキシ先のポート番号をprefixして、Nginxは80ポートで複数のserver_name
に応答することができます。
データコンテナの作成
Dockerfileを作成します。VOLUMEに格納するディレクトリを書きます。nsenterでアタッチするときにbashが必要になるので、busyboxではなくubuntuにしました。
FROM ubuntu:trusty |
イメージをビルドします。
$ docker build -t masato/confd-data . |
データコンテナを起動します。
$ docker run --name confd-data -i -t -d masato/confd-data /bin/bash |
condの設定
nsenterを使い、データコンテナにアタッチします。
前回作成した~/bin/docker-nester
コマンドを使います。
$ docker-nsenter cd887aad372d |
データコンテナに/etc/confd/conf.d/nginx.toml
ファイルを作成します。まずディレクトリの作成から。
# mkdir -p /etc/confd/conf.d |
nginx.tomlファイルを作成します。
myapp1とmyapp2のサブドメイン毎に2つ設定します。これは0.6.xから採用された書式です。
[template] |
myapp2サブドメイン用のTOMLファイルです。
[template] |
DockerのHTTP Routing - Part7: Nginx multiple upstreamsで調べた書き方で、Nginxの設定ファイルのテンプレートを作成します。0.6.x
からgetv
とgetvs
が使えます。
Goのtext/templateを使っていますが、Railsに慣れていると表現力が乏しいです。特にconfdではユーザー定義関数のFuncMapが自分で追加できないので不便です。テンプレート内ではパスを操作したい場合があるので、strings.Splitも追加して欲しいです。
upstream {{getv "/subdomain"}} { |
Nginx + etcd + confdのイメージを作成
今回作成したDockerfileです。etcd, confd, Nginxを1つのコンテナにインストールして使います。
etcdのインストールはいろいろ方法がありますがGOPATHを指定してからgo get
することにします。
confdもgo get
したかったのですがGitHubからタグをしてしてインストールできないようなので、バイナリをダウンロードします。
0.6.x Quick Start Guideで採用された書式を利用します。
FROM dockerfile/supervisor |
Nginx + etcd + confdンテナの起動
データコンテナを--volumes-from
に指定して、Nginxのコンテナを起動します。
$ docker run --name nginx-confd -d -p 80:80 --volumes-from confd-data masato/nginx-confd |
起動したコンテナのIPアドレスを確認します。
$ docker inspect 095b93ed0e25 | jq -r '.[0].NetworkSettings.IPAddress' |
etcdの動作確認
Dockerホストからetcdへputとgetのテストをします。
$ curl -L http://172.17.0.209:4001/v2/keys/mykey -XPUT -d value="this is awesome" |
Dockerホストのetcdctlからもpeers
を指定して確認してみます。etcdクラスタに参加しないので、-no-sync
オプションを指定します。
$ etcdctl -C "172.17.0.209:4001" -no-sync get /mykey |
Sinatraコンテナを2つ起動
Sinatraのサンプルアプリはmarceldegraaf/sinatraを利用します。それぞれポートは5001と5002にマッピングします。
$ docker pull marceldegraaf/sinatra |
Sinatraコンテナをconfdに登録
DockerホストからNginxコンテナのIPアドレスを確認します。
$ docker-get-ip 095b93ed0e25 |
5001ポートでリバースプロキシするSinatraコンテナのIPアドレスを確認します。
$ docker-get-ip b6ea1bb67b7f |
5002ポートでリバースプロキシするSinatraコンテナのIPアドレスを確認します。
$ docker-get-ip 93f545c79ce0 |
etcdctlコマンドで動的にルーティングを設定します。Dockerホストのetcdはクラスタに参加しないため-no-sync
を指定します。
/myapp1/subdomain
のキーに、upstreamの名前を登録します。/myapp1/upstream
のキーに、upstream先のserverのIPアドレスとポートを登録します。
$ etcdctl -C "172.17.0.209:4001" -no-sync set /myapp1/subdomain p5001 |
確認
xip.ioを使い、NginxからSinatraアプリへ動的リバースプロキシができました。
$ curl p5001.10.1.2.164.xip.io |
confdが作成した、myapp1(p5001サブドメイン)用のNginxの設定ファイルです。
upstream p5001 { |
confdが作成した、myapp2(p5002サブドメイン)用のNginxの設定ファイルです。
upstream p5002 { |
まとめ
- DockerのHTTP Routing: Part1: Service Discovery
- DockerのHTTP Routing: Part2: リバースプロキシ調査
- DockerのHTTP Routing - Part3: OpenResty はじめに
- DockerのHTTP Routing - Part4: xip.io と Nginx と Node.js
- DockerのHTTP Routing - Part5: xip.io と bouncy と XRegExp
- DockerのHTTP Routing - Part6: confd はじめに
- DockerのHTTP Routing - Part7: Nginx multiple upstreams