ルーティング
Routing ・ るーてぃんぐ
パケットを宛先まで届ける経路を選択する仕組み。ネットワークをまたぐ通信の要。
✦ 30秒で試す — 航海地図を持たない中継役たちが、世界の裏側まで荷物を届ける新しい道が決まるまでの間、Aが送るパケットは?予想してみる概要
ルーティング(経路制御)は、パケットを宛先のIPアドレスまで届けるために「次にどこへ渡すか」を選び続ける仕組みです。インターネットは無数のネットワークの相互接続体であり、東京の端末からアメリカのサーバへの通信は、途中の何台ものルータをリレーのように経由します。各ルータは経路の全体を知っているわけではなく、「この宛先ならお隣のあのルータへ」という次の一歩(ネクストホップ)だけを判断します。この局所的な判断の連鎖が、結果として世界の裏側までパケットを届けるのです。
たとえるなら、宛先の住所だけが書かれた荷物を、各地の集配所が「この住所なら西方面の集配所へ」と順送りしていく宅配網です。どの集配所も配達の全行程は知りませんが、それぞれが正しい方面へ送り出せば荷物は届きます。この「方面別の仕分け表」にあたるのがルーティングテーブルです。
普段は意識せずに使えるルーティングですが、開発の現場では「クラウドのサブネット同士がつながらない」「VPNを張ったら一部の通信だけ届かない」といった形で顔を出します。traceroute で経路を追ったり、ip route でテーブルを読んだりする力は、インフラのトラブルシューティングの基礎体力です。
なぜ生まれたか
すべての機器が1本のケーブルや1つのスイッチにぶら下がる小さなネットワークなら、宛先を探す仕組みは単純で済みます。しかし世界中の組織がそれぞれ勝手に作ったネットワーク同士をつなぐとなると、「全機器の場所を1か所で把握する」ことは規模的にも管理的にも不可能です。しかも経路の途中の回線や拠点は故障するため、固定の経路では一部の故障が全体の不通につながってしまいます。
この問題意識の源流としてよく語られるのが、1960年代前半に RAND 研究所のポール・バランが行った研究です。核攻撃を受けても生き残る通信網として、中心を持たない網の目状のネットワークと、メッセージを小さな塊に分けて各中継点が自分の判断で転送する方式を提案しました。ただし、よく混同されますが、インターネットの前身 ARPANET(1969年)の直接の目的は核攻撃への耐性ではなく、高価な計算機を研究機関の間で共有することでした。ARPANET はバランや英国のドナルド・デービスらのパケット交換の考え方を取り入れ、結果として「一部が壊れても残りの経路で通信を続けられる」性質を持つことになります。
その答えの形が、「宛先ごとの完全な経路」ではなく「宛先の方面ごとの次の一歩」だけを各ルータに持たせ、ルータ同士が経路情報を交換し合って障害時には自動で迂回路に切り替える、という分散型の経路制御でした。IPアドレスをネットワーク部とホスト部に分けたのも、この「方面ごと」の仕分けを可能にするためです。中央の管制塔なしに、各ルータの局所的な判断だけで全体が機能する — この設計こそが、インターネットが誰の所有物でもないまま惑星規模に成長できた理由のひとつです。
詳細
ルーティングテーブルとロンゲストマッチ
ルータの判断のよりどころがルーティングテーブルです。各行は「宛先ネットワーク(IPアドレスのプレフィックス)」と「ネクストホップ(次に渡す相手)」の対応で、たとえば「10.0.0.0/8 宛ては ルータB へ」「10.1.0.0/16 宛ては ルータC へ」のように、宛先を1台ずつではなくネットワーク単位でまとめて書きます。この集約のおかげで、テーブルは世界中の全機器を列挙せずに済みます。
パケットが届くと、ルータは宛先IPアドレスに一致するプレフィックスをテーブルから探します。このとき複数の行に一致することがあり、その場合は最も長い(=最も具体的な)プレフィックスを優先します。これが「ロンゲストマッチ(最長一致)」の原則です。宛先 10.1.2.3 のパケットは /8 と /16 の両方に一致しますが、より具体的な /16 の行が勝ちます。どの行にも一致しない宛先を受け持つのが「デフォルトルート(0.0.0.0/0)」で、家庭のPCが「よく分からない宛先は全部ルータへ」と送り出せるのはこの仕組みのおかげです。
このロンゲストマッチは、OSI参照モデルでいうレイヤ3(ネットワーク層)の中核動作です。レイヤ2の MACアドレスによる転送が同一ネットワーク内の配達だとすれば、ルーティングはネットワークとネットワークの間をまたぐ配達を担います。
静的ルーティングと動的ルーティング
ルーティングテーブルの作り方には2通りあります。静的ルーティングは管理者が手で経路を書く方式で、動作が予測しやすく余計な通信も発生しませんが、経路の追加や障害のたびに人手の変更が必要です。小規模な拠点や、クラウドのルートテーブル(VPC内のサブネット間経路など)ではいまも主役です。
動的ルーティングは、ルータ同士がルーティングプロトコルで経路情報を交換し合い、テーブルを自動で構築・更新する方式です。組織内(AS内)で使う IGP には、大きく2つの流派があります。1つは RIP に代表される距離ベクトル型で、各ルータは隣のルータと「その宛先までの距離はいくつか」だけを定期的に教え合い、いちばん近いと言った隣を次の行き先に選びます。全体の地図は誰も持っておらず、隣の言うことを信じるだけです。もう1つは OSPF や IS-IS に代表されるリンクステート型で、各ルータが「自分はどの隣と、どのコストのリンクでつながっているか」を網全体に配り、全員が同じ地図を持ったうえで、それぞれが最短経路をアルゴリズム(ダイクストラ法)で計算します。そして組織と組織の間、つまりインターネット全体の経路交換を担うのが BGP です。
収束 — 障害が起きてから全員が合意するまで
回線障害が起きると、各ルータが経路を計算し直し、全体が新しい経路で合意するまでの過程を「コンバージェンス(収束)」と呼びます。障害に最初に気づくのは、切れたリンクの両端のルータだけです。ほかのルータは、隣から知らせが届くまで古い表のまま転送を続けます。その間、パケットは行き場を失って捨てられたり、2台以上のルータが互いに「その宛先はそっちが近い」と押し付け合うルーティングループに入ったりします。ループに入ったパケットが永遠に回り続けないのは、IP ヘッダに TTL(生存時間)という数があり、ルータを1台越えるたびに1ずつ減って、0 になった時点で捨てられるからです。
距離ベクトル型には、道が完全になくなったときに特有の弱点があります。ルータ同士が互いの古い距離を信じて「そっちが3なら自分は4」「そっちが4なら自分は5」と距離を少しずつ数え上げ、上限(RIP では 16 を「無限大」とします)に達するまで「届かない」と確定できないのです。これを無限カウントと呼びます。対策として、ある宛先について「その隣から教わった経路は、その隣には教え返さない」スプリットホライズンなどの工夫がありますが、3台以上で輪になるループまでは防げません。リンクステート型は全員が地図を持つぶん収束が速く、大きな網ではこちらが主流です。
下の部品では、7台のルータが距離ベクトル型で経路を交換しています。リンクをクリックして切り、表が隣から隣へ書き換わっていくようすと、その間にパケットがどうなるかを見てください。
A から宛先(G の先のネットワーク)へ、パケットが流れ続けています。リンクをクリックして切ってみてください。まずは、いまパケットが通っている C–G がおすすめです。
収束の速さは、そのまま障害時にどれだけのパケットが消えるかに直結します。そのため実務では、経路情報の交換間隔を短くする、障害をリンクの物理的な状態から即座に検知する(BFD などの仕組み)、予備の経路をあらかじめ計算しておく、といった工夫で収束時間を縮めます。
実務での顔の出し方
クラウド時代のインフラ設計は、実はルーティング設計そのものです。VPC のルートテーブルで「このサブネットからインターネットへは NATゲートウェイ経由」と書くのは静的ルートの設定であり、NAT とルーティングはここで組み合わさります。VPN の「特定の宛先だけトンネルに流す」スプリットトンネルも、Kubernetes のPod間通信も、その実体はルーティングテーブルの操作です。
典型的な落とし穴も知っておきましょう。行きと帰りで別の経路をたどる「非対称ルーティング」は、経路上にステートフルなファイアウォールがいると帰りのパケットだけ落とされる厄介な障害を起こします。また、静的ルートの書き間違いでも、2台のルータが互いに「その宛先はそっちだ」と押し付け合うルーティングループが恒常的にできてしまいます。traceroute で同じルータの組が繰り返し現れたらループのサインです(traceroute 自体、TTL を1から順に増やして送り、各ルータが返す「TTL切れ」の通知で経路を調べる道具です)。「つながらない」の原因調査では、名前解決(DNS)の次にまず経路を疑う — これがネットワークデバッグの定石です。
試問
7台のルータ(A〜G)がリンクでつながり、送り手 A から宛先 G へパケットが流れ続けています。各ルータは隣と「宛先まであと何歩か」を一定間隔で教え合い、表の「次」に書いた隣へパケットを渡します。リンクを押すと切れ(もう一度で戻る)、表が隣から隣へ書き換わっていきます。
A から宛先(G の先のネットワーク)へ、パケットが流れ続けています。リンクをクリックして切ってみてください。
