VLAN間ルーティングの深淵へ:Router-on-a-StickからL3スイッチのSVIまで
ネットワークの設計をしていると、必ずぶち当たる壁がある。「なぜ、VLANを分けたはずのホスト同士が通信できないのか?」という問いだ。そしてその先に待っているのが、VLAN間ルーティングという名の、ネットワークエンジニアの腕の見せ所である。
今日は、教科書の定義をなぞるような退屈な話はしない。パケットがスイッチのASICをどう駆け抜け、CPUの負荷をどう回避しているのか。現場で叩き上げられた視点から、その本質を解き明かしていこう。
—
1. 原点:Router-on-a-Stickの「悲哀と美学」
初期のネットワーク構成において、VLAN間ルーティングの主役は間違いなく Router-on-a-Stick(ルータオンアスティック)だった。スイッチのポートに 802.1Q タギングを施し、一本の物理ケーブル(トランク)を通してルータに全VLANのトラフィックを流し込む。
なぜこれが「悲哀」なのか
この構成の最大の弱点は、単一の物理リンクにトラフィックが集中することだ。ルータのインターフェースがボトルネックとなり、全パケットがルータを往復するため、物理的な帯域を浪費する。show interface コマンドでインターフェースのトラフィックを見て、冷や汗をかいた経験のあるエンジニアも多いはずだ。
設定例(Cisco IOS)
# サブインターフェースを使ってVLAN 10と20をルーティングする
interface GigabitEthernet0/0.10
encapsulation dot1Q 10 # VLAN 10のタグを識別
ip address 192.168.10.1 255.255.255.0
interface GigabitEthernet0/0.20
encapsulation dot1Q 20 # VLAN 20のタグを識別
ip address 192.168.20.1 255.255.255.0
この構成は、小規模環境や安価なL2スイッチしか使えない現場では今でも現役だ。しかし、現代のハイパフォーマンスなシステムでは、この「ルータへの往復」は遅延の原因となる。
—
2. 現代のスタンダード:L3スイッチのSVIルーティング
現代のデータセンターやオフィスネットワークで主役を張るのは、Switch Virtual Interface(SVI)を用いたL3スイッチによるルーティングだ。
スイッチのハードウェア(ASIC)がルーティング処理を行うため、ルータにパケットを飛ばす必要はない。スイッチのバックプレーン内で完結するこの仕組みこそ、高速な通信を支える屋台骨だ。
SVIの挙動を解剖する
SVIは、特定のVLANに対応する仮想的なインターフェースだ。L3スイッチは、このSVIに対して IPアドレス を割り当てることで、そのVLANのデフォルトゲートウェイとして機能する。
# VLANの設定
vlan 10
name Web_Server_VLAN
vlan 20
name App_Server_VLAN
# SVIインターフェースの設定
interface Vlan10
ip address 192.168.10.254 255.255.255.0
no shutdown
interface Vlan20
ip address 192.168.20.254 255.255.255.0
no shutdown
# ルーティング機能の有効化(機種による)
ip routing
ここでのポイントは、ip routing コマンドを打った瞬間に、このデバイスはスイッチからルータへと「進化」するということだ。ARP キャッシュと FIB(Forwarding Information Base)が連携し、ワイヤースピードでパケットが転送される。
—
3. Web API開発者が知っておくべき「ネットワークの境界線」
インフラエンジニアだけがネットワークを知っていれば良い時代は終わった。Web APIを設計する際、リクエストがどの VLAN を経由し、どこでルーティングされているかを知ることは、レイテンシ改善やトラブルシューティングの初手となる。
例えば、Python で別VLAN上のAPIを叩く際、接続エラーが発生したとしよう。その時、単に「接続できない」で終わらせず、パケットがどこでドロップしているかを確認すべきだ。
確認のためのPythonスニペット
import requests
# 別VLAN上のAPIエンドポイントへの疎通確認
def check_api_connectivity(url):
try:
# タイムアウトを短めに設定してルーティングの問題を早期検知
response = requests.get(url, timeout=2)
print(f"Status Code: {response.status_code}")
except requests.exceptions.ConnectTimeout:
print("Error: ルーティング、あるいはACLで遮断されている可能性があります")
except Exception as e:
print(f"Unexpected error: {e}")
check_api_connectivity("http://192.168.20.10/api/v1/data")
もし ConnectTimeout が発生するなら、それはOSI参照モデルの第3層(L3)の問題だ。traceroute を実行し、ゲートウェイである SVI のアドレスまでパケットが届いているかを確認しよう。
—
4. 現場の教訓:トラブルシューティングの鉄則
最後に、私が現場で数々の障害を切り抜けてきた経験から、一つだけアドバイスを送る。
「ルーティングがうまくいかないとき、犯人は大抵 ACL か ARP である」
1. ACL(Access Control List): VLAN間ルーティングを有効にしても、スイッチの VLAN interface に適用されたインバウンド/アウトバウンドの ACL がトラフィックを殺していることがよくある。show ip access-lists でカウンタが動いているか、必ず確認すること。
2. ARPの不一致: ルータ側は認識しているのに、クライアント側のデフォルトゲートウェイ設定が間違っている、あるいはルータが Proxy ARP を返していないケースだ。
ネットワークは「魔法」ではない。パケットは物理法則に従い、設定されたロジック通りに流れるだけだ。もし通信が途絶えたら、まずはパケットの経路を紙に書き出し、どのノードで何が起きているかを論理的に分解してほしい。
プロトコルの裏側にある「意図」を理解すること。それが、真のスペシャリストへの第一歩だ。
コメント