0
0

サーバーが落ちた時にターゲットグループを切り替える

Last updated at Posted at 2024-09-13

こんにちは。ねこしまです。
今回は、ELBにリスナーとして登録されているEC2①が落ちてしまった際にEC2②のターゲットグループにリスナーを切り替えるという作業を行う機会があったのでその内容を共有したいと思います。

はじめに

全体の流れ

ELBにリスナーとして登録されているターゲットグループのEC2がUnHealthyになった際にCloudWatchアラームで検知し、SNSに流します。
SNSではメール送信と共にLambdaのトリガーとします。
LambdaではEC2①のターゲットグループをリスナーから外し、EC2②のターゲットグループを新たにリスナーとして登録をします。
image.png

前提条件

 ・VPCやサブネット・ELB・EC2が作成済みであること

対象外事項

 ・ターゲットグループ切り替え後のEC2②の起動

対象事項

 ・EC2①②それぞれのターゲットグループの作成
 ・EC2①のUnhealthyを検知するCloudWatchアラームの作成
 ・Lambda起動のトリガーとなるSNSの作成
 ・ターゲットグループの切り替えを行うLambdaの作成

設定

ターゲットグループの作成

EC2①を登録したターゲットグループ(first-tg)を作成します。
image.png
続いてEC2②を登録したターゲットグループ(second-tg)を作成します。
image.png

ターゲットグループが2つできました。
image.png

ロードバランサーの作成

では、ALBを作成します。
まず、[ロードバランサーの作成]を押下します。
image.png
今回の作成はALBです!
image.png

ターゲットグループはEC2①が登録されているfirst-tgで設定します。
image.png

ロードバランサーを作成し、しばらくたつと、登録しているターゲットグループがHealthyになりました!
image.png

ALBのDNS名でアクセスすると、下記のようにEC2①のページを見ることが出来ました。
image.png

Lambdaの作成

では、Lambda関数を作成します。
下記リンクを参考に作成しました。
lambdaでalbのターゲットグループ変更の仕方

まず[関数の作成]を押下します。
image.png

ランタイムはPython3.12を使用します。
image.png

関数は下記を入力してDeployします!※インスタンスの起動や停止は含まず、TGの切り替えのみを行っています。

import boto3
import json
import time

elbv2_client = boto3.client('elbv2')
ec2_client = boto3.client('ec2')

target_group_arn1 = '1台目のインスタンスが紐づいたターゲットグループのARN'
target_group_arn2 = '2台目のインスタンスが紐づいたターゲットグループのARN'
listener_arn = '変更するリスナーのARN'

def lambda_handler(event, context):
    MESSAGE = json.loads(event['Records'][0]['Sns']['Message']) 
    Deregister_tg_ID = MESSAGE['Trigger']['Dimensions'][0]['value']
    
    Message = json.dumps(MESSAGE) 
    deregister_target_group_arn = json.dumps(Deregister_tg_ID) 

    elbv2_client.modify_listener(
        ListenerArn=listener_arn,
        DefaultActions=[
            {
                'Type': 'forward',
                'TargetGroupArn': target_group_arn2,
            },
        ]
    )

これでLambda関数は完成しました。

SNSの作成

では続いてSNSを作成します。
※今回は通知も同時に行いたかったためSNSを使用します。

まず[トピックを作成]を押下します。
image.png

トピック名を記入して作成します。
image.png

次は作成したトピックのサブスクリプションを作成します。
image.png

プロトコルはLambdaを選択し、エンドポイントには先ほど作成したSNSのARNを入力します。
image.png

作成を押下し、Lambdaに戻るとトリガーとしてSNSが入力されていることが分かります。
image.png

ここまでの設定を行ったら、最後はCloudWatchアラームのみになりました!最後にここを作成したら完成です。
image.png

CloudWatchアラームの作成

EC2①が登録されたターゲットグループ(first-sg)のUnHealthyHostCountメトリクスでアラームを作成します!
image.png

今回は1分間の平均で統計を取り、3分以内の3データポイントでUnhealthyだった場合にターゲットグループが切り替わるように設定したいと思います。
また、本メトリクスはHealthyの場合データ不足になってしまうので「欠落データを適正」として扱うようにします。こうすることで、普段はアラームがOKとなるようになります。
image.png

アラームになった時のアクションでは、LambdaのトリガーとなっているSNSを登録します。
image.png

しばらくすると、アラームがOK状態になりました!これで設定は完了となります。
image.png

切り替わりの確認

では、ターゲットグループの切り替えが出来るか動かしていきます!
image.png

EC2①をUnhealthyにし、ターゲットグループがEC2②が登録されているsecond-tgに切り替われば成功となります。

まず現在のALBのリスナーと画面を確認します。
現在は下記のようにEC2①が登録されたfirst-tgが登録されています。
image.png

そして、ALBにアクセスするとこのようなページが出ます。
image.png

前提の確認が済んだので、テスト開始します。
今回はEC2①のindex.htmlを削除する形でUnhealthyにしていきます。



ターゲットグループが切り替わり、ページも変わりました!(※EC2②は起動済み)
image.png
image.png

最後に

今回は、EC2①がUnhealthyとなった場合にEC2①のターゲットグループからEC2②のターゲットグループへ変更するという内容を設定しました。
また、今回の要件とは違ったため省略していますが、EC2②の自動起動とTG切り替え後の自動での戻しについても今後検証してみたいと思います!

この記事がどなたかのお役に立てばとっても嬉しいです!
最後までお読みいただきありがとうございましたー!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0