Prometheus Advent Calendar 2017 2日目
の記事です。
SNMP Exporterで何かというネタです。
SNMP Exporterとは
Prometheusを利用して、SNMPで得られる情報をモニタリングしようというときに利用するExporterです。
既存のSNMPマネージャからPrometheusに移行したいと言うときに利用します。
機能は単純で、リクエストが来ると、SNMPを利用して情報を集め、表示するだけのものです。
SNMP Exporterの設定
SNMP Exporterの設定は、 SNMPを利用して何を(どうやって)収集するのか?という1点です。
SNMP Exporterでは、モジュールという単位で何を収集するのかを設定します。
設定ファイルには、多数のモジュールが並列して記載されています。
下記に例をあげます
if_mibというモジュールからの抜粋です
walk にて、snmpwalkするOIDを指定します。
そして、
metricsにて、各OIDの名称と、値のタイプ、Indexが存在する場合はIndexの情報を記載します。
この他、authという、SNMP v2cでいうCommunityの設定やSNMP v3のユーザ名、パスワードなどを設定するセクションなどがあります。
if_mib:
walk:
- 1.3.6.1.2.1.1.3
- 1.3.6.1.2.1.2
- 1.3.6.1.2.1.31.1.1
metrics:
- name: sysUpTime
oid: 1.3.6.1.2.1.1.3
type: gauge
help: The time (in hundredths of a second) since the network management portion
of the system was last re-initialized. - 1.3.6.1.2.1.1.3
- name: ifNumber
oid: 1.3.6.1.2.1.2.1
type: gauge
help: The number of network interfaces (regardless of their current state) present
on this system. - 1.3.6.1.2.1.2.1
- name: ifIndex
oid: 1.3.6.1.2.1.2.2.1.1
type: gauge
help: A unique value, greater than zero, for each interface - 1.3.6.1.2.1.2.2.1.1
indexes:
- labelname: ifIndex
type: gauge
- name: ifDescr
oid: 1.3.6.1.2.1.2.2.1.2
type: DisplayString
help: A textual string containing information about the interface - 1.3.6.1.2.1.2.2.1.2
indexes:
- labelname: ifIndex
type: gauge
- name: ifType
oid: 1.3.6.1.2.1.2.2.1.3
type: gauge
help: The type of interface - 1.3.6.1.2.1.2.2.1.3
indexes:
- labelname: ifIndex
type: gauge
- name: ifMtu
oid: 1.3.6.1.2.1.2.2.1.4
type: gauge
help: The size of the largest packet which can be sent/received on the interface,
specified in octets - 1.3.6.1.2.1.2.2.1.4
indexes:
- labelname: ifIndex
type: gauge
- name: ifSpeed
oid: 1.3.6.1.2.1.2.2.1.5
type: gauge
help: An estimate of the interface's current bandwidth in bits per second - 1.3.6.1.2.1.2.2.1.5
indexes:
- labelname: ifIndex
type: gauge
- name: ifPhysAddress
oid: 1.3.6.1.2.1.2.2.1.6
type: PhysAddress48
help: The interface's address at its protocol sub-layer - 1.3.6.1.2.1.2.2.1.6
indexes:
- labelname: ifIndex
type: gauge
- name: ifAdminStatus
oid: 1.3.6.1.2.1.2.2.1.7
type: gauge
help: The desired state of the interface - 1.3.6.1.2.1.2.2.1.7
indexes:
- labelname: ifIndex
type: gauge
- name: ifOperStatus
oid: 1.3.6.1.2.1.2.2.1.8
type: gauge
help: The current operational state of the interface - 1.3.6.1.2.1.2.2.1.8
indexes:
- labelname: ifIndex
type: gauge
# 以下略
これは、オフィシャルにあるサンプルからの抜粋です。
インターフェースの情報を取得するためのものの一部です。
設定自体はSNMP Exporterに付属のgeneratorで作られています。
ただ、バイナリ配布されているものには現在generatorは付属していません。
ソースコードからビルドする必要があります。
generatorがNet-SNMPに依存しており、現状はDynamic Linkでバイナリが作成されるようになっているためこのような状態です。
issueにあがっておりいずれ同梱されるようになるかもしれません。
generatorの利用
generatorのビルド
前述の通り、generator を利用するためには、ビルドする必要があります。
Net-SNMPのライブラリと、includeファイルを入手しておき、
(yum install net-snmp-devel
, apt install libsnmp-base libsnmp-devel
など)
golangをインストールし、
go get github.com/prometheus/snmp_exporter
でsnmp_exporterのソースコードを入手し、
cd $GOPATH/src/github.com/prometheus/snmp_exporter/generator
go build
とビルドすることで、generatorのバイナリが作成されます。
あとは generator.ymlを見ながら記載していくだけです。
上記で上げたsnmp設定のサンプルはgeneratorでは
modules:
if_mib:
walk: [sysUpTime, interfaces, ifXTable]
のわずか3行です。
わかりやすく、管理し易いと思いますので、基本的には、generatorでの設定ファイル生成をおすすめします。
generatorの設定ファイルではOID情報がありませんが、これはすべてMIBファイルから持ってきています。
ですので、設定したい機器のSNMP-MIBファイルを別途入手しておく必要があります。
generatorのREADMEの下の方に主なMIBファイルの入手先と、設置の仕方が書いてありますので参考にすると良いでしょう。
generatorの設定(オフィシャルページからの抜粋と解説)
generatorの設定は、 generator.yml に記載します。
設定はモジュール単位で行います。
module:
<module1>:
module1の設定
<module2>:
module2の設定
<module3>:
module3の設定
のような構成です。
各モジュールは
<modulename>:
walk:
snmpwalkするもの
version: 2 # snmp v1,2,3 を設定するもの
max_repetitions: 25 #SNMP BULK Requestするときの最大値
retries: 3 # リトライ回数
timeout: 10s # タイムアウト時間
auth:
認証情報
lookups:
Indexを他のものに置き換えるための情報
overrides:
metric情報を書き換えるための情報
から構成されています。
<modulename>
には好きな名称を使いましょう。prometheusで設定するmodule名です。収集する際にも記録されます。
SNMP Exporterの設定にあった、metricsの記載がありませんが、これはwalk:
から自動的に生成されます。
(ので、大きな範囲をwalk:
に書くと、結構な量が設定されてしまいます)
あまりに量が多いと、機器によっては、タイムアウトしてしまうので注意しましょう。
上記if_mib設定をとある機器に利用したところ、60秒待っても帰ってこないという事がありました。
lookups
lookups ですが、 Indexをわかりやすいものに書き換えるためのものです。
lookups:
- old_index: ifIndex
new_index: ifName
- old_index: someIndex
new_index: someDescr
のように、元のIndexと新しいIndexを並べます。
注意点として、 置き換え後のIndexがユニークである必要があります。
サンプルには、 mib_ifDescr や mib_ifNameなど、ifIndexを他のものに書き換える設定が例として記載されていますが、
ifDescrなどは、ユニークである保証がありません、機器によっては、これを使うと情報が取れなくなりますので気をつけましょう。
その手の情報が欲しければ、prometheusには優秀なクエリがありますので、そちらで合成すると良いでしょう。
ifInOctets * on(ifIndex) group_left(ifName) ifName
とか
ifInOctets * on(ifIndex) group_left(ifName) ifName * on(ifIndex) group_left(ifDescr) ifDescr
のようなクエリにて、ifNameやついでにifDescrを紐付けられます。
ただし、これもやりすぎるとクエリ応答が遅くなるので程々に。
私の環境で
rate(ifHCInOctets[5m]) * 8
rate(ifHCInOctets[5m]) * 8 * on(instance,ifIndex) group_left(ifName) ifName * on(instance,ifIndex) group_left(ifDescr) ifDescr
の2つで試してみたところ、 前者で1500msくらいで帰ってきていたものがifNameとifDescrをつけた後者では2900ms前後の時間がかかるようになりました。
クエリに関しては16日に出て来るクエリ道場で覚えましょう
こうなるともう、 prometheusのルールを利用して収集時に追加したほうが良いと思います。
overrides
overridesは、SNMPで取得した情報を書き換えて保存するためのものです。
例えば、SNMPで値を取得すると、文字列で "OK" "NG" "UNKNOWN"などが返ってくる場合、メトリクスとして扱えないので、OK=1 NG=2 UNKNOWN=3などとして、数値に置き換えることでメトリクスとして扱えるようにしようという場合などに利用できます。
利用する際には正規表現が使えます
overrides:
<MetricName>:
regex_extracts:
<SubName>:
- regex: 'OK'
value: '1'
- regex: 'NG'
value: '2'
- regex: 'UNKNOWN'
value: '3'
- regex: '(.*)'
value: '0'
のように、それぞれ割り当てることができます。これで監視できるようになりますね。
<MetricName>
が元の名称、<SubName>
が新しくつける名称です。
この場合、<MetricName><SubName>
という名称(元の名前に自分でつけた名前が連結されたもの)がデータにつけられます。
なお、この時、もとの<MetricName>
というデータはSNMP Exporter上には現れなくなります。
snmp.ymlの作成
generator.ymlができあがったら、
あとは generator.yml のあるディレクトリで、
/path/to/generator generate
を実行すればsnmp.ymlファイルが作成されます。 snmp_exporterからこのファイルを指定して動かし、動作テストをしてみましょう。
実際に作成してみたgenerator.yml
検証等を行う中で作成したgenerator.yml からの抜粋です
yamaha:
auth:
community: public
walk:
- sysName
- yrhCpuUtil1min
- yrhInboxTemperature
- yrhMemoryUtil
- yrhFanModuleStatus
- yrhFanModuleIndex
if_name:
auth:
community: public
walk:
- sysUpTime
- ifAdminStatus
- ifOperStatus
- ifInErrors
- ifOutErrors
- ifInDiscards
- ifOutDiscards
- ifOutQLen
- ifDescr
- ifName
- ifAlias
- ifHCInOctets
- ifHCOutOctets
- ifHCInUcastPkts
- ifHCInBroadcastPkts
- ifHCInMulticastPkts
- ifHCOutUcastPkts
- ifHCOutBroadcastPkts
- ifHCOutMulticastPkts
lookups:
- old_index: ifIndex
new_index: ifName
paloalto:
auth:
community: public
walk:
- entPhysicalDescr
- entPhySensorValue
- entPhySensorOperStatus
- hrProcessorLoad
- hrDeviceDescr
- hrStorageDescr
- hrStorageUsed
- hrStorageSize
- panSessionActive
- panSessionActiveICMP
- panSessionActiveTcp
- panSessionActiveUdp
- panSessionUtilization
- panSysHAPeerState
- panSysHAState
- sysName
overrides:
panSysHAPeerState:
regex_extracts:
Status:
- regex: '.*active.*'
value: '1'
- regex: '.*passive.*'
value: '2'
- regex: '.*'
value: '0'
panSysHAState:
regex_extracts:
Status:
- regex: '.*active.*'
value: '1'
- regex: '.*passive.*'
value: '2'
- regex: '.*'
value: '0'
終わりに
SNMP Exporterの基本的な使い方の解説で終わってしまいました。
他のSNMPを利用したメトリック収集ツールからPrometheusに移行したい!というときの参考にでもなれば幸いです。
PS. 間違っているところなどのご指摘、歓迎します。