【AWS】ALBからの切り離しと再登録手順
AWS で ALB を使って負荷分散している状況で、片系ずつデプロイやメンテナンスを行いたい場合に AWSCLI からターゲットグループを外す方法を紹介します。
検証環境は以下の記事で解説したものを使います。
構成はこんな感じ
実行環境
- macOS Monterey バージョン 12.1(Intel)
流れと解説
ALB
を使って冗長化しているので、片方をALB
から切り離してもう片方でサービスを継続させたまま、EC2
のメンテナンスやコードのデプロイをいます。
-
ALB
から 1 台目のEC2
を切り離す - 1 台目の
EC2
でメンテナンスやコードのデプロイを行う - 1 台目の
EC2
をALB
に再登録する -
ALB
から 2 台目のEC2
を切り離す - 2 台目の
EC2
でメンテナンスやコードのデプロイを行う - 2 台目の
EC2
をALB
に再登録する
2 台以上で冗長化している場合も、1 台ずつ同じように切り離しと再登録を繰り返せば良いです。
このようなデプロイ方式をローリングアップデートと呼びます。
デプロイ方式には他にブルーグリーンデプロイがあり、AWS のCodePipeline
でCI/CD
環境を構築する場合はこちらを使用することになります。
ローリングアップデートではデプロイ作業中に一時的に処理する台数が減るため、トラフィックが落ち着いている時間に実施するなど工夫する必要があります。
また、コードのデプロイにロールバック機能を持ったツール、例えばcapistrano
やdeployer
などを使用していない場合、切り戻しに時間がかかってしまいます。
対してブルーグリーンデプロイ方式では同じ台数でアップデート済みのEC2
を別に用意しておいて、両系を稼働させたままネットワーク的に瞬時に切り替えるので、デプロイ時の負担が少なく、切り替えや切り戻しが簡単に行なえます。
ではなぜ今回ローリングアップデートを採用するかというと、これを使わなければいけないような場合があるからです。
例えば以下のような場合です。
- 現在稼働している
EC2
の構成が正しく管理されておらず、AMI にしてクローンした場合に正しく動作する保証がない。 - 内部の IP アドレスが変わると困る。
-
CI/CD
を組み込む際に何らかの理由により、CodePipeline
が使えず、かつCI/CD
ツールから AWS のリソースを制御することができない。
上記のような制約がある場合は、EC2
を全く新しく作成する必要があるブルーグリーンデプロイを採用することはできず、必然的にローリングアップデートを行うことになるのかなと思います。
ALB からの切り離し&再登録手順
ALB
からEC2
を切り離す手順を紹介します。
AWS マネジメントコンソールから GUI で行う手順と、AWSCLIを用いてコマンドで行う方法の 2 つを解説します。
AWSCLI のインストールは以下を参考にしてください。
※今回はDocker
ではなく、Mac にインストールした AWSCLI を使用しています。
AWS マネジメントコンソールからの手順
-
AWS マネジメントコンソールから
EC2
の画面を開き、ロードバランシング -> ターゲットグループ
を選択し、対象のターゲットグループの画面を開きます。
-
Registered targets
に表示されているEC2
インスタンスのうち、切り離したいインスタンスにチェックを入れて、Deregister
をクリックします。
Health status
がdraining
になっていれば切り離された状態です。
-
再登録する際は、同じ画面から
Register targets
をクリックします。 -
登録する
EC2
インスタンスにチェックを入れ、ポートを入力し、Include as pending below
をクリックします。
-
Review targets
にPending
として追加されますので、確認してRegister pending targets
をクリックします。
-
登録直後は
Health status
がinitial
と表示されますが、しばらくしてhealthy
に変われば完了です。
AWSCLI を用いた手順
-
target group
のARNとEC2
のインスタンス IDを確認しておきます。
-
target group
のARNとEC2
のインスタンス IDを予め環境変数にセットしておきます。
export TARGET_GROUP_ARN=<コピーしたターゲットグループのARN>
export INSTANCE_ID=<対象EC2のインスタンスID>
- 現在の状態を確認する
aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP_ARN
表示例)
{
"TargetHealthDescriptions": [
{
"Target": {
"Id": "<対象EC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "healthy"
}
},
{
"Target": {
"Id": "<もう片方のEC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "healthy"
}
}
]
}
-
target group
から切り離し
aws elbv2 deregister-targets --target-group-arn $TARGET_GROUP_ARN --targets Id=$INSTANCE_ID
- もう一度状態を取得し、対象のインスタンスの
TargetHealth -> State
がdraining
になっていることを確認する。
aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP_ARN
表示例)
{
"TargetHealthDescriptions": [
{
"Target": {
"Id": "<対象EC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "draining",
"Reason": "Target.DeregistrationInProgress",
"Description": "Target deregistration is in progress"
}
},
{
"Target": {
"Id": "<もう片方のEC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "healthy"
}
}
]
}
- デプロイやメンテナンス後は、再登録を行う。
aws elbv2 register-targets --target-group-arn $TARGET_GROUP_ARN --targets Id=$INSTANCE_ID,Port=80
- 状態を何度か取得し、対象のインスタンスの
TargetHealth -> State
がinitial -> healthy
に変わることを確認する。
aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP_ARN
表示例)
{
"TargetHealthDescriptions": [
{
"Target": {
"Id": "<対象EC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
},
{
"Target": {
"Id": "<もう片方のEC2のインスタンスID>",
"Port": 80
},
"HealthCheckPort": "80",
"TargetHealth": {
"State": "healthy"
}
}
]
}
まとめ
ローリングアップデートを行う際の、GUI での ALB からの切り離し方法と AWSCLI での切り離し方法を解説しました。
個人的にはコマンドで行って手順化しておいたほうが、ミスも少なくなって良いかなと思います。
次はこのコマンドを使ってCI/CD
への組み込みを検証したいと思います。
Discussion