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>