Prometheus+snmp_exporterでIX2105を監視する

前回(IX2105 で DS-Lite と接続して爆速インターネットをやる)に引き続き、IX2105 の設定を行っていきます。 今回は Prometheus での監視をやっていきます。

  • IX2105 で SNMP を有効化する
  • snmp_exporter の導入
  • カスタムモジュールを定義して snmp_exporter に PR を投げる
  • Prometheus の設定を行う
  • Grafana で可視化する

IX2105 で SNMP を有効化する

まず IX2105 側の SNMP 機能を有効にします。 今回は IP 制限を行いません。

snmp-agent ip enable
snmp-agent ip community public

手元の Linux マシンから接続が行えるかを確かめてみます。

$ snmpwalk -v1 192.168.111.1 -c public 1.3.6.1.2.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "NEC Portable Internetwork Core Operating System Software, IX Series IX2105 (magellan-sec) Software, Version 9.7.15, RELEASE SOFTWARE, Compiled Mar 13-Tue-2018 18:18:58 JST #2, IX2105"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.119.1.84.14.1
iso.3.6.1.2.1.1.3.0 = Timeticks: (17331617) 2 days, 0:08:36.17
iso.3.6.1.2.1.1.4.0 = ""
iso.3.6.1.2.1.1.5.0 = STRING: "Router"
iso.3.6.1.2.1.1.6.0 = ""
iso.3.6.1.2.1.1.7.0 = INTEGER: 72

snmp_exporter の導入

次は Prometheus からの監視を行いたいので、snmp_exporter のバイナリを適当にダウンロードして試してみます。 デフォルトではポート 9116 で HTTP サーバが起動します。

DL 先: https://github.com/prometheus/snmp_exporter/releases

$ ./snmp_exporter &
$ curl localhost:9116/snmp?target=192.168.111.1
$ curl localhost:9116/snmp?target=192.168.111.1&module=if_mib  # 同じ意味(モジュール名を明示的に指定)

すると、こんな調子でつらつらとメトリクスが出てきます。

# TYPE ifHCInOctets counter
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet0",ifIndex="1",ifName="GigaEthernet0"} 1.5119176458e+10
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet0-Multiplexor",ifIndex="3",ifName="GigaEthernet0-Multiplexor"} 1.5119176458e+10
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet0.0",ifIndex="355",ifName="GigaEthernet0.0"} 1.5119176458e+10
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet0.0-LAN",ifIndex="13",ifName="GigaEthernet0.0-LAN"} 1.5119176458e+10
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet1",ifIndex="2",ifName="GigaEthernet1"} 5.20355025575e+11
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet1-Multiplexor",ifIndex="4",ifName="GigaEthernet1-Multiplexor"} 5.20355024179e+11
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet1.0",ifIndex="356",ifName="GigaEthernet1.0"} 5.20355024179e+11
ifHCInOctets{ifAlias="",ifDescr="GigaEthernet1.0-LAN",ifIndex="14",ifName="GigaEthernet1.0-LAN"} 5.20355024179e+11
ifHCInOctets{ifAlias="",ifDescr="Tunnel0",ifIndex="223",ifName="Tunnel0"} 9.327241604e+09
ifHCInOctets{ifAlias="",ifDescr="Tunnel0.0",ifIndex="726",ifName="Tunnel0.0"} 9.327241604e+09

適当に SNMP の代表的なメトリクスを export してくれます。 gauge, counter とかの区別も付いていてすごいですね。 ですが、プライベート MIB に含まれる機器特有のファン回転数・筐体温度等のメトリクス情報は取得できません。

IX の場合は、以下の URL に取得できる情報の一覧が有りました。 温度・ファン・CPU 使用率・メモリ・IPsec 等、面白そうなメトリクスが多数含まれています。 これらを snmp_exporter で取得するためにはモジュールの定義を行う必要があります。 デフォルトでは標準的なメトリクスを取得する if_mib モジュールの他、ベンダー依存の cisco_wlc arista_sw ddwrt keepalived が定義されています。 NEX の IX は定義されていないので、今回は nec_ix モジュールを作ってみましょう。

IX での SNMP 仕様: https://jpn.nec.com/univerge/ix/faq/snmpv1.html

