prometheusでSNMP監視をする

## ファイル構成
```
.
├── docker-compose.yml
├── prometheus
│   └── prometheus.yml
└── snmp-exporter
    ├── generator.yml
    ├── mibs
    │   ├── ACCOUNTING-CONTROL-MIB.my
    │   （省略）
    │   └── XGCP-MIB.my
    └── snmp.yml
```

## docker-compose.yml
```docker-compose.yml
version: '3'
services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - '9090:9090'

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    hostname: grafana
    ports:
      - 3000:3000
    user: "$PID:$GID"
    volumes:
      - ./grafana:/var/lib/grafana

  snmp-expoter:
    image: prom/snmp-exporter
    container_name: snmp-exporter
    ports:
      - '9116:9116'
    volumes:
      - './snmp-exporter/snmp.yml:/etc/snmp_exporter/snmp.yml'
```

## SNMP用のファイル生成
筆者の環境がubuntuなのでMIBファイルをダウンロードする
```
apt -y update
apt -y install snmp snmp-mibs-downloader
download-mibs
```

ここから、欲しいMIBのOIDを参照する
https://qiita.com/Mabuchin/items/d435c0afb4f0ca17ad25

ホスト情報系MIB(SNMPv2-MIB)
| OID | MIB | 説明 |
|:-:|:-:|:-:|
|1.3.6.1.2.1.1.5.0|sysName|機器のホスト名|
|1.3.6.1.2.1.1.1.0|sysDescr|機器に関する説明(機種情報やOSバージョン等)|
|1.3.6.1.2.1.1.6.0|sysLocation|snmp locationで登録されている文字列|

Interface系MIB(IF-MIB)
| OID | MIB | 説明 |
|:-:|:-:|:-:|
|1.3.6.1.2.1.2.1.0|ifNumber|機器に存在するInterfaceの数(Loopback等の論理も含む)|
|1.3.6.1.2.1.2.2.1.1|ifIndex|InterfaceのifIndexの番号(snmpwalkで一覧確認)|
|1.3.6.1.2.1.2.2.1.2.(ifIndex)|ifDescr|インタフェース名(Eth0/0等)|
|1.3.6.1.2.1.31.1.1.1.18.(ifIndex)|ififAlias|インタフェースのDescription|
|1.3.6.1.2.1.2.2.1.7.(ifIndex)|ifAdminStatus|論理的なインタフェースの状態(1:up 2:down)|
|1.3.6.1.2.1.2.2.1.8.(ifIndex)|ifOperStatus|物理的なインタフェースの状態(1:up 2:down)|
|1.3.6.1.2.1.2.2.1.4.(ifIndex)|ifMtu|インタフェースのMTU値|
|1.3.6.1.2.1.2.2.1.5.(ifIndex)|ifSpeed|インタフェースの帯域(~~bps)|
|1.3.6.1.2.1.31.1.1.1.15.(ifIndex)|ifHighSpeed|インタフェースの帯域(~~Mbps)|
|1.3.6.1.2.1.2.2.1.10.(ifIndex)|ifInOctets|インタフェースで受信したパケットの総バイト数(32bitカウンタ)|
|1.3.6.1.2.1.2.2.1.16.(ifIndex)|ifOutOctets|インタフェースで送信したパケットの総バイト数(32bitカウンタ)|
|1.3.6.1.2.1.31.1.1.1.6.(ifIndex)|ifHCInOctets|インタフェースで受信したパケットの総バイト数(64bitカウンタ こちらを推奨)|
|1.3.6.1.2.1.31.1.1.1.10.(ifIndex)|ifHCOutOctets|インタフェースで送信したパケットの総バイト数(64bitカウンタ こちらを推奨)|
|1.3.6.1.2.1.31.1.1.1.7.(ifIndex)|ifHCInUcastPkts|インタフェースで受信したUnicastパケットの総数|
|1.3.6.1.2.1.31.1.1.1.11.(ifIndex)|ifHCOutUcastPkts|インタフェースで送信したUnicastパケットの総数|
|1.3.6.1.2.1.31.1.1.1.8.(ifIndex)|ifHCInMulticastPkts|インタフェースで受信したMulticastパケットの総数|
|1.3.6.1.2.1.31.1.1.1.12.(ifIndex)|ifHCOutMulticastPkts|インタフェースで送信した総Unicastパケット数|
|1.3.6.1.2.1.31.1.1.1.9.(ifIndex)|ifHCInBroadcastPkts|インタフェースで受信したBroadcastパケットの総数|
|1.3.6.1.2.1.31.1.1.1.13.(ifIndex)|ifHCOutBroadcastPkts|インタフェースで送信したBroadcastパケットの総数|
|1.3.6.1.2.1.2.2.1.13.(ifIndex)|ifInDiscards|破棄した受信パケットの総数|
|1.3.6.1.2.1.2.2.1.19.(ifIndex)|ifOutDiscards|破棄した送信パケットの総数|
|1.3.6.1.2.1.2.2.1.14.(ifIndex)|ifInErrors|受信したパケットのエラー総数|
|1.3.6.1.2.1.2.2.1.20.(ifIndex)|ifOutErrors|送信したパケットのエラー総数|
|1.3.6.1.2.1.2.2.1.14.(ifIndex)|ifInUnknownProtos|受信したパケットのうちプロトコルが不明で破棄したパケット(送信は無し)|


