クラウドの世界でシステムを動かしていると、ある日突然、外の世界(インターネット)との通信がパタッと途絶えるという、冷や汗もののトラブルに直面することがあります。
「あれ、データベースのバックアップが外部ストレージにアップロードできないぞ?」
「SREチームのSlackに、API連携先からのタイムアウトアラートが鳴り響いている……!」
こういう時、原因の多くは「NATゲートウェイ(NAT Gateway)」の周辺、そして今回テーマにする「黒い穴(Blackhole)ルーティング」に隠されていることが多いのです。
「パケットがブラックホールに落ちる」なんて聞くと、なんだかSF映画のようで少し不気味に聞こえるかもしれませんが、実はクラウドのネットワーク裏側で起きている、とっても現実的で、かつインフラエンジニアなら誰もが一度はハマる「あるある」な現象なんです。
今回は、パケットの旅立ちからブラックホールの謎、そして現場での具体的な切り分け手法まで、身近な例えを交えながら一歩ずつ優しく紐解いていきましょう!
—
1. パケットの旅立ちとNATゲートウェイの役割
まずは、クラウドの中(プライベートな世界)から、インターネット(パブリックな世界)へ手紙(パケット)を送る仕組みを、私たちの身近な「郵便配達」に例えて考えてみましょう。
プライベートサブネットは「私書箱の街」
AWSのVPC(Virtual Private Cloud)やGCPのVPCネットワークの中には、セキュリティを高く保つために「プライベートサブネット」というエリアを作ります。ここにいるサーバー(インスタンス)たちには、いわば「外の世界からは直接手紙が届かない、自分たちだけの内線番号(プライベートIPアドレス)」しか割り当てられていません。
このプライベートな街の住人が、外のインターネットにあるWebサービスへ「お買い物注文書(リクエスト)」を出したいとします。
NATゲートウェイは「街の唯一の郵便局長」
でも、内線番号だけが書かれた手紙をそのまま外の世界のポストに投函しても、郵便局は宛先(返信先)が分からないので配達してくれませんよね。
そこで登場するのがNATゲートウェイです。
NATゲートウェイは、プライベートな街の住人から手紙を受け取ると、こう書き換えてくれます。
> 「よし、この手紙の差出人名(プライベートIPアドレス)を、俺の持っている外向けの顔(グローバルIPアドレス)に書き換えてから外に送ってやるよ。返事が来たら、ちゃんとお前のところに持ってきてやるからな!」
この「住所の書き換えと取り次ぎ」をしてくれる心強い窓口が、NATゲートウェイ(Network Address Translation Gateway)というわけです。
—
2. 突然の悲劇:NATゲートウェイがダウンすると?
さて、順調に動いていたこの郵便局(NATゲートウェイ)ですが、クラウドの基盤側でのメンテナンスや何らかの障害によって、ある日突然「利用不可(ダウン)」になってしまったとします。
郵便局がシャッターを閉めてしまいました。
しかし、プライベートサブネットのサーバーたちは、そんなこと露知らず、相変わらず外の世界へ向けて「注文書(パケット)」をどんどん作り続けます。
ここで、クラウドのネットワーク(VPCのルートテーブル)に目を向けてみましょう。
私たちが普段設定しているルートテーブルは、次のようなお世話をしています。
宛先: 0.0.0.0/0 (すべてのインターネット向け)
ターゲット: nat-xxxxxx (あなたの愛用しているNATゲートウェイ)
サーバーがパケットを送り出すと、ルートテーブルは指示通りに「お、インターネット向けだな? じゃあ、あのNATゲートウェイという名の郵便局長にパス!」と、パケットを送り出します。
しかし、その先の郵便局はもうもぬけの殻(ダウン状態)です。
—
3. 「黒い穴(Blackhole)」ルーティングの正体
ここで、パケットはどうなってしまうのでしょうか?
行き場を失ったパケットは、ルーターの中で路頭に迷います。「あれ、宛先の郵便局がないぞ? どこに行けばいいんだ……?」と。
この瞬間、クラウドの内部ネットワークでは、宛先を見失ったパケットがそのままどこにも出力されずに、文字通り「闇の中(消滅)」へと消え去ります。
これが「黒い穴(Blackhole)ルーティング」、あるいは「ブラックホール現象」と呼ばれる状態です。
宇宙のブラックホールと同じで、一度そこに吸い込まれたが最後、データは二度と戻ってきません。エラーメッセージ(「宛先が見つかりませんでした」という親切なお手紙)すら返ってこないことが多いため、外から見ると「ただひたすら通信がフリーズ(タイムアウト)する」という、エンジニア泣かせの不気味な症状を引き起こします。
—
4. 現場でどうやって切り分ける? トラブルシューティングの基本
もし、あなたの管理するプライベートサブネット内のサーバーから外部への通信が突如途絶えたら、現場のSREとしてはどう動くべきでしょうか? 一緒に手順を追っていきましょう。
ステップ1: 症状の切り分け(「本当にNATが原因か?」の確認)
まずは、パケットがどこまで飛んでいて、どこで止まっているのかを調べます。
サーバーにログインして、おなじみの ping や traceroute、あるいは通信の様子を覗き見る tcpdump などのツールを使ってみましょう。
例えば、パブリックIPアドレスを持つ外部のサーバーへ向けて、以下のように通信テストを行います。
# 外部の信頼できるサーバー(例: 8.8.8.8)に対してパケットを飛ばしてみる
ping -c 4 8.8.8.8
# もし名前解決(DNS)が怪しいなら、digコマンドで確認
dig @8.8.8.8 example.com
これで完全に無応答(100%パケットロス)になる場合、ルートやゲートウェイに異常がある可能性がグッと高まります。
ステップ2: ルートテーブルの確認
次に、そのサーバーが所属しているサブネットの「ルートテーブル」をクラウドの管理コンソール(AWSならAWS Console、GCPならGCP Console)で開いて確認します。
「すべての通信 (0.0.0.0/0) を向けている先のターゲット(NATゲートウェイ)」の状態はどうなっているでしょうか?
AWSの場合、マネージメントコンソール上でNATゲートウェイのステータスが Failed や Deleting、あるいは紐づいているElastic IP(EIP)に異常が発生していないかを確認します。
ステップ3: 具体的な復旧・回避アクション
もしNATゲートウェイ自体が回復不能な故障を起こしていると判明した場合、迅速に次のようなアクションを取る必要があります。
1. 新規のNATゲートウェイの作成:
別の可用性ゾーン(AZ)などに新しいNATゲートウェイをサクッと作成します。
2. ルートテーブルのターゲット付け替え:
ルートテーブルの 0.0.0.0/0 の宛先を、新しく作った生きたNATゲートウェイに書き換えます。
TerraformなどのIaC(Infrastructure as Code)で管理している環境であれば、ルートの向き先を変更するコードをサッと修正して適用するのがスマートですね。
# Terraformでのルートテーブル設定変更例
resource "aws_route" "internet_access" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0"
# 故障した旧NATIDから、新しく作成したNATゲートウェイのIDに差し替える
nat_gateway_id = aws_nat_gateway.healthy_new_nat.id
}
この変更がクラウド側に反映された瞬間、ブラックホールに吸い込まれていたパケットたちが再び正しいルートを見つけ、システムが息を吹き返します!
—
まとめ:ネットワークの「目に見えない流れ」をイメージしよう
今回は、NATゲートウェイの障害と「黒い穴(Blackhole)ルーティング」について、郵便配達の例えを交えながら解説しました。
- プライベートサブネットのサーバーは、外の世界へ行くためにNATゲートウェイという「郵便局」を頼っている。
- 郵便局がダウンしているのに、ルートが其処を指し示していると、パケットは行き場を失い「ブラックホール」に吸い込まれて消えてしまう。
- トラブル時は、パケットの行き先(ルートテーブル)と、出口(NATゲートウェイの状態)を疑い、冷静に一つずつ確認していくことが大切。
インフラやネットワークの世界は、目に見えないパケットが飛び交っているため、最初は難しく感じられるかもしれません。でも、「誰がどこへ手紙を出したくて、途中の郵便屋さんは今ちゃんと仕事をしているか?」というストーリーで考えてみると、不思議とスッと頭に入ってくるはずです。
日頃から「もしこのゲートウェイが消えたら、パケットはどこへ迷い込むだろう?」そんな視点を少しだけ持って、レジリエント(回復力のある)なクラウドアーキテクチャを一緒に設計・運用していきましょう!
コメント