envoy HTTPロードバランサー
前回は、envoyを介して外部サービスを参照した。今回は自前クラスタのサービスをenvoyを介して参照したい。
準備
hello 2つ立ち上げる
# docker run --rm -d --name hello1 dockercloud/hello-world # docker run --rm -d --name hello2 dockercloud/hello-world
コンテナからhello-world を試す。
# docker run -it --link hello1 alpine wget -O - hello1 <h3>My hostname is 0b94df201862</h3> </body> # docker run -it --link hello2 alpine wget -O - hello2 <h3>My hostname is 7fd639de7e3d</h3> </body>
envoy 起動
envoy.yaml。admin セクションがなくてもいいんだなー。
static_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 80 } filter_chains: - filters: - name: envoy.http_connection_manager config: stat_prefix: ingress_http http_filters: - name: envoy.router route_config: name: route virtual_hosts: - name: hello_service domains: ["hello.local"] routes: - match: prefix: "/" route: cluster: hello_cluster clusters: - name: hello_cluster type: STRICT_DNS connect_timeout: 0.25s lb_policy: ROUND_ROBIN load_assignment: cluster_name: hello_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: { address: hello1, port_value: 80 } - endpoint: address: socket_address: { address: hello2, port_value: 80 }
envoy 起動。1.10.0が出ていたので使ってみた。
docker run \ --name envoy --rm --publish 80:80 \ --link hello1 --link hello2 \ -v /tmp/envoy:/etc/envoy \ envoyproxy/envoy:v1.10.0
/etc/hosts に次を加える
127.0.0.1 hello.local
curl する。
curl httpd.local <h3>My hostname is 0b94df201862</h3> </body> curl httpd.local <h3>My hostname is 7fd639de7e3d</h3> </body>
helloクラスタ 1コ落とす
これだけだと、前回と変わらない。試しにhelloクラスタ 1コ落とす。
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c4f6d6e58250 envoyproxy/envoy:v1.9.0 "/usr/bin/dumb-init …" 10 minutes ago Up 10 minutes 0.0.0.0:80->80/tcp, 10000/tcp envoy 7fd639de7e3d dockercloud/hello-world "/bin/sh -c /run.sh" 18 minutes ago Up 18 minutes 80/tcp hello2 0b94df201862 dockercloud/hello-world "/bin/sh -c /run.sh" 19 minutes ago Up 19 minutes 80/tcp hello1 # docker stop hello1 hello1 # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c4f6d6e58250 envoyproxy/envoy:v1.9.0 "/usr/bin/dumb-init …" 11 minutes ago Up 11 minutes 0.0.0.0:80->80/tcp, 10000/tcp envoy 7fd639de7e3d dockercloud/hello-world "/bin/sh -c /run.sh" 19 minutes ago Up 19 minutes 80/tcp hello2
で curl。成功したり失敗したりを繰り返す。envoy が503 を返している。落ちたほうを勝手に切り離すとかはやってくれない。
# curl hello.local <h3>My hostname is 7fd639de7e3d</h3> </body> # curl hello.local upstream connect error or disconnect/reset before headers. reset reason: connection failure # curl -i hello.local HTTP/1.1 503 Service Unavailable content-length: 91 content-type: text/plain date: Wed, 19 Jun 2019 11:49:29 GMT server: envoy upstream connect error or disconnect/reset before headers. reset reason: connection failure
health_checks を試す
envoy.yaml clusters に health_checks を追加。これで hello1 と envoy起動。envoy起動時 hello1 がないと怒られます。
clusters: - name: hello_cluster type: STRICT_DNS connect_timeout: 0.25s lb_policy: ROUND_ROBIN load_assignment: cluster_name: hello_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: { address: hello1, port_value: 80 } - endpoint: address: socket_address: { address: hello2, port_value: 80 } health_checks: - timeout: 1s interval: 5s unhealthy_threshold: 1 healthy_threshold: 1 http_health_check: path: /
hello1 を落として curl。なんど試しても問題ない。
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 599434dba3ff envoyproxy/envoy:v1.10.0 "/docker-entrypoint.…" 47 seconds ago Up 45 seconds 0.0.0.0:80->80/tcp, 10000/tcp envoy 41a26ecb6ce4 dockercloud/hello-world "/bin/sh -c /run.sh" 6 minutes ago Up 6 minutes 80/tcp hello1 7fd639de7e3d dockercloud/hello-world "/bin/sh -c /run.sh" About an hour ago Up About an hour 80/tcp hello2 # docker stop hello1 hello1 # curl hello.local <h3>My hostname is 7fd639de7e3d</h3> </body> # curl hello.local <h3>My hostname is 7fd639de7e3d</h3> </body>
hello1 を起動して curl。何度か試したらhello1が反応した。
# docker run --rm -d --name hello1 dockercloud/hello-world 391fad84edc08a8a56a3101e88c1b7ff76e79d6e615de3f0b5be81111e59b84a # curl hello.local <h3>My hostname is 7fd639de7e3d</h3> </body> # curl hello.local <h3>My hostname is 7fd639de7e3d</h3> </body> # curl hello.local <h3>My hostname is 391fad84edc0</h3> </body>