通信系MIB(IP-MIB)

| OID | MIB | 説明 |
|:-:|:-:|:-:|
|1.3.6.1.2.1.4.3.0|ipInReceives|受信したパケットの総数|
|1.3.6.1.2.1.4.4.0|ipInHdrErrors|ヘッダのエラーにより破棄した受信パケットの総数|
|1.3.6.1.2.1.4.5.0|ipInAddrErrors|無効なIPアドレスで破棄した受信パケットの総数|
|1.3.6.1.2.1.4.12.0|ipOutNoRoutes|経路が存在しないため破棄した送信パケットの総数|
|1.3.6.1.2.1.4.8.0|ipInDiscards|破棄した受信パケットの総数|
|1.3.6.1.2.1.4.11.0|ipOutDiscards|破棄した送信パケットの総数|
|1.3.6.1.2.1.4.9.0|ipInDelivers|フォワードしたパケットの総数(32bitなのであまり信用できません)|
|1.3.6.1.2.1.4.14.0|ipReasmReqds|IP Fragmentによって分割された、連結する必要のあるパケット総数|
|1.3.6.1.2.1.4.15.0|ipReasmOKs|IP Fragmentから再構成に成功したパケットの総数|
|1.3.6.1.2.1.4.16.0|ipReasmFails|IP Fragmentから再構成に失敗したパケットの総数|
|1.3.6.1.2.1.4.19.0|ipFragCreates|機器自体がフラグメントを実施したパケットの総数|
|1.3.6.1.2.1.4.34.1.3.1.4.(IPv4Addr)|ipAddressIfIndex.ipv4|IPv4からIFindex値を算出|
|1.3.6.1.2.1.4.34.1.3.2.16.(IPv6Addr)|ipAddressIfIndex.ipv6|IPv6からIFindex値を算出|

generetor.ymlを作成する
```yml
modules:
  snmpnet_basic:                # モジュール名（任意）
    walk:                       # 取得するOIDリスト
      - ifNumber
      - ifDescr
      - ifOperStatus
      - ifSpeed
    version: 2
    max_repetitions: 60
    retries: 3
    timeout: 60s
    auth:
      community: communityname  # コミュニティ名

```
MIBSをコピーしてくる
```
cp /usr/share/snmp/mibs/ietf/* ./mibs
cp /usr/share/snmp/mibs/iana/* ./mibs
cp /usr/share/snmp/mibs/* ./mibs
```


以下を実行
```
$ docker run -it -v "${PWD}:/opt/" prom/snmp-generator generate
```

生成されたsnmp.yml
```snmp.yml
snmpnet_basic:
  walk:
  - 1.3.6.1.2.1.2.2.1.2
  - 1.3.6.1.2.1.2.2.1.5
  - 1.3.6.1.2.1.2.2.1.8
  get:
  - 1.3.6.1.2.1.2.1.0
  metrics:
  - 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: 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: 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: 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
    enum_values:
      1: up
      2: down
      3: testing
      4: unknown
      5: dormant
      6: notPresent
      7: lowerLayerDown
  version: 2
  max_repetitions: 60
  retries: 3
  timeout: 1m0s
  auth:
    community: communityname
```

## prometheus.ymlの作成
```./prometheus/prometheus.yml
global:
  scrape_interval: 15s # デフォルトの監視対象にpullする間隔
  external_labels: # 外部と通信するときのラベル
    monitor: 'codelab-monitor'

scrape_configs: # 監視対象ごとの設定
  - job_name: 'prometheus' # Prometheus自身の監視
    scrape_interval: 5s # デフォルトの間隔を上書き
    static_configs:
      - targets: ['prometheus:9090']


###### SNMP
  - job_name: 'cisco_ncs_snmp'
    static_configs:
      - targets: ['10.254.0.1']

    metrics_path: /snmp
    params:
      module: ['snmpnet_basic']　　　#先ほど設定したモジュール名
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: snmp-exporter:9116
```

## Grafanaの設定
![image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/2f1ede8c-a16d-87f7-747c-e83a04681672.png)




## 参考文献
- https://amemo.hatenablog.jp/entry/2018/07/20/212116
- https://qiita.com/Mabuchin/items/d435c0afb4f0ca17ad25
- https://hogem.hatenablog.com/entry/20100622/1277215889
- https://qiita.com/gzock/items/0794898cd3ed68350e9b
- https://techstep.hatenablog.com/entry/2019/01/13/190707
- https://amateur-engineer-blog.com/getting-started-prometheus/#toc5
- https://www.zabbix.com/documentation/6.0/jp/manual/config/items/itemtypes/snmp/mibs