【入門編】 NATインスタンスのAuto ScalingとFailover用カスタムルートテーブル制御 – クラウドインフラと仮想化ネットワーク実践ガイド

ネットワークの「関所」を守れ!NATインスタンスの自動復旧アーキテクチャ入門

こんにちは!SREとして日々クラウドの海を泳いでいるライターです。

今日は、AWSを触り始めたエンジニアが必ず一度は悩む「NAT(ネットワーク・アドレス・トラレーション)インスタンス」の守り方についてお話しします。

「プライベートサブネットにあるサーバーが、外の世界(インターネット)とどうやって会話しているの?」という疑問から、その「関所」が倒れた時にどうやって自動で立ち直らせるか、という現場の泥臭いテクニックまで、一緒に紐解いていきましょう!

—

1. NATインスタンスって、そもそも何者?

インターネットから切り離された「プライベートサブネット」にいるサーバーたちは、外の世界から直接見えないので非常に安全です。でも、OSのアップデートをしたり、外部のAPIを叩いたりと、どうしても外へ出たい時がありますよね。

ここで登場するのが「NATインスタンス」です。例えるなら、「手紙の転送係」です。

1. プライベートサブネットのサーバーが、「外の誰かに手紙(パケット)を届けたい!」と転送係に渡す。
2. 転送係(NATインスタンス)は、自分の名前(自分のIPアドレス)を封筒に書き換えて、インターネットへ投げる。
3. 相手からの返信が届いたら、元のサーバーが誰かを確認して、正しい宛先に届け直す。

この転送係が倒れると、プライベートサブネットのサーバーは「外の世界への窓口」を失い、孤立してしまいます。これがネットワーク障害の始まりです。

—

2. なぜ「高可用性(HA)」が必要なのか?

AWSには便利なマネージドサービスである NAT Gateway がありますが、コストや要件の都合で自前の EC2 をNATインスタンスとして運用するケースもまだあります。

しかし、EC2 は生き物です。夜中に突然ダウンすることだってあります。「NATインスタンスが落ちました」というアラートで叩き起こされる悪夢を避けるために、「もし転送係が倒れたら、すぐに交代要員を呼んで手紙の宛先を切り替える」という仕組みを作る必要があるのです。

—

3. 自動リカバリの仕組み:LambdaとCloudWatchの連係プレー

この仕組みを実現するには、以下の3つのコンポーネントがタッグを組みます。

1. CloudWatch Alarm: 「NATインスタンスが応答しない!」と検知する監視役。
2. EventBridge (旧 CloudWatch Events): アラームをトリガーに発火する司令塔。
3. Lambda: ルートテーブルの行き先を、生きているNATインスタンスへと書き換える実行部隊。

郵便ルート(ルートテーブル)の書き換えイメージ

AWSのネットワークでは、すべてのサブネットに「どの道を通って外に出るか」という地図(ルートテーブル)があります。この地図の「インターネット行き」の行き先を、障害発生時に別のNATインスタンスのIPにパッと書き換えるわけです。

—

4. 実装のヒント:Lambdaによるルート切り替え

Lambdaを使ってルートテーブルを書き換える際は、boto3(AWSのPython SDK)を使うのが定番です。

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    
    # 書き換えたいルートテーブルID
    route_table_id = 'rtb-xxxxxxxxxxxxxxxxx'
    # 新しいNATインスタンス(あるいはENI)のID
    new_nat_instance_id = 'eni-xxxxxxxxxxxxxxxxx'
    
    try:
        # 古いルートを削除して、新しいNATへ向くように追加する
        ec2.replace_route(
            RouteTableId=route_table_id,
            DestinationCidrBlock='0.0.0.0/0', # インターネット全般
            NetworkInterfaceId=new_nat_instance_id # 新しい転送係のID
        )
        print("ルートテーブルの切り替えに成功しました!")
    except Exception as e:
        print(f"エラーが発生しました: {e}")

注意点:リカバリタイムについて

この手法は非常に強力ですが、「インスタンスが死んでからルートが切り替わるまで」のタイムラグが発生します。

  • CloudWatchのアラーム検知(数分)
  • Lambdaの実行(数秒)
  • ルートテーブルの反映(即時〜数十秒)

トータルで数分間の通信断が発生します。「絶対に通信を途切れさせたくない!」というミッションクリティカルな環境では、このタイムラグを許容できるかどうかが設計の分かれ道になります。

—

5. SREからのアドバイス

実務でこのアーキテクチャを組むとき、初心者が陥りがちな罠が2つあります。

1. IAM権限の忘れ物: Lambdaにルートテーブルを書き換える権限(ec2:ReplaceRoute)を忘れずに付与してください。「Lambdaを動かしたのに、なぜか失敗する…」という原因の9割はこれです。
2. Src/Dest Checkの無効化: NATインスタンスとして使うEC2は、AWSのデフォルト設定である「送信元/送信先確認(Source/Dest Check)」を無効化しないと、パケットを転送してくれません。これも忘れないようにしましょう。

# AWS CLIで簡単に設定できます
aws ec2 modify-instance-attribute --instance-id i-xxxxxxxx --no-source-dest-check

—

最後に:完璧なネットワークなんてない

クラウドインフラを運用していると、「絶対に壊れないネットワーク」を作りたくなりますが、実際には「壊れてもすぐに自動で直る仕組み」を作る方が、ずっと現実的で堅牢な答えになります。

今回ご紹介した手法は、まさにその第一歩です。最初は少し難しく感じるかもしれませんが、パケットを「手紙」、ルートテーブルを「地図」と例えれば、意外とシンプルだと思いませんか?

ぜひ皆さんの環境でも、この「自動転送係」を育ててみてください。トラブルが起きた時、何もしなくても勝手に復旧しているのを見た時の感動は、SRE冥利に尽きるものですよ!

それでは、また次回の記事でお会いしましょう!Happy Clouding!

コメント

タイトルとURLをコピーしました