スティッキーセッションを有効化した ALB でターゲット EC2 が Unhealthy となった場合のリクエスト振り分けの挙動を確認してみた
こんにちは、岩城です。
ALB の維持設定(スティッキーセッション)を有効化し、複数の EC2 をターゲットに設定している環境で、既にリクエストが振り分けられた EC2 に障害が発生した場合、維持設定が影響して正常な EC2 に振り分けられることがないかを確認する機会がありました。
確認の結果を共有します。
いきなり結論
維持設定が有効な状態で一度 EC2 #1 へリクエストした後。EC2 #1 のヘルスチェックが Unhealthy になると、Healthy な EC2 #2 へリクエストが振り分けられます。
つまり、維持設定が影響して Unhealthy な EC2 #1 にリクエストされ続けることはありません。
ここで 1 点注意が必要なことがあります。
ALB にはターゲットグループに登録されているターゲットがすべて Unhealthy である場合、すべてのターゲットにリクエストを振り分けます。
仮に EC2 #1 と EC2 #2 共に Unhealthy になった場合、両方にリクエストが振り分けられることになることはおさえておきましょう。
ターゲットグループに異常な登録済みターゲットのみが含まれている場合、そのヘルスステータスにかかわらず、ロードバランサーはそれらすべてのターゲットにリクエストをルーティングします。
Application Load Balancer ターゲットグループのヘルスチェック - エラスティックロードバランシング
試してみる
検証環境は、ALB + Nginx をインストールした EC2 ×2 です。
ALB のターゲットグループの設定で維持設定を有効化していること以外は特別なことはしていません。
ちなみに、維持設定を有効化していないと、リクエストする度にレスポンスする EC2 が変わります(ラウンドロビン)。
初回リクエスト
初回リクエストした結果 EC2 #1 に振り分けられたとします。
維持設定を有効化しているので、何度リクエストしても #1 にリクエストします。
リクエストのイメージ
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #1!</h1>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #1!</h1>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #1!</h1>
</body>
</html>
EC2 #1 を Unhealthy にする
EC2 #1 に障害が発生したことを想定したシャットダウンにより、意図的に ALB からのヘルスチェックを失敗させ Unhealthy にしました。
維持設定が有効なので障害が発生した EC2 #1 にリクエストされ続けると思われるかも知れませんが、そんなことはありません。
Unhealthy となった後のリクエストで Healthy な EC2 #2 にリクエストが振り分けられます。
リクエストのイメージ
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #1!</h1>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #1!</h1>
</body>
</html>
# EC2 #1 をシャットダウン
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
</body>
</html>
# EC2 #2 へ振り分けられた
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #2!</h1>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #2!</h1>
</body>
</html>
$ curl -c cookie.txt -b cookie.txt http://devio-alb-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to #2!</h1>
</body>
</html>
EC2 #1 を Healthy に戻す
EC2 #1 を起動し ALB からのヘルスチェックに成功すると Healhty に戻ります。
この時、EC2 #1 は Healthy に戻りましたが、維持設定が有効になっているため、EC2 #2 にリクエストされ続けます。
勝手に障害発生前の EC2 #1 に戻るということはありません。
おわりに
頭では分かっていましたが、実際に確認してみました。
実際のところ、維持設定を有効にしているということは、セッション情報など保持するステートフルなアプリケーションが EC2 上で稼働していると思います。
ヘルスチェックが失敗し別の EC2 にリクエストされた場合、元の EC2 で持っていた情報はロストしますので、ユーザー影響がありそうです。
ロストされて困る場合、セッション情報は ElastiCache を使ったり、ログは S3 に出力するなど、ステートレス化を検討してみてください。
本エントリが、どなたかのお役に立てれば幸いです。