(初心者向け記事です)
こんにちは、2022年10月にサーバーワークスに入社した大城と申します。現在AS部IE課でAWS修行中です。研修の模擬案件でALBターゲットグループの設定について考察することがあったのでブログに残したいと思います。
はじめに
研修の模擬案件で本番稼働中にシステム変更をする作業がありました。要件としては「日中帯作業のため極力本番環境に影響が出ないこと」で作業としてはインスタンスタイプを変更するというシンプルな内容でした。
構成
実際はもっと他にリソースがありますが関連する箇所だけ抜粋して記載しています。ALB配下にEC2インスタンスが2台ある構成です。
個人検証環境での素振り
下準備
AWS環境準備
ありがたいことにサーバーワークスでは個人単位でAWSアカウントが払い出されています。何か作業をする時の素振り環境として活用しています。まず個人検証環境に CloudFormation を使って、さくっと本番環境を想定した環境を立てました。EC2にnginxを導入し、とりあえずwebアクセスできる環境を作りました。(このあたりの手順は今回省略します)
影響確認方法
作業時の影響確認として今回はMacにプリインストールされているabコマンドを利用しました。1並列で10分間のアクセスを継続させました。
ab -c 1 -t 600 "http://ALBのURL/"
最初に実施したインスタンスタイプ変更手順
ALBターゲットグループでヘルスチェック設定しているし大丈夫だろう!という安易な考えで、まずは試しにEC2インスタンス1台ずつ下記の作業を実施しました。
- EC2インスタンスを停止
- インスタンスタイプ変更
- EC2インスタンス開始
発生した問題
当たり前ではありますが、abコマンドの結果 Failed requests
が記録されました。インスタンスを停止するタイミングでブラウザでアクセスすると数十秒 Bad Gateway 出ました。
abコマンドの結果
Failed requests: 47 (Connect: 0, Receive: 0, Length: 47, Exceptions: 0)
Bad Gateway
ターゲットグループのヘルスチェック設定
なぜBad Gatewayが出てしまったのか、AWSドキュメントと実際のターゲットグループのヘルスチェック設定を見ながら確認していきます。
構築で利用した CloudFormation の抜粋
AWSTemplateFormatVersion: "2010-09-09" # <省略> Resources: TargetGroup1: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: Port: 80 Protocol: "HTTP" HealthCheckEnabled: True HealthCheckProtocol: "HTTP" HealthCheckPath: "/" HealthCheckPort: "traffic-port" HealthyThresholdCount: 5 UnhealthyThresholdCount: 2 HealthCheckTimeoutSeconds: 5 HealthCheckIntervalSeconds: 30 Matcher: HttpCode: 200 # <省略>
確認するポイントは2点
UnhealthyThresholdCount: 2
であるため2回チェックに失敗したら非正常となる
HealthCheckIntervalSeconds: 30
であるため30秒に1回チェックされる
チェックの間隔は30秒であることが分かります。またEC2インスタンスを停止してリクエストが受け付けられなくなっても2回チェックがNGとなるまで非正常と見なされません。そのため ALB->停止したEC2
にリクエストが送信され続け、ブラウザからアクセスする際に Bad Gatewayが出たということになります。
どうすればBad Gatewayが発生しないか
AWSのドキュメントにも書いてある通りターゲットグループから登録解除して作業すれば解決します。
登録済みターゲットの需要が低下した場合や、ターゲットを保守する必要がある場合、ターゲットグループから登録解除できます。登録解除するとすぐに、ロードバランサーはターゲットへのリクエストのルーティングを停止します。ターゲットがリクエストを受信する準備ができたら、ターゲットグループに再度登録することができます。
登録解除に関する設定もAWSドキュメントを確認しながら見てみます。
構築で利用した CloudFormation の抜粋
AWSTemplateFormatVersion: "2010-09-09" # <省略> Resources: TargetGroup1: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: # <省略> TargetGroupAttributes: - Key: "deregistration_delay.timeout_seconds" Value: 300 # <省略>
確認するポイント
deregistration_delay.timeout_seconds 300
となっているため、登録解除のボタンを押した後、ブチッと切り離すのではなく300秒待機してくれます。
修正したインスタンスタイプ変更手順
ALBターゲットグループからEC2インスタンスを適切に登録解除と登録を行うことで、abコマンドの結果 Failed requests
がでなくなりました。1台ずつ下記の作業を実施して個人検証環境で問題ないことを確認しました。その後、模擬案件の本番環境でも問題なく作業完了させることが出来ました。
- ALBターゲットグループからEC2インスタンスを登録解除
- EC2インスタンスを停止
- インスタンスタイプ変更
- EC2インスタンス開始
- ALBターゲットグループにEC2インスタンスを登録
最後に
ここまで読んで頂きありがとうございます。AWSドキュメントやAWSマネージメントコンソール上で設定確認することは大事です。それと合わせて実際に検証してみて、どのような挙動になるのか体験することも大事なんだなと思いました。
大城 慶明 (記事一覧)
マネージドサービス部
2022年10月サーバーワークスに入社、沖縄からリモート勤務。AWSを勉強中。沖縄では大城が多いので「よっさん」と呼ばれています。AWS14冠。NRUG沖縄支部運営。X @yo_ohshiro