なぜそのリクエストは「そこ」へ飛ぶのか?ALBのルーティング戦略を極める
現場でトラブルシューティングをしていると、「ALBのリスナールールが効かない」という悲鳴をよく耳にします。深夜の障害対応でログを追っているとき、ALBのルーティングロジックがブラックボックス化していると、それはもう地獄です。
今日は、AWSのApplication Load Balancer(ALB)における「ホストヘッダー」と「パスベース」ルーティングの真髄を、現場の視点から紐解いていきましょう。単なる仕様の解説ではなく、パケットがどう判定され、どうターゲットグループ(TG)へ運ばれるのか、その「リアル」を共有します。
1. なぜ「ホスト」と「パス」で振り分ける必要があるのか?
マイクロサービス化が進む現代のアーキテクチャでは、単一のドメインで複数の機能を提供することが一般的です。
- ホストヘッダーベース:
api.example.comとweb.example.comを同じALBで受け取り、別々のマイクロサービスへ流す。 - パスベース:
example.com/api/v1/*は決済サービスへ、example.com/images/*はS3バケットをバックエンドにしたサーバーレスへ流す。
これらを適切に組み合わせることで、ALBは単なるL7バランサーを超え、インフラ構成を抽象化する「フロントドア」として機能します。
2. 通信のシーケンスと判定ルール
ALBは、受信したHTTPリクエストを上から順に「リスナールール」と照合します。ここでのポイントは、「ルールには優先順位がある」ということと、「デフォルトルールが最後の砦である」という点です。
判定の優先順位
1. ホストヘッダー: Host ヘッダーの内容を評価。
2. パスパターン: リクエストURIのパスを評価。
3. アクション: 一致した場合、指定したTGへ転送(または固定レスポンス/リダイレクト)。
もしルールを複数設定している場合、優先順位が高いものからマッチングが行われます。この優先順位の設定を誤ると、意図せず特定のリクエストが「なんとなく近いルール」に吸い込まれ、深夜の障害の原因になります。
3. 実践:リスナールールの設定と確認
まずは、curlでリクエストを投げて、意図したヘッダーが正しく解釈されているか確認する習慣をつけましょう。
ホストヘッダーで振り分ける(CLI例)
特定のホスト名でアクセスしたときだけ、バックエンドの特定のサービスへ飛ばす設定です。
# curlで明示的にHostヘッダーを付与して疎通確認
curl -H "Host: api.internal.example.com" http://my-alb-123456789.ap-northeast-1.elb.amazonaws.com/health
パスベースで振り分ける(Python/Requests例)
APIのバージョンごとにルーティングを分ける例です。
import requests
# パスベースのルーティングを検証
# /api/v1/user へのアクセスを想定
url = "http://my-alb-123456789.ap-northeast-1.elb.amazonaws.com/api/v1/user"
try:
response = requests.get(url)
print(f"Status Code: {response.status_code}")
# 実際にはレスポンスヘッダーやボディを見て、
# 正しいマイクロサービスから返ってきているか確認
except Exception as e:
print(f"Error: {e}")
4. 現場でハマる「落とし穴」Tips
その1:ワイルドカードの罠
パスの指定で /* を使う際、ルールの順序が適切でないと、全てのリクエストが最上位のルールにマッチしてしまうことがあります。
- NG例:
/を優先順位1位に設定すると、その後の/api/*などは二度と評価されません。 - 鉄則: 「より詳細な(長い)パス」を優先順位の上位に配置すること。
その2:大文字・小文字の区別
ALBは、ホスト名については大文字・小文字を区別しませんが、パスについてはルール作成時に注意が必要です。RFC 3986ではパスはケースセンシティブであるべきとされていますが、ALBの設定画面での挙動は予期せぬマッチングを招くことがあるため、常に小文字で統一して設計するのがSREの常識です。
その3:503 Service Unavailable の正体
もしルーティング設定をしたのに 503 が返ってくる場合、以下の2点を疑ってください。
1. ターゲットグループのヘルスチェック: 転送先インスタンスがHealthyになっているか。
2. リスナールールの優先順位: 意図しないルールにマッチし、空のTGへ転送されていないか。
まとめ:ネットワークは「可視化」から始まる
ALBのルーティング設計は、いわば「Webの交通整理」です。複雑になればなるほど、どのルールが優先されているのか、どのヘッダーがトリガーになっているのかを常に意識する必要があります。
AWSコンソール上の設定画面だけでなく、TerraformやCloudFormationで構成管理を行っている場合も、必ず「優先順位(Priority)」を明示的に記述するようにしてください。
# Terraformでの記述例:優先順位を明示する
resource "aws_lb_listener_rule" "api_rule" {
listener_arn = aws_lb_listener.front_end.arn
priority = 10 # 数値が小さいほど優先度が高い
action {
type = "forward"
target_group_arn = aws_lb_target_group.api_tg.arn
}
condition {
path_pattern {
values = ["/api/*"]
}
}
}
「なんとなく動く」から「意図して制御できる」へ。この一歩が、あなたのインフラを堅牢なものに変えていくはずです。何かトラブルに遭遇したら、まずは curl -v でヘッダーを凝視することから始めてみてください。パケットは、嘘をつきませんよ。
コメント