みなさんこんにちは。マネージドサービス課の塩野です。
New Relicのネットワークオブザーバビリティやってみようとしたけど、標準プロファイルに情報がなくほしい情報の取得ができないということはないでしょうか。やっぱりネットワーク機器の監視で、ベンダー独自の詳細なメトリクスを取得したいことがありますよね。
標準MIBだけでは物足りない場合、カスタムMIBの設定が必要です。この記事では、MIBファイルからJSONへの変換を含めた、カスタムMIB設定の実践的な手順を解説します。
目次
概要
New RelicのSNMP監視では、ktranslateというDockerコンテナを使って実施します。
実際の作業では、標準的なプロファイルに欲しい情報がなく、ベンダーから入手したMIBファイルを解析し、必要なOIDを特定してYAMLプロファイルを作成することが多いですね。手順を追って進めれば、標準では取得できないベンダー固有のメトリクスも監視できるようになります。
SNMP監視の基本的な仕組み
SNMP(Simple Network Management Protocol)は、ネットワーク機器を監視・管理するための標準プロトコルです。ルーターやスイッチ、ファイアウォールなど、多くの機器がSNMPに対応しています。
SNMPでは、監視対象の情報を「OID(Object Identifier)」という一意の識別子で管理します。このOIDと情報の構造を定義したものがMIB(Management Information Base)です。
graph LR
A[監視サーバー<br/>ktranslate] -->|SNMPリクエスト<br/>OID指定| B[ネットワーク機器]
B -->|SNMPレスポンス<br/>メトリクス値| A
A -->|データ送信| C[New Relic]
style A fill:#1CE783
style B fill:#00B4D8
style C fill:#1CE783
MIBには標準MIBとカスタムMIBがあります。
標準MIBは、IF-MIBやHOST-RESOURCES-MIBなど、多くの機器で共通して使える汎用的なものです。インターフェースの統計情報やCPU使用率といった基本的なメトリクスを取得できます。
カスタムMIBは、ベンダーが独自に定義したMIBです。Cisco、Arista、Juniperなどのベンダーは、自社製品特有の機能や詳細な情報を提供するために独自のMIBを用意しています。例えば、Ciscoのメモリプール情報やAristaのBGP詳細情報などがこれに該当します。
New RelicでのSNMP監視アーキテクチャ
New RelicのSNMP監視は、ktranslateというオープンソースのDockerコンテナを使って実現されています。このコンテナ(ktranslate)がSNMPマネージャとして動作し、ネットワーク上のSNMPエージェントからメトリクスを収集してNew Relicに送信します。
graph TB
subgraph "監視対象ネットワーク"
D1[Router 1<br/>10.0.0.1]
D2[Switch 1<br/>10.0.0.2]
D3[Firewall 1<br/>10.0.0.3]
end
subgraph "監視基盤"
K[ktranslate<br/>Dockerコンテナ]
C[snmp-base.yaml<br/>設定ファイル]
M[MIBプロファイル<br/>ディレクトリ]
end
subgraph "New Relicプラットフォーム"
N[New Relic<br/>メトリクス収集]
E[Entity<br/>デバイス管理]
end
D1 -->|SNMPポーリング| K
D2 -->|SNMPポーリング| K
D3 -->|SNMPポーリング| K
C -.設定読み込み.-> K
M -.MIB定義参照.-> K
K -->|メトリクス送信| N
N --> E
style K fill:#00B4D8
style N fill:#1CE783
style E fill:#1CE783
設定の中心となるのがsnmp-base.yamlというファイルです。このファイルに監視対象のデバイス情報、SNMPの認証情報、ポーリング間隔などを記述します。
MIBプロファイルは、各ベンダーの機器に対応したYAMLファイルで、どのOIDを収集するかが定義されています。New Relicは公式のSNMPプロファイルリポジトリを提供しており、主要なベンダーの機器に対応したプロファイルが用意されています。
カスタムMIBを使う場合は、このプロファイルを自分で作成するか、既存のプロファイルをカスタマイズすることになります。
カスタムMIBの設定手順
実際にカスタムMIBを設定する手順を見ていきます。大きく分けて6つのステップがあります。
graph TD
A[MIBファイル入手] --> B[MIBをJSONに変換]
B --> C[JSONを解析してOID特定]
C --> D[SNMP Walkで実機確認]
D --> E[YAMLプロファイル作成]
E --> F[snmp-base.yaml設定]
F --> G[コンテナ起動]
style A fill:#FFE5B4
style B fill:#FFE5B4
style C fill:#B4E5FF
style D fill:#B4E5FF
style E fill:#C8E6C9
style F fill:#C8E6C9
style G fill:#C8E6C9
ステップ1: MIBファイルの入手と配置
まず、監視したい機器のベンダーからMIBファイルを入手します。多くのベンダーは、サポートサイトやダウンロードページでMIBファイルを公開しています。
MIBファイルは通常.mibや.txtという拡張子で提供されます。これらのファイルには、OIDの定義や構造が記述されています。
# MIBファイル用のディレクトリを作成 mkdir -p /opt/newrelic/snmp/mibs mkdir -p /opt/newrelic/snmp/json # ベンダーから入手したMIBファイルを配置 cp VENDOR-CUSTOM-MIB.mib /opt/newrelic/snmp/mibs/
ステップ2: MIBファイルをJSONに変換
MIBファイルは人間が読むには複雑な形式なので、JSONに変換して解析しやすくします。PySMIというPythonライブラリのmibdumpツールを使います。
# PySMIのインストール pip install pysmi # MIBをJSONに変換 mibdump --destination-format json \ --destination-directory /opt/newrelic/snmp/json \ VENDOR-CUSTOM-MIB
変換が成功すると、/opt/newrelic/snmp/json/VENDOR-CUSTOM-MIB.jsonというファイルが生成されます。
ステップ3: JSONファイルの解析
生成されたJSONファイルを開いて、必要なOIDを特定します。JSONファイルは以下のような構造になっています。
{ "VENDOR-CUSTOM-MIB": { "meta": { "module": "VENDOR-CUSTOM-MIB" }, "objects": { "deviceInfo": { "name": "deviceInfo", "oid": "1.3.6.1.4.1.9999.1.1", "nodetype": "node" }, "deviceTemperature": { "name": "deviceTemperature", "oid": "1.3.6.1.4.1.9999.1.1.1", "nodetype": "scalar", "class": "objecttype", "syntax": { "type": "Integer32" }, "maxaccess": "read-only", "status": "current", "description": "Current device temperature in Celsius" }, "interfaceStatsTable": { "name": "interfaceStatsTable", "oid": "1.3.6.1.4.1.9999.1.2.1", "nodetype": "table", "class": "objecttype", "maxaccess": "not-accessible", "status": "current" }, "interfaceStatsEntry": { "name": "interfaceStatsEntry", "oid": "1.3.6.1.4.1.9999.1.2.1.1", "nodetype": "row", "class": "objecttype", "maxaccess": "not-accessible" }, "interfaceIndex": { "name": "interfaceIndex", "oid": "1.3.6.1.4.1.9999.1.2.1.1.1", "nodetype": "column", "class": "objecttype", "syntax": { "type": "Integer32" }, "maxaccess": "read-only" }, "interfaceName": { "name": "interfaceName", "oid": "1.3.6.1.4.1.9999.1.2.1.1.2", "nodetype": "column", "class": "objecttype", "syntax": { "type": "DisplayString" }, "maxaccess": "read-only" }, "interfaceErrors": { "name": "interfaceErrors", "oid": "1.3.6.1.4.1.9999.1.2.1.1.3", "nodetype": "column", "class": "objecttype", "syntax": { "type": "Counter64" }, "maxaccess": "read-only", "description": "Total number of errors on this interface" } } } }
このJSONから、以下の情報を読み取ります。
スカラーOIDの見つけ方
nodetypeがscalarのオブジェクトを探します。上記の例ではdeviceTemperatureがスカラーOIDです。
oid:1.3.6.1.4.1.9999.1.1.1syntax.type:Integer32(数値型)maxaccess:read-only(読み取り専用)description: 説明文
スカラーOIDは単一の値を返すため、YAMLではsymbolとして定義します。
テーブルOIDの見つけ方
nodetypeがtableのオブジェクトを探します。上記の例ではinterfaceStatsTableがテーブルOIDです。
テーブルには複数の行(エントリー)があり、各行には複数のカラムがあります。
- テーブル本体:
interfaceStatsTable(OID:1.3.6.1.4.1.9999.1.2.1) - エントリー:
interfaceStatsEntry(OID:1.3.6.1.4.1.9999.1.2.1.1) - カラム:
interfaceIndex(OID:1.3.6.1.4.1.9999.1.2.1.1.1) - インデックスinterfaceName(OID:1.3.6.1.4.1.9999.1.2.1.1.2) - 名前(文字列)interfaceErrors(OID:1.3.6.1.4.1.9999.1.2.1.1.3) - エラー数(数値)
テーブルOIDは複数行のデータを返すため、YAMLではtableとして定義します。
データ型の確認
syntax.typeを見ると、データ型が分かります。
Integer32,Counter32,Counter64,Gauge32: 数値型 → メトリクスとして収集可能DisplayString,OctetString: 文字列型 → タグとして使用IpAddress: IPアドレス型 → タグとして使用
数値型のOIDはメトリクスとして、文字列型のOIDはタグ(ディメンション)として使うのが基本です。
ステップ4: SNMP Walkで実機確認
JSONで特定したOIDが実際の機器でサポートされているか、SNMP Walkで確認します。
# 特定のOIDツリーをWalk snmpwalk -v2c -c public 192.168.1.100 1.3.6.1.4.1.9999 > device_snmpwalk.txt
出力例を見てみます。
SNMPv2-SMI::enterprises.9999.1.1.1.0 = INTEGER: 45 SNMPv2-SMI::enterprises.9999.1.2.1.1.1.1 = INTEGER: 1 SNMPv2-SMI::enterprises.9999.1.2.1.1.2.1 = STRING: "eth0" SNMPv2-SMI::enterprises.9999.1.2.1.1.3.1 = Counter64: 1234 SNMPv2-SMI::enterprises.9999.1.2.1.1.1.2 = INTEGER: 2 SNMPv2-SMI::enterprises.9999.1.2.1.1.2.2 = STRING: "eth1" SNMPv2-SMI::enterprises.9999.1.2.1.1.3.2 = Counter64: 5678
この出力から以下のことが確認できます。
1.3.6.1.4.1.9999.1.1.1.0(deviceTemperature)は値45を返している1.3.6.1.4.1.9999.1.2.1(interfaceStatsTable)には2行のデータがある- 1行目: インデックス1, 名前"eth0", エラー数1234
- 2行目: インデックス2, 名前"eth1", エラー数5678
JSONで見つけたOIDが実際に値を返していることが確認できました。この確認作業は重要です。MIBファイルに定義されていても、機器のファームウェアバージョンによってはサポートされていないOIDもあるためです。
ステップ5: YAMLプロファイルの作成
JSONとSNMP Walkの結果を基に、YAMLプロファイルを作成します。
# custom-device.yml --- extends: - system-mib.yml provider: kentik-default sysobjectid: - 1.3.6.1.4.1.9999.* metrics: # スカラーOID: デバイス温度 - MIB: VENDOR-CUSTOM-MIB symbol: OID: 1.3.6.1.4.1.9999.1.1.1.0 name: deviceTemperature poll_time_sec: 60 # テーブルOID: インターフェース統計 - MIB: VENDOR-CUSTOM-MIB table: OID: 1.3.6.1.4.1.9999.1.2.1 name: interfaceStatsTable symbols: - OID: 1.3.6.1.4.1.9999.1.2.1.1.3 name: interfaceErrors poll_time_sec: 60 metric_tags: - column: OID: 1.3.6.1.4.1.9999.1.2.1.1.2 name: interfaceName
YAMLの各項目の意味
extends: 継承する既存プロファイル。system-mib.ymlは標準的なシステムメトリクスを含むprovider: New Relicでのエンティティ識別子sysobjectid: このプロファイルを適用する機器のsysObjectID(ワイルドカード可)metrics: 収集するメトリクスのリスト
スカラーOIDの定義
- MIB: VENDOR-CUSTOM-MIB symbol: OID: 1.3.6.1.4.1.9999.1.1.1.0 name: deviceTemperature poll_time_sec: 60
MIB: MIBファイル名(拡張子なし)symbol.OID: JSONのoidフィールドの値 +.0(スカラーは末尾に.0が必要)symbol.name: New Relicで表示されるメトリクス名(JSONのnameを使うのが一般的)poll_time_sec: ポーリング間隔(秒)
※symbol.OIDは、JSONに .0 が含まれていない場合の対応
※必ずsnmpwalk/snmpget で確認すること
テーブルOIDの定義
- MIB: VENDOR-CUSTOM-MIB table: OID: 1.3.6.1.4.1.9999.1.2.1 name: interfaceStatsTable symbols: - OID: 1.3.6.1.4.1.9999.1.2.1.1.3 name: interfaceErrors metric_tags: - column: OID: 1.3.6.1.4.1.9999.1.2.1.1.2 name: interfaceName
table.OID: テーブルのOID(JSONのinterfaceStatsTableのoid)table.name: テーブル名symbols: 収集する数値カラムのリストOID: カラムのOID(JSONのinterfaceErrorsのoid)name: メトリクス名
metric_tags: タグとして使う文字列カラムのリストcolumn.OID: カラムのOID(JSONのinterfaceNameのoid)column.name: タグ名
この設定により、New Relicでは以下のようなメトリクスが記録されます。
deviceTemperature: 45
interfaceErrors{interfaceName="eth0"}: 1234
interfaceErrors{interfaceName="eth1"}: 5678
ステップ6: snmp-base.yamlの設定
作成したプロファイルを使用するように、snmp-base.yamlを編集します。
devices: custom_device_192.168.1.100: device_name: custom_device device_ip: 192.168.1.100 snmp_comm: public oid: .1.3.6.1.4.1.9999.1.1 mib_profile: custom-device.yml provider: kentik-default poll_time_sec: 60 user_tags: environment: production location: datacenter-1 global: poll_time_sec: 60 mib_profile_dir: /etc/ktranslate/profiles mibs_enabled: - VENDOR-CUSTOM-MIB - IF-MIB - HOST-RESOURCES-MIB
mibs_enabledセクションに、使用するカスタムMIBを追加することが重要です。ここに記載されていないMIBは、プロファイルで定義されていてもポーリングされません。
ステップ7: Dockerコンテナの起動
設定ファイルとプロファイルの準備ができたら、ktranslateコンテナを起動します。
docker run -d --name ktranslate-snmp \
--restart unless-stopped \
-v $(pwd)/snmp-base.yaml:/snmp-base.yaml \
-v /opt/newrelic/snmp/profiles:/etc/ktranslate/profiles \
-v /opt/newrelic/snmp/mibs:/etc/ktranslate/mibs \
-e NEW_RELIC_API_KEY=$YOUR_LICENSE_KEY \
kentik/ktranslate:v2 \
-snmp /snmp-base.yaml \
-nr_account_id=$YOUR_ACCOUNT_ID \
-metrics=jchf \
-tee_logs=true \
-service_name=snmp-polling \
nr1.snmp
ボリュームマウントで、設定ファイル、プロファイルディレクトリ、MIBディレクトリをコンテナ内にマッピングしています。
コンテナが正常に起動したら、ログを確認してエラーがないかチェックします。
docker logs ktranslate-snmp
正常に動作していれば、数分後にNew Relicのダッシュボードでメトリクスが表示されるようになります。
トラブルシューティングのポイント
カスタムMIBの設定でよく遭遇する問題と対処法をまとめておきます。
メトリクスが表示されない場合
まず確認すべきは、mibs_enabledセクションにカスタムMIBが追加されているかです。プロファイルで定義していても、ここに記載がないとポーリングされません。
次に、デバイスのmib_profile設定が正しいプロファイルファイルを指しているか確認します。ファイル名のタイポや拡張子の間違いがないかチェックしましょう。
SNMPの認証情報(コミュニティストリングやSNMPv3の認証情報)が正しいかも重要です。機器側のSNMP設定と一致しているか確認してください。
OIDが見つからないエラー
MIBファイルが正しく配置されていない可能性があります。コンテナ内の/etc/ktranslate/mibsディレクトリにMIBファイルが存在するか確認します。
また、MIBファイルに依存関係がある場合、必要なすべてのMIBファイルが揃っているか確認が必要です。ベンダーのMIBは、他のMIBを参照していることがよくあります。
ポーリングタイムアウト
timeout_msの値を増やすことで改善する場合があります。デフォルトは3000ミリ秒ですが、応答が遅い機器では5000〜10000ミリ秒に設定するとよいでしょう。
devices: slow_device: device_name: slow_device device_ip: 192.168.1.200 timeout_ms: 10000 retries: 2
retriesを設定することで、タイムアウト時の再試行回数を増やすこともできます。
まとめ
New RelicでカスタムMIBを使ったSNMP監視を設定する方法を紹介しました。
設定の流れをおさらいすると、まずベンダーからMIBファイルを入手し、PySMIでJSONに変換します。JSONファイルを解析してスカラーOIDとテーブルOIDを特定し、SNMP Walkで実機確認を行います。その後、YAMLプロファイルを作成してOIDとメトリクスのマッピングを定義し、snmp-base.yamlでデバイスとプロファイルを紐付け、最後にktranslateコンテナを起動するという手順でした。
標準MIBだけでは取得できないベンダー固有のメトリクスを監視できるようになると、ネットワークの可視性が大きく向上します。New Relicの公式SNMPプロファイルリポジトリには、多くのベンダーのプロファイルが公開されているので、まずはそこから自分の環境に合ったものを探してみるのがおすすめです。既存のプロファイルを見れば、YAMLの書き方の参考にもなります。
この記事がどなたかのお役に立てれば幸いです。
宣伝
弊社では、お客様環境のオブザーバビリティを加速するためのNew Relicアカウント開設を含めた伴走型のNew Relic導入支援サービスをご提供しております。もしご興味をお持ちの方は、こちらのお問合せフォームよりお問合せ頂けましたら幸いでございます。
参照
◆ 塩野 正人
◆ マネージドサービス部 所属
◆ X(Twitter):@shioccii
◆ 過去記事はこちら
前職ではオンプレミスで仮想化基盤の構築や運用に従事。現在は運用部隊でNew Relicを使ってサービス改善に奮闘中。New Relic User Group運営。