🌟

【AWS】ALBからの切り離しと再登録手順

2022/02/05に公開

AWS で ALB を使って負荷分散している状況で、片系ずつデプロイやメンテナンスを行いたい場合に AWSCLI からターゲットグループを外す方法を紹介します。

検証環境は以下の記事で解説したものを使います。

https://zenn.dev/tokku5552/articles/create-php-env-with-cfn

https://zenn.dev/tokku5552/articles/create-php-env-explanation

構成はこんな感じ
image

実行環境

  • macOS Monterey バージョン 12.1(Intel)

流れと解説

ALBを使って冗長化しているので、片方をALBから切り離してもう片方でサービスを継続させたまま、EC2のメンテナンスやコードのデプロイをいます。

  1. ALBから 1 台目のEC2を切り離す
  2. 1 台目のEC2でメンテナンスやコードのデプロイを行う
  3. 1 台目のEC2ALBに再登録する
  4. ALBから 2 台目のEC2を切り離す
  5. 2 台目のEC2でメンテナンスやコードのデプロイを行う
  6. 2 台目のEC2ALBに再登録する

2 台以上で冗長化している場合も、1 台ずつ同じように切り離しと再登録を繰り返せば良いです。
このようなデプロイ方式をローリングアップデートと呼びます。
デプロイ方式には他にブルーグリーンデプロイがあり、AWS のCodePipelineCI/CD環境を構築する場合はこちらを使用することになります。

ローリングアップデートではデプロイ作業中に一時的に処理する台数が減るため、トラフィックが落ち着いている時間に実施するなど工夫する必要があります。
また、コードのデプロイにロールバック機能を持ったツール、例えばcapistranodeployerなどを使用していない場合、切り戻しに時間がかかってしまいます。
対してブルーグリーンデプロイ方式では同じ台数でアップデート済みのEC2を別に用意しておいて、両系を稼働させたままネットワーク的に瞬時に切り替えるので、デプロイ時の負担が少なく、切り替えや切り戻しが簡単に行なえます。

https://aws.amazon.com/jp/quickstart/architecture/blue-green-deployment/

ではなぜ今回ローリングアップデートを採用するかというと、これを使わなければいけないような場合があるからです。
例えば以下のような場合です。

  • 現在稼働しているEC2の構成が正しく管理されておらず、AMI にしてクローンした場合に正しく動作する保証がない。
  • 内部の IP アドレスが変わると困る。
  • CI/CDを組み込む際に何らかの理由により、CodePipelineが使えず、かつCI/CDツールから AWS のリソースを制御することができない。

上記のような制約がある場合は、EC2を全く新しく作成する必要があるブルーグリーンデプロイを採用することはできず、必然的にローリングアップデートを行うことになるのかなと思います。

ALB からの切り離し&再登録手順

ALBからEC2を切り離す手順を紹介します。
AWS マネジメントコンソールから GUI で行う手順と、AWSCLIを用いてコマンドで行う方法の 2 つを解説します。

AWSCLI のインストールは以下を参考にしてください。
※今回はDockerではなく、Mac にインストールした AWSCLI を使用しています。
https://zenn.dev/tokku5552/articles/aws-container

AWS マネジメントコンソールからの手順

  • AWS マネジメントコンソールからEC2の画面を開き、ロードバランシング -> ターゲットグループを選択し、対象のターゲットグループの画面を開きます。
    image

  • Registered targetsに表示されているEC2インスタンスのうち、切り離したいインスタンスにチェックを入れて、Deregisterをクリックします。
    Health statusdrainingになっていれば切り離された状態です。
    image

  • 再登録する際は、同じ画面からRegister targetsをクリックします。

  • 登録するEC2インスタンスにチェックを入れ、ポートを入力し、Include as pending belowをクリックします。
    image

  • Review targetsPendingとして追加されますので、確認してRegister pending targetsをクリックします。
    image

  • 登録直後はHealth statusinitialと表示されますが、しばらくしてhealthyに変われば完了です。
    image

AWSCLI を用いた手順

  • target groupARNEC2インスタンス IDを確認しておきます。
    image
  • target groupARNEC2インスタンス 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 -> Statedrainingになっていることを確認する。
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 -> Stateinitial -> 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