ネットワークの「悲劇」を防ぐ守護神:STP(Spanning Tree Protocol)の深淵を覗く
ネットワークエンジニアという人種は、往々にして「ループ」という言葉に悪夢を見るものです。スイッチを一つ繋ぎ間違えただけで、ブロードキャストストームが発生し、ネットワーク全体が使い物にならなくなる――。あの瞬間、管理画面にログインすらできず、ただひたすらパケットが飽和する音(ファンの唸り)を聞く絶望感は、一度味わえば二度と忘れません。
そんな悲劇を未然に防ぐために、我々には IEEE 802.1D で定義された Spanning Tree Protocol (STP) があります。今日は、教科書の定義をなぞるのではなく、現場で「なぜそのポートがブロックされたのか」を即座に判断できる、エンジニアのためのSTP解説をお届けします。
—
1. STPの本質:論理的な「木」を作るアルゴリズム
STPの目的はシンプルです。冗長構成(ループ)を維持しつつ、論理的に「木構造」を作ることで、単一のパスだけをアクティブにすることです。そのプロセスは、以下の3ステップで完結します。
1. ルートブリッジの選出: ネットワークの頂点を決める。
2. ルートポートの選出: 各スイッチからルートブリッジへ至る「最短」の道を決める。
3. 指定ポート(Designated Port)の選出: 各セグメントにおいて、ルートへ繋がる代表者を選ぶ。
これらに選ばれなかった「選外」のポートが、Blocking 状態となり、ループを物理的に遮断します。
ルートブリッジ選出の極意
ルートブリッジは Bridge Priority(デフォルト32768)と MACアドレス の組み合わせ、つまり Bridge ID で決まります。
- Priority が小さいほうが勝つ。
- 同点なら MACアドレス が小さいほうが勝つ。
実務Tips: ネットワークの設計において、ルートブリッジが「適当なスイッチ」に決まってしまうのはNGです。必ずコアスイッチに低い Priority を設定し、意図的にルートとして固定してください。
# Cisco IOSでの設定例
# プライオリティを下げて、このスイッチを確実にルートにする
(config)# spanning-tree vlan 1 priority 4096
—
2. パス選択の鍵:パスコストとポートID
STPにおいて「最短」を決めるのは Path Cost です。これはリンクの帯域幅(スピード)に基づきます。
- 10Mbps: 100
- 100Mbps: 19
- 1Gbps: 4
- 10Gbps: 2
パケットがスイッチ間を移動する際、受信したポートのコストを累積していきます。もしコストが同じ場合、次に比較されるのが Bridge ID、それでも同じなら Port ID です。
—
3. 実践:トポロジの可視化と確認
開発エンジニアの皆さんが「APIのレスポンスが妙に遅い」あるいは「パケットロスがある」と疑うとき、インフラ側ではこうした STP のステータスを確認しています。例えば、curl で死活監視を打つ際、もしループが起きていれば TCP Handshake すら不安定になります。
まずは、現在のSTP状態をコマンドラインから確認する例を見てみましょう。
# スイッチの現在のSTP状態を確認
show spanning-tree vlan 1
# 出力例(抜粋)
# Root ID: Priority 4096, Address 0011.2233.4455
# This bridge is the root
# Interface Role Sts Cost Prio.Nbr Type
# Fa0/1 Desg FWD 19 128.1 P2p
# Fa0/2 Altn BLK 19 128.2 P2p
この Altn (Alternate) が BLK (Blocking) になっていることが、STPが正しく機能している証です。
—
4. API設計者へ贈る:インフラとアプリケーションの境界線
Web API を設計・運用している皆さんに伝えたいのは、「ネットワーク層の再計算はアプリケーション層に致命的な影響を与える」ということです。
STPのトポロジが変化(Topology Change Notification)すると、MACアドレス学習テーブルがフラッシュされます。この数秒間、ネットワークは「どこに誰がいるか」を再学習するため、一時的にブロードキャストが溢れ、通信が不安定になります。
Pythonでネットワークの疎通を確認するスクリプトを書くなら、単なる GET リクエストだけでなく、タイムアウトを短めに設定して「瞬断」を検知できるようにしておくのが定石です。
import requests
from requests.exceptions import ConnectTimeout
def check_network_stability(url):
try:
# STP再計算による一時的な断線を検知するために短めのタイムアウト
response = requests.get(url, timeout=1.0)
return response.status_code == 200
except ConnectTimeout:
print("警告: ネットワークの再計算やパケットロスが発生している可能性があります")
return False
# 運用監視のループ内で呼び出す想定
—
最後に:安定したインフラを作るために
STPは古いプロトコルですが、今なおデータセンターの基盤を支える強力な仕組みです。しかし、現代のインフラでは Rapid STP (802.1w) への移行が必須です。15〜30秒かかるコンバージェンスを数秒に縮めるだけで、ユーザー体験は劇的に変わります。
もし皆さんがスイッチの設定を触る機会があれば、まずは show spanning-tree を叩いてみてください。そこに表示される Root ID と Cost は、あなたのネットワークがどのように「呼吸」しているかを示す、最も正直なデータなのです。
ネットワークは、決して魔法ではありません。すべての挙動には理由があります。その理由を解き明かす楽しさを、ぜひ皆さんの日々の業務でも感じていただければ幸いです。
コメント