概要
docker Swarm には Ingress という機能がありこれを使うことで分散配置されたコンテナにどのコンテナホストからもアクセスすることができるようになります
エンドポイントも複数に分散してしまいます
今回は Ingress の更に上にロードバランサを設けて Ingress で publish したポートを一つのエンドポイントでアクセスする方法を紹介します
環境
- macOS 10.14.5
- Vagrant 2.1.1
- Ubuntu 16.04 LTS
- docker 18.09.7
準備
この手順 で docker Swarm 環境を構築しました
また今回は Ingress 用のバランサも作る必要があるので VM を 3 台にしています
Swarm クラスタが 2 台で残り 1 台はクラスタに入れないようにします
stack deploy
まずは stack deploy でコンテナを作成しましょう
クラスタ内のコンテナホストは 2 台なのでそれぞれにコンテナができるように replicas: 2
にしましょう
vim docker-compose.yml
version: '3.4'
services:
nginx:
image: valian/nginx-test-page
ports:
- "80:80"
deploy:
replicas: 2
docker stack deploy -c docker-compose.yml test
docker stack ls
docker service ls
docker stack ps test
curl vm01
vm02 からもコンテナにアクセスできることを確認しましょう
ingress サーバからバランシングする (nginx)
やり方はいろいろあると思いますが今回は nginx を使ってみます
新たに追加した vm03 サーバをロードバランサにします
vim default.conf
server {
listen 80;
location / {
proxy_pass http://test;
}
}
upstream test {
server 172.28.128.3;
server 172.28.128.4;
}
vm01 と vm02 は IP で指定しています
バランシングする nginx コンテナから Swarm クラスタ内のコンテナホストにアクセスします
その際に名前を引けないので IP を指定しています
nginx コンテナを起動しましょう
docker run -d -p 80:80 -v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf --name web nginx
vm03 にアクセスして Ingress と通して vm01 と vm02 に配置されたコンテナにアクセスできることを確認します
curl vm03
片方のコンテナをダウンさせてみる
今回 stack deploy で 2 台のコンテナを起動させています
インシデントのシミュレーションとして片方のコンテナをダウンさせてみます
vm01 or vm02 のコンテナホストにログインして直接コンテナを停止してみましょう
docker stop 0dfc9f942286
curl vm03
を続けていると挙動を確認できます
デフォルトの nginx の状態だとダウンしたコンテナにもリクエストを投げてしまうのでたまに 502 になるのが確認できます
stack deploy の場合 replicas: 2
で指定したコンテナ数以下になると自動でコンテナを再作成するのでそのうち 502 は発生しなくなります
502 を発生させないようにするには基本的には nginx を haproxy に置き換えるのが良いと思います
ingress サーバからバランシングする (haproxy)
ということで haproxy もやってみたいと思います
先程同様に vm03 上で動作させます
vim haproxy.cfg
frontend web_proxy
default_backend test
bind *:80
backend test
option redispatch
retries 3
server vm01 172.28.128.3:80 weight 1
server vm02 172.28.128.4:80 weight 1
redispatch を指定することでダウンしたコンテナにアクセスしないようにします
docker run -d -p 80:80 -v $(pwd)/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg --name web haproxy
起動して動作確認しましょう
while true:; do curl vm03; sleep 1; done
これで先程同様にコンテナを停止してみましょう
すると 502 は出ずにコンテナが再作成されるまで片方のコンテナにだけアクセスし続けるのが確認できると思います
おまけ: クラスタ内のコンテナホストの IP を取得する方法
for NODE in $(docker node ls --format '{{.Hostname}}'); do echo -e "${NODE} - $(docker node inspect --format '{{.Status.Addr}}' "${NODE}")"; done
おまけ: dockerd のジャーナルログの確認
sudo journalctl -u docker
tail したい場合は -f
オプションも使います
ただ今回の動作確認のようなコンテナのダウンや再作成のログは表示されないようです
表示させたい場合はログレベルを debug にする必要があります
sudo vim /etc/docker/daemon.json
sudo kill -SIGHUP $(pidof dockerd)
最後に
docker Swarm の Ingress の機能で publish したポートを更にロードバランサで分散してみました
nginx と haproxy を使ってみましたが基本は haproxy を使ったほうが良いかなと思います
0 件のコメント:
コメントを投稿