コンテナ構成の変更に伴うロードバランサ(例えばnginx)設定の変更にconsul, consul-template, registrator を使っておりますが、なかなか快適です。
一点だけ不満だったのが、Registrator をデフォルトの設定で起動すると、serviceのAddress/Portがコンテナ内ではなくホストネットワーク用のものが生成されるため、ロードバランサ自体をコンテナとして運用している場合にうまいこと consul-template を作るのが難しいことでした。
例) .ID
のパターンから正規表現でホスト名を抜き出すという汚い事をやっていた
upstream hogehoge_web {
{{range service "hogehoge_web"}}server {{.ID | regexReplaceAll "^.*?:(.*?):.*?$" "$1"}}:3000 max_fails=3 fail_timeout=10 weight=1;
{{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
こんなおかしな設計のはずがないと思い、Registratorのソースを確認したところ、きちんと --internal=true
というオプションが用意されており、これをつけて起動すればコンテナ側で利用できるAddress/Portを登録してくれるようです。
docker-compose.ymlの記述例)
consul:
image: gliderlabs/consul-server
command: "-bootstrap"
ports:
- 8300:8300
- 8400:8400
- 8500:8500
- 8600:8600/udp
registrator:
image: gliderlabs/registrator:latest
command: --internal=true --ttl=120 --ttl-refresh=30 consul://consul:8500
volumes:
- /var/run/docker.sock:/tmp/docker.sock
links:
- consul
Registratorを--internal=true
で使う場合、net: host
になっていると内向きと外向きの両方のサービスが二重に登録されてしまって気持ちが悪いので、ブリッジにしています。
これで以下のように素直な記述ができます。
upstream hogehoge_web {
{{range service "hogehoge_web"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=10 weight=1;
{{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
素晴らしい。