AWS環境でALBがPrivate Subnetのコンテナを見つけられない時の解決記 (Target Unhealthy)
AWSでECSやFargateを運用している際、コンテナのログは正常なのに、ALB(Application Load Balancer)側でだけ「Unhealthy」が出てしまうことはありませんか?セキュリティグループもNATゲートウェイも設定済み。それでも通信が通らない……。
今回は、そんな時に見落としがちな**「ALBとアベイラビリティゾーン(AZ)のマッピング不一致」**によるトラブル解決記をまとめました。
1. トラブルの状況: 「コンテナはReady、でもALBはUnhealthy」
構成は一般的な Public ALB + Private Subnet (ECS/Fargate) です。
-
コンテナの状態: ログを確認すると
0.0.0.0:3000で正常にリスニングしており、エラーもなし。 -
現象: ALBのターゲットグループ(Target Group)で、ヘルスチェックが常に
Unhealthyになる。 -
確認済みの項目:
- セキュリティグループ(SG)のインバウンド/アウトバウンド設定:問題なし。
- プライベートサブネットからNATゲートウェイへのルーティング:問題なし。
一見完璧に見える設定ですが、なぜかALBがターゲットを見つけられずにいました。
2. 原因分析: 「ALBの足が届かない場所」
問題の核心は、アベイラビリティゾーン(AZ)のマッピング不一致にありました。
-
ALBの設定: AZ
2aと2bのパブリックサブネットのみを担当するように設定されていた。 -
実際のターゲット: コンテナは AZ
2cのプライベートサブネットで起動していた。
ALBは、自身が管理するように設定されたAZにのみ「ノード(通信の足がかり)」を作成します。つまり、ALBが 2a と 2b しか見ていない場合、2c にあるターゲットに対してトラフィックを送る手段がありません。 ターゲットがいくら正常に動いていても、ALBにとっては「手が届かない場所」にいるため、通信不能と判断されてしまいます。
3. 勘違いしやすいポイント: NAT Gateway ≠ パブリックサブネット
ここでやりがちなミスが、「2c のプライベートサブネットにNATゲートウェイを置いてあるから、インターネット通信はできるはずだ」という思い込みです。
- NAT Gateway: プライベートサブネット内のリソースが「外(インターネット)」へ出ていくための一方通行の出口です。
- Internet-facing ALB: 外部からのリクエストを受け取る必要があるため、各AZにおいて必ずインターネットゲートウェイ(IGW)と紐付いた**「パブリックサブネット」**に配置されている必要があります。
つまり、ALBに 2c のターゲットを管理させるには、2c にもALBが常駐するためのパブリックサブネットが不可欠なのです。
4. 解決方法 (Step-by-Step)
① 新しいパブリックサブネットの作成
ターゲット(コンテナ)が存在するアベイラビリティゾーン(例:ap-northeast-2c)に、新しいサブネットを作成します。この際、既存のCIDRブロックと重ならないように注意します。
② ルーティングテーブルの接続(パブリック化)
作成した 2c のサブネットのルーティングテーブルに、0.0.0.0/0 -> IGW の経路を追加し、これを「パブリックサブネット」として機能させます。
③ ALBのネットワークマッピングを更新
AWSコンソールから対象のALBを選択し、[ネットワークマッピング (Network mapping)] -> [サブネットの編集 (Edit subnets)] へ進みます。
- 問題のAZ(
2c)にチェックを入れます。 - 先ほど作成した
2cのパブリックサブネットを選択してマッピングを保存します。
5. 結果と教訓
設定変更から1〜2分後、ターゲットグループの状態が Initial を経て、ついに Healthy(緑のチェック) に変わりました!
今日のまとめ
- ALBは自分がマッピングされたAZしか管理しない: ターゲットが存在するすべてのAZには、ALBノードが配置されるためのパブリックサブネットが紐付いている必要があります。
- 構造の理解が先決: NATゲートウェイがあるからといって、そのサブネットをALBが利用できるわけではありません。ALBのための「入り口(パブリックサブネット)」を適切に用意しましょう。
同じようなトラブルで悩んでいるエンジニアの方の助けになれば幸いです。