tl;dr
この記事では、dockerとconsulを使ってスケーラビリティを高めた環境を構築する手順を説明します。
ざっくりで色々と端折っているところがあります。
docker-compose scale web=5
のように、簡単にサーバーを増やせたりする運用が可能になります。
ネットワークの作成
consul用とmastodon用で異なるdocker-compose.ymlを使うので、同じネットワークが必要になるため予め作っておきます。
docker network create consul-network
consulを使う
consulは docker-nginx-lb を使います。こちらmastodonとは関係ないディレクトリにgit cloneしてきます。
docker-compose.ymlの編集
このリポジトリには、docker-compose.ymlが含まれているので、 少し編集します。
networks:
default:
external:
name: consul-network
を追加し、先ほど作成したネットワークに接続します。
nginx.confの編集
リポジトリに含まれているnginx.confを編集します。
テンプレートになっており、rangeと書いてある部分に自動的にserver
が追加されていきます。
mastodon.web
や mastodon.streaming
は Tag:Name
の関係になっています。
streamingはWebsocketとして読めるように修正します。
- upstream web {
+ upstream app {
least_conn;
- {{range service "production.app"}}server {{.Address}}:{{.Port}} max_fails=3
+ {{range service "mastodon.web"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
{{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
server {
- listen 80 default_server;
+ listen 3000 default_server;
+ client_max_body_size 10m;
location / {
- proxy_pass http://app;
+ proxy_pass http://web;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
+ upstream streaming {
+ least_conn;max_fails=3
+ {{range service "mastodon.streaming"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
+ {{else}}server 127.0.0.1:65535; # force a 502{{end}}
+ }
+
+ server {
+ listen 4000 default_server;
+ client_max_body_size 10m;
+
+ location / {
+ proxy_pass http://streaming;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ }
+ }
mastodon側の修正
docker-compose.ymlの編集
同じように、ネットワークに接続させます。
もしもすでにサービスを稼働している場合、ネットワークが変更されるのでIPアドレスに注意してください。
networks:
default:
external:
name: consul-network
を追加し、先ほど作成したネットワークに接続します。
一度実行してみる
ここまできたら、mastodon
と docker-nginx-lb
それぞれで docker-compose up --build
します。 ホスト側で http://(ホストIP):8500
にアクセスし、Consul UI にアクセスします。
このように表示されたら、Consulが正しく動いています。
環境変数の設定
docker-nginx-lb
の docker-compose.yml
では、 registrator
も一緒に動くようになっているので、環境変数に
environment:
SERVICE_NAME: web
SERVICE_3000_NAME: web
SERVICE_TAGS: mastodon
と定義されているコンテナを見つけると、サービスとして登録してくれます。 一つだけポートが開いているサーバーの場合は、 name
という形式のサービス名で登録され、 複数のポートが空いている場合 は name-3000(Name-Port)
という形式で登録されるので注意が必要です。(また、名前に アンダーバー_ は使用できません)
webの修正
environment:
SERVICE_NAME: web
SERVICE_3000_NAME: web
SERVICE_TAGS: mastodon
streamingの修正
environment:
SERVICE_NAME: streaming
SERVICE_4000_NAME: streaming
SERVICE_TAGS: mastodon
修正し起動させると、 registrator が serviceを見つけてconsulに登録してくれます。
consulはserviceが変更された通知を受け取ると、nginxのconfを自動的に上書きし、nginxを自動的にリロードします。
デプロイ(参考程度)
docker-compose build
docker-compose scale web=10
docker-compose ps | grep "mastodonto_web_[1-5] " | awk '{print $1}' | xargs docker stop
docker-compose up --build --force-recreate -d web
docker-compose scale web=5
おまけ
実際にこの構築手順で作ったインスタンスこちらです。
おもったよりお魚が集まらなかったので終了しました。