以前から興味のあったロードバランサーをdockerで構築。
Contents
ロードバランサーとは?
定義
主にwebサーバーの処理を分散させる仕組みで、そのために処理を振り分けることをさします。
通常は リクエスト→webサーバーという流れですが、
ロードバランサーを入れると リクエスト→ロードバランサー→webサーバー(通常は2台以上のことが多いです。)
のようになります。
メリット
負荷軽減
一般的には高負荷状態のシステムに対して組まれることが多く、サーバーを2台以上にすることで1台1台の負荷を軽減することができます。
可用性の向上
1台のサーバーがダウンしても、他のサーバーが生きていれば、システムが継続して稼働できるようになります。このような性質のことを可用性と呼びます。
拡張性の向上
サーバーを増やしたりすることでシステムの規模を拡張させることが容易になります。
デメリット
コスト増加
当たり前ですが、サーバーの数だけ、サーバー費用がかかります。またメンテナンスの手数も増えることになります。
実装上の変更が必要
複数のサーバーからアクセスすることになるので、特定のサーバーにしかないリソースへのアクセスをしている実装は変更する必要があります。
具体的にはセッションの保存に関してサーバーではなく、DBで保存するようにしましょう。また画像ファイルやその他、動的に生成させるファイルなどもサーバーにおかず、共通のサーバーかあるいはS3のようなクラウドサービスで管理する必要があります。
またGitで反映するときにも同時に反映できるようにスクリプトを組んだりする必要があります。
参考リンク
わわわIT用語辞典 ロードバランサ (load balancer)
実装
例えばテストで実際にAWSやVPCを立てるのは面倒なので、dockerを使うのが一番お手軽だと思います。
https://github.com/umanari145/load_balancer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
. ├── README.md ├── balancer │ └── nginx.conf ├── docker │ ├── web1 │ │ ├── Dockerfile │ │ └── default.conf │ └── web2 │ ├── Dockerfile │ └── default.conf ├── docker-compose.yml ├── web1 │ └── index.html └── web2 └── index.html |
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
version: '3' services: balancer: container_name: 'balancer' image: nginx volumes: - ./balancer/nginx.conf:/etc/nginx/nginx.conf ports: - 8080:80 networks: - balancer web1: container_name: 'web1' build: context: "./docker/web1" dockerfile: "Dockerfile" volumes: - ./web1:/var/www/html ports: - 7000:80 networks: - balancer web2: container_name: 'web2' build: context: "./docker/web2" dockerfile: "Dockerfile" volumes: - ./web2:/var/www/html ports: - 7001:80 networks: - balancer networks: balancer: driver: "bridge" |
balancer/nginx.conf
実際に処理を振り分けるnginxの処理を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
events { worker_connections 16; } http { upstream balancer.local { server web1; server web2; } server { listen 80; location / { proxy_pass http://balancer.local; } } } |
上記のような書き方だと処理が交互に分散されますが、2:1で振り分けるなど等分ではない振り分け方などもあります。
docker/web1/Dockerfile(web2も同様)
1 2 3 |
FROM nginx COPY default.conf /etc/nginx/conf.d/default.conf |
docker/web1/default.conf(web2も同様)
1 2 3 4 5 6 7 8 9 10 |
server { listen 80; server_name localhost; location / { root /var/www/html; index index.html index.htm; } } |
web1/index.html
(web2も同様ですが、テストでは均等にアクセスしているかを検証するために違う文字を入れるのもありです。)
1 2 3 4 5 6 |
<!DOCTYPE html> <html> <body> <p>webserver1</p> </body> </html> |
Docker でロードバランサ・アプリケーションサーバ・DBサーバの環境構築
実践編ーDockerを使ってnginxでリバースプロキシを立ててみる
(ロードバランサーではなくリバースプロキシですが、参考になりました。)