実際の現場で起きた問題:SNMPポーリングが抱える「5分間の死角」
前四半期、社内の主要なSIPトランクで、3箇所の地方拠点にまたがり通話の切断が無作為に発生し始めました。Mean Opinion Score(MOS:音声品質評価値)は良好な4.3から1.8へと急落。拠点スタッフからは20分おきに音声が途切れるという報告が上がっていたにもかかわらず、監視ダッシュボードのインジケーターはすべて平穏なグリーンのままでした。平均インターフェース使用率は42%前後に留まり、コアスイッチのCPU使用率は18%、インターフェースのエラーカウンタもゼロを示していたのです。
ダッシュボード上は何一つ異常がないように見えましたが、回線上の実態は深刻でした。
光スプリッターでアップリンクを分岐し、ハードウェアキャプチャを実施したところ、原因はすぐに判明しました。連続して実行されたデータベースのレプリケーション処理が、100Gbpsのフルラインレートで450ミリ秒間のバーストトラフィックを発生させていたのです。このマイクロバーストがスイッチの32MB共有パケットバッファを枯渇させ、RTP音声パケットをサイレントにドロップしていました。ネットワーク管理システム(NMS)がSNMP経由で300秒ごとにしかインターフェース統計をポーリングしていなかったため、このスパイクを完全に検知できていなかったのです。
SNMPは現場の実態を単に「平均化」して覆い隠してしまいます。100Gポートは毎秒1億4,000万個以上のパケットを送信します。NMSが5分に1回しかサンプリングを行わなければ、瞬間的なトラフィックサージは滑らかで無害なグラフへと平滑化されてしまいます。グラフ上からマイクロバーストが消え去っても、エンドユーザーはその悪影響を直接受けているのです。
根本原因分析:プル型SNMPが現代のネットワークで通用しない理由
従来の監視ツールでは、高速化するネットワークファブリックに追従できません。SNMPの根本的なアーキテクチャには物理的な制約があり、単にポーリング間隔を短くするだけでは解決できないのです。
1. プル型アーキテクチャの非効率性
SNMPは、中央のコレクターが数千ものオブジェクト識別子(OID)に対してUDPのGetRequestクエリを繰り返し送信する仕組みに依存しています。標準的な48ポートのTop-of-Rack(ToR)リーフスイッチにおけるオーバーヘッドを考えてみましょう。
- コレクターは、基本的なバイト数やパケット数を取得するだけでも、ポーリングサイクルごとに数百ものOIDリクエストを発行します。
- スイッチのルートプロセッサは制御ループを中断してコンテキストスイッチを行い、メモリ上のMIB(Management Information Base)ツリーを探索(ウォーク)してレスポンスを生成し、UDPパケットを返送します。
- 数百の物理・論理インターフェースを備えたモジュラースイッチでは、SNMPウォークによってコントロールプレーンのCPU使用率が40%を超えてしまうことがあります。深刻なケースでは、BGPやOSPFなどのルーティングプロトコルの処理に必要なCPUリソースを奪ってしまうことさえあります。
2. ナイキストの標本化定理の問題とインキャストバースト
ポーリングによって取得されるメトリクスは、任意の2点間($T_1$と$T_2$)の差分データにすぎません。例えば、あるインターフェースで開始12秒目に200ミリ秒のバーストが発生し、14,000パケットがドロップされた後、残りの299秒間は何事もなかったと仮定します。
300秒目に実行されたSNMPクエリは、その14,000個のドロップを300秒全体に分散させ、毎秒わずか46パケットという取るに足らない平均廃棄率として算出します。ポーリングタイマーをサブ秒単位まで短縮しなければ、テールドロップやTCPインキャストの輻輳を検知することはできません。しかし、そこまで頻度を上げれば、従来のSNMPエンジンはたちまちクラッシュしてしまいます。
3. 脆弱で一貫性のないMIBツリー
ベンダー固有のMIB構造が非常に煩雑であることは広く知られています。Cisco、Arista、Juniper、Linux SONiCが混在する環境で、トランシーバーの光送信出力(DOM)、キュー深度のテレメトリ、BGPピアの状態などを抽出するには、機器ごとに独自のOID変換辞書を保守しなければなりません。OSのアップグレードによってエンタープライズOIDのブランチが変更されると、ダッシュボードは何の予告もなく破損してしまいます。
ソリューション比較:SNMP vs Webhook vs ネットワークストリーミングテレメトリ
テレメトリパイプラインの全面刷新に着手する前に、本番環境で利用可能な3つのデータ収集モデルを比較評価しました。
| 項目 | SNMPv2c / SNMPv3 | HTTP Webhook / イベントスクリプト | gNMI / gRPC ストリーミングテレメトリ |
|---|---|---|---|
| メカニズム | プル型(UDPによる定期的ポーリング) | プッシュ型(イベントごとのリアクティブなHTTP POST) | プッシュ型(gRPC上のHTTP/2による永続ストリーミング) |
| 収集間隔(頻度) | 低頻度(60秒〜300秒) | イベント駆動のみ(状態変更時) | サブ秒単位(1秒ごとの連続送信または変更時送信) |
| データスキーマ | SMIv2 MIB(OID) | 非構造化 JSON / Syslog | 構造化 YANG(OpenConfig、IETF) |
| コントロールプレーンへの負荷 | 高(ソフトウェアによるMIBウォーク) | 中(ローカルスクリプトのフォーク) | ごくわずか(内部キャッシュへのオフロード) |
| トランスポートセキュリティ | 平文(v2c)または煩雑なUSM(v3) | TLS(HTTPS) | ネイティブな相互TLS(mTLS)およびトークン認証 |
Webhookは、リンク障害のような発生頻度の低いアラートには適しています。しかし、毎秒数百万件にも及ぶインターフェースカウンタの継続的な更新負荷には到底耐えられません。リアルタイムメトリクスにおいては、gNMI(gRPC Network Management Interface)が事実上の業界標準となっています。
アーキテクチャ構成:gNMI、Telegraf、InfluxDB
ストリーミングテレメトリは、従来の監視パラダイムを根本から覆します。外部サーバーがカウンタ情報を繰り返し問い合わせるのではなく、スイッチ側から永続的なHTTP/2接続を介してデータを自動的にプッシュします。カウンタデータはマイクロ秒単位の分解能で、内部の状態データベースから直接ストリーミングされます。
本番パイプラインは主に以下の3層で構成されています。
- gNMIネットワークノード:OpenConfig YANGのデータパスを公開するCisco IOS-XEおよびArista EOSスイッチ。
- Telegraf:
inputs.gnmiプラグインを介してスイッチに接続し、protobufストリームを収集・パースする軽量なGo言語製デーモン。 - InfluxDB v2:ナノ秒精度のタイムスタンプとダウンサンプリング機能を備え、メトリクスを保存する専用の時系列データベースエンジン。
ステップ1:スイッチでのgNMIサーバーの有効化
現代のほとんどのスイッチOSには、ネイティブなgNMIデーモンが組み込まれています。主要なエンタープライズ機器でgNMIサービスを公開する手順は以下のとおりです。
Cisco IOS-XE (17.3以降)では、着信Dial-inサブスクリプション用のセキュアなgRPCサーバーを有効化します。
! 暗号化キーとgRPCエンドポイントを有効化
netconf-yang
!
gnmi
port 57400
secure-port 57400
secure-trustpoint Telemetry-mTLS
!
Arista EOS (4.25以降)では、管理APIコンテキスト配下でOcta/gNMIプロバイダーを有効化します。
management api gnmi
transport grpc default
port 57400
ssl profile Telemetry-TLS-Profile
provider eos-native
no shutdown
!
ステップ2:DockerによるInfluxDBとTelegrafのデプロイ
コレクターとデータベースをコンテナ化することで、シンプルかつ再現性の高いデプロイが可能になります。以下が運用環境用のdocker-compose.ymlです。
version: '3.8'
services:
influxdb:
image: influxdb:2.7
container_name: influxdb
restart: unless-stopped
ports:
- "8086:8086"
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=netadmin
- DOCKER_INFLUXDB_INIT_PASSWORD=ChangeThisPasswordNow123!
- DOCKER_INFLUXDB_INIT_ORG=infrastructure
- DOCKER_INFLUXDB_INIT_BUCKET=telemetry_raw
- DOCKER_INFLUXDB_INIT_RETENTION=14d
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=SuperSecretTelegrafToken123!
volumes:
- influxdb_data:/var/lib/influxdb2
telegraf:
image: telegraf:1.30
container_name: telegraf
restart: unless-stopped
depends_on:
- influxdb
network_mode: "host"
volumes:
- ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
- ./certs:/etc/telegraf/certs:ro
volumes:
influxdb_data:
ステップ3:TelegrafでのDial-in gNMIサブスクリプションの設定
Dial-inモードでは、Telegrafがスイッチのポート57400宛てにアウトバウンド接続を確立し、特定のYANGデータパスをリクエストします。これにより、各ネットワーク機器上でカスタムスクリプトを実行する手間を省くことができます。
telegraf.confに以下の設定ブロックを追加します。
[agent]
interval = "1s"
round_interval = true
metric_batch_size = 5000
metric_buffer_limit = 50000
collection_jitter = "0s"
flush_interval = "1s"
flush_jitter = "0s"
logfile = ""
[[outputs.influxdb_v2]]
urls = ["http://127.0.0.1:8086"]
token = "SuperSecretTelegrafToken123!"
organization = "infrastructure"
bucket = "telemetry_raw"
# 入力: リーフスイッチに対するDial-in gNMIクライアント
[[inputs.gnmi]]
addresses = ["10.10.1.1:57400", "10.10.1.2:57400"]
username = "telemetry_svc"
password = "ServiceAccountPass123!"
redial = "10s"
encoding = "proto"
# PKI環境の設定に応じてTLS検証を調整
insecure_skip_verify = false
tls_ca = "/etc/telegraf/certs/ca.pem"
tls_cert = "/etc/telegraf/certs/telegraf.crt"
tls_key = "/etc/telegraf/certs/telegraf.key"
# サブスクリプション 1: 1秒サンプリングのインターフェースカウンタ
[[inputs.gnmi.subscription]]
name = "interfaces"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
subscription_mode = "sample"
sample_interval = "1s"
# サブスクリプション 2: イベント駆動型のポート稼働状態変更
[[inputs.gnmi.subscription]]
name = "interface_oper_status"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/oper-status"
subscription_mode = "on_change"
ステップ4:ストリームの起動と動作検証
テレメトリコレクタースタックをバックグラウンドで起動します。
docker compose up -d
コレクターのログ出力を追跡し、TLSハンドシェイクおよびYANGパスのサブスクリプションが成功していることを確認します。
docker logs -f telegraf
スキーマのパースエラーなどがなく、正常な接続メッセージが出力されていれば成功です。
2026-10-14T12:00:01Z I! [inputs.gnmi] [10.10.1.1:57400] に接続しました
2026-10-14T12:00:01Z I! [inputs.gnmi] [10.10.1.2:57400] に接続しました
2026-10-14T12:00:02Z I! [inputs.gnmi] openconfig-interfaces:/interfaces/interface/state/counters のサブスクリプションを開始しました
ステップ5:InfluxDBでの高粒度メトリクスのクエリ実行
http://<collector-ip>:8086からInfluxDBのUIを開きます。個別の100Gアップリンクにおけるパケットスループットを計算し、マイクロバーストを監視するには、次のFluxクエリを実行します。
from(bucket: "telemetry_raw")
|> range(start: -15m)
|> filter(fn: (r) => r["_measurement"] == "interfaces")
|> filter(fn: (r) => r["_field"] == "in_octets" or r["_field"] == "in_discards")
|> filter(fn: (r) => r["interface_name"] == "HundredGigE1/0/1")
|> derivative(unit: 1s, nonNegative: true)
|> yield(name: "real_time_rate")
サンプリング間隔を1秒に設定したことで、その違いは一目瞭然となりました。以前は42%というフラットな平均値の影に隠れていた450ミリ秒のレプリケーションバーストが、98Gbpsの明確なスパイクとして描画され、その直後に2,300パケットの受信破棄(input discards)が発生している様子がはっきりと確認できたのです。原因の特定にかかる時間は、4時間におよぶ責任の擦り付け合いから、わずか10秒の視覚的分析へと短縮されました。
現場で得られた教訓と実践的な推奨事項
プル型のポーリングからプッシュ型のテレメトリへと切り替えたことで、スイッチのCPU使用率は28%から2.4%へと大幅に低減しました。さらに、移行後わずか2週間のうちに、スパインスイッチで発生していた3件のサイレントパケットドロップの不具合を発見することができました。パイプラインの大規模化に伴う信頼性を維持するために、以下の実践的なルールを遵守してください。
- ステータスフラグには
on_changeサブスクリプションを使用する:ルーティング状態やリンクの稼働ステータスを1秒周期でポーリングすることは絶対に避けてください。on_changeモードでサブスクライブすれば、無駄なサンプリングを排除できます。BGPセッションが切断された際にもミリ秒単位で通知を受け取ることができ、データベースのストレージ容量とネットワーク帯域を節約できます。 - サンプリングレートを適切に階層化する:優先度の高いインターフェースのパケット数やバッファドロップ数は、1秒間隔で収集する価値があります。一方で、環境センサーやシャーシ温度、光トランシーバー(DOM)などは数分単位でしか変動しないため、これらは30秒または60秒間隔でストリーミングします。
- スイッチの管理ポートを堅牢化する:ハードウェアコントロールプレーンポリシング(CoPP)やアクセスコントロールリスト(ACL)を用いて、TCPポート57400を保護してください。テレメトリ接続をコレクターのIPアドレスのみに厳格に制限し、テレメトリ用のユーザーアカウントには読み取り専用(Read-Only)ロールのみを付与します。
SNMPは30年にわたりその役割を果たしてきました。しかし、現代のクラウドネットワークには現代のツールが不可欠です。gNMI、Telegraf、InfluxDBを組み合わせることで、スイッチのコントロールプレーンに過度な負荷をかけることなく、全ポートにわたるサブ秒単位の可視性を即座に手に入れることができます。

