【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