カスタムモジュールを定義して snmp_exporter に PR を投げる

自分が投げた PR がマージされたので、次のリリースから IX の監視を行うためにカスタムモジュールを定義する必要はなくなりました。モジュール名は nec_ix として公開されています。 https://github.com/prometheus/snmp_exporter/pull/427

どの SNMP のメトリクス値を取得して何のラベルを付けるかは、同一ディレクトリに保存されている snmp.yml ファイルで定義しています。 見てみると、CiscoWLC, Arista, keepalived 等のプライベート MIB が含まれることが分かると思います。

https://github.com/prometheus/snmp_exporter/blob/master/snmp.yml

ただ、この 1 万行を超えるファイルを手で管理しているわけではありません。 MIB の定義ファイルから自動で生成するためのジェネレータが同一リポジトリに有ります。

https://github.com/prometheus/snmp_exporter/tree/master/generator

  1. make で MIB の定義ファイルを取得する
  2. generator.yml に書かれたルールに従って MIB 定義ファイルを参照
  3. 各メトリクスの名前・種類・説明文などを snmp.yml に出力
  4. snmp_exporter が snmp.yml の情報を使用して、SNMP エージェントが持つ値を取得・ /metrics へ公開

ですので通常拡張を行うときは、 Makefile generator.yml のみ編集すれば良いです。 今回は、 generator.yml に以下のように追記しました。 今回はメトリクスの定義が素直だったので、walk のみ記述すれば適切にメトリクスの取得が行えました。 この定義を行うことで、 picoSystem 以下の picoCelsius picoFahrenheit 等の子のメトリクスが再帰的に取得できるようになります。

modules:
  nec_ix:
    walk:
      - picoSystem
      - picoIpSecFlowMonitorMIB
      - picoExtIfMIB
      - picoNetworkMonitorMIB
      - picoIsdnMIB
      - picoNgnMIB
      - picoMobileMIB
      - picoIPv4MIB
      - picoIPv6MIB

curl localhost:9116/snmp?target=192.168.111.1&module=nec_ix と叩けば、CPU 使用率・ヒープ使用率・IPSec の状態・ファンの状態・電源の状態など、面白そうなメトリクスが取得できるようになりました。

Prometheus の設定を行う

スクレイピングの設定を行います。 ポイントとしては、ネットワーク機器の IP アドレスを指定しますが、その機器に HTTP でメトリクスを取得しに行くことは出来ないので、 __address__ ラベルを置換して全て snmp_exporter にリクエストを送信する必要があります。

設定例はこのようになります。 snmp-exporter.example.com:9116 は、自分で立てた snmp_exporter のアドレスを指定してください。 module には複数指定が出来ないので、屈辱的ですがこのように 2 つ書くことになります。

scrape_configs:
  - job_name: "snmp_if_mib"
    static_configs:
      - targets:
          - 192.168.111.1 # ix2105
    metrics_path: /snmp
    params:
      module: [if_mib]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: snmp-exporter.example.com:9116 # The SNMP exporter's real hostname:port.
  - job_name: "snmp_nec_ix"
    static_configs:
      - targets:
          - 192.168.111.1 # ix2105
    metrics_path: /snmp
    params:
      module: [nec_ix]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: snmp-exporter.example.com:9116 # The SNMP exporter's real hostname:port.

Grafana で可視化する

とりあえず {job="snmp_nec_ix"} などでクエリを叩けばざーっと値が出てくるので、ほしそうなモノを Dashboard に突っ込んでいくだけです。

Explore での表示例。

ダッシュボードの設定例。

ファンが搭載されているモデルだと回転数などが取れるようになったのですが、IX2105 はファンレスなので残念ながら確認できないです。 ホンマか?と思うものの、通信を大量に流してもせいぜい CPU は 20%程度しか使っていないようです。 なので、特に温度が上がるわけでもなく暇なグラフになっています… 異常なときに調査できるように貯めておくので良いんですが寂しいです。

おわり

PR も無事マージされたし、IX は安定して動いているし満足です。 Vyos を Hypter-V で動かしていたので、WindowsUpdate が発生してネットが定期的に落ちるという心配もなくなりました。