Dial-Out方式のTelemetryデータを収集する(gRPC)

過去に UDP での Dial-Out方式の Telemetryデータを収集しましたが、今回 gRPC でのTelemetryのコレクターを設定した際のメモ

前回UDPのDial-Outで確認したときの記事

https://qiita.com/k-maki/items/67fd31818deceabb67be

# Telemetryとは
ざっくり
- トラフィックや機器状態など情報を出力するネットワーク監視のための技術
- 従来のSNMPと比較して「柔軟性が高い」「リアルタイム性が高い」などのメリットがある
- 接続方式・メッセージ形式・通信形式が複数種類ある
    - 接続方式：Dial-In / Dial-Out
    - メッセージ形式：GPB、JSON など
    - 通信形式：UDP、gRPC など
    
今回は、Juniper の Dial-Out( gRPC ) で確認しました

# 利用したソフト

なかなか gRPC の Dial-Out に対応したコレクターのソフトが見つからず今回は以下の構成で対応しました
- `pmtelemetryd` : gRPC の Telemetry を受信して JSON形式ファイルに出力
    - `pmacct`のツール群の中のストリーミングテレメトリーコレクターが`pmtelemetryd`
    - `pmtelemetryd`そのままだと gRPC の Telemetry を受信ができないため、`mdt-dialout-collector`の gRPC dial-out libraries 入れて利用
        - https://github.com/network-analytics/mdt-dialout-collector/blob/main/doc/integration-with-pmtelemetryd.md
- `telegraf` : `pmtelemetryd`で受信したテレメトリーデータの保存ファイルを tail して内容の編集と`Prometheus`に取り込めるメトリクスにする
- `Prometheus` & `Grafana` : メトリクスの収集(`Prometheus`)と可視化(`Grafana`)

`mdt-dialout-collector`については、Juniper 以外に Cisco や Huawei にも対応しています。`mdt-dialout-collector`単体でも動作させることはできますが、出力が Kafka に対応していましたが、ファイル出力に対応していなかったので、今回は`mdt-dialout-collector`のライブリを利用した`pmtelemetryd`を利用しました

以下のサイトにも`mdt-dialout-collector`の説明があります(英語です)

https://blog.apnic.net/2022/10/17/multivendor-async-grpc-dial-out-collector/

全体のイメージは以下になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043279/04ec98c4-ff64-4204-be8f-c65b1ad15591.png)


# 各ソフトの構築方法
今回、dockerですべて動作させてみました、GitHubにdocker composeのファイル一式保存したので以下で利用できます。

```
git clone --depth=1 https://github.com/katsumi2018/grpc-dialout-collector-compose.git
cd grpc-dialout-collector-compose

docker compose up --build
```

初めの bulid は`pmtelemetryd`の構築が結構かかります自分の環境で15分くらいでした、2回目以降の実行は `docker compose up` で起動します


# 動作確認
## 構成
Ubuntu 24.04.1 LTS で構築しました
(ネットワークシュミレータ上に作りました)

以下のようにサーバ以外に Telemetry を送信するネットトワーク機器として vJunosEvolved をつなげてます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043279/7e44c7a6-1b74-4bde-a4f6-34c9dd56baf0.png)


vJunosEvolvedのコンフィグは以下ととしてます
- Telemetryサーバのアドレスは 10.99.0.1 、宛先ポート番号は 20000
- 30 秒周期で送信
- gRPCで送信
- 送信する内容は、IFの送受信データ量の `in-octets` `out-octets`
- rootのパスワードは仮で root123 にしてます


```: Junos-EVOコンフィグ
set version 23.4R2-S2.1-EVO
set system root-authentication encrypted-password "$6$MmGV7bPW$AuqgoIhnFiZQD9eLmmhS.Fwywh63knLvg96p9VLQXP5jSxMk3QXSBFph4Z3W1Hcvf34xdlIh0QRlHrh/j8rr5/"
set system syslog file interactive-commands interactive-commands any
set system syslog file messages any notice
set system syslog file messages authorization info
set services analytics streaming-server TELEMETRY_SERVER remote-address 10.99.0.1
set services analytics streaming-server TELEMETRY_SERVER remote-port 20000
set services analytics export-profile TELEMETRY_PROFILE local-address 10.99.0.2
set services analytics export-profile TELEMETRY_PROFILE reporting-rate 30
set services analytics export-profile TELEMETRY_PROFILE format json-gnmi
set services analytics export-profile TELEMETRY_PROFILE transport grpc
set services analytics sensor TELEMETRY_SENSOR_IF_IN_OCTETS server-name TELEMETRY_SERVER
set services analytics sensor TELEMETRY_SENSOR_IF_IN_OCTETS export-name TELEMETRY_PROFILE
set services analytics sensor TELEMETRY_SENSOR_IF_IN_OCTETS resource /interfaces/interface/state/counters/in-octets
set services analytics sensor TELEMETRY_SENSOR_IF_OUT_OCTETS server-name TELEMETRY_SERVER
set services analytics sensor TELEMETRY_SENSOR_IF_OUT_OCTETS export-name TELEMETRY_PROFILE
set services analytics sensor TELEMETRY_SENSOR_IF_OUT_OCTETS resource /interfaces/interface/state/counters/out-octets
set interfaces et-0/0/0 unit 0 family inet address 10.99.0.2/24
set interfaces et-0/0/9 unit 0 family inet address 1.1.1.1/24
```

## 確認結果(Prometheus)
ブラウザで、`http://<サーバーのIP>:9090/`にアクセスして Query で Telemetry データが取得できていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043279/48fa61be-95b6-432a-94b6-a701a6209fc3.png)

## 確認結果(Grafana)
ブラウザで、`http://<サーバーのIP>:3000/`にアクセスして、ユーザ名/パスワード`admin`でログインして Grafana の設定を行うことで以下のようなグラフにすることを確認できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043279/3b794ea9-8341-4d28-ada4-5e452fa9be1a.png)
詳細は省略しますが、「Prometheusと連携」と「ダッシュボードの作成」の作成は以下を参考にしてください

https://qiita.com/k-maki/items/21ee627c2ecbf0f9360c#grafana%E4%B8%8A%E3%81%A7%E3%81%AE%E8%A8%AD%E5%AE%9A

Grafanaの「Prometheusと連携」についてはDocker間を跨いだやり取りとなるため
`http://loacalhost:9090`ではなく`http://prometheus:9090`とする必要があります


# (参考)Telemetry環境を変更する場合
今回は、Juniper の Telemetry データをポート番号:20000 で`in-octets` `out-octets` を取得できるように設定していますが、内容を変える場合は各種設定ファイルの変更が必要なため参考にメモしておきます

## Telemetryの受信ポートを変える場合
Telemetryで待ち受けるポート版後を変える場合は以下の2つを変更する必要があります
- `pmtelemetryd/pmtelemetryd-grpc-dialout.conf`
    - `ipv4_socket_juniper = "0.0.0.0:20000";`を修正、ポート番号 21000 にしたい場合は
`ipv4_socket_juniper = "0.0.0.0:21000";`に変更
    - [GitHubに保存している pmtelemetryd-grpc-dialout.conf](https://github.com/katsumi2018/grpc-dialout-collector-compose/blob/main/pmtelemetryd/pmtelemetryd-grpc-dialout.conf)
- `docker-compose.yml`
    - `pmtelemetryd`の中の`ports`部分のポート番号を変更
    - [GitHubに保存している docker-compose.yml](https://github.com/katsumi2018/grpc-dialout-collector-compose/blob/main/docker-compose.yml)

## 取得する Telemetry の内容を変えたい場合
`in-octets` `out-octets` 以外を取得したい場合は、`telegraf.conf`の中身を修正する必要があります。もとのデータを見ながら`[[inputs.tail.json_v2.field]]`や`[[inputs.tail.json_v2.tag]]`を修正することになると思います。
`field`がメトリクスとして取得したい数値(今回は`in-octets`など)、メトリクスの`tag`が付加情報(IF番号など)になります
[GitHubに保存している telegraf.conf](https://github.com/katsumi2018/grpc-dialout-collector-compose/blob/main/telegraf/telegraf.conf)


```: 修正前のデータ /path/to/spool/telemetry-data.txt
{"event_type": "log", "seq": 69, "timestamp": "2025-XX-XX XX:XX:XX.630787", "telemetry_node": "10.99.0.2", "telemetry_port": 58164, "telemetry_data": {"/in-octets": "7481230", "extension": "{\"systemId\":\"re0\",\"sensorName\":\"sensor_1000\",\"subscribedPath\":\"/interfaces/interface/state/counters/in-octets/\",\"streamedPath\":\"/interfaces/interface/state/counters/in-octets/\",\"component\":\"evo-aftmand-bt\",\"sequenceNumber\":\"10\",\"payloadGetTimestamp\":\"XXXXXXXXXXXXX\",\"streamCreationTimestamp\":\"XXXXXXXXXXXXX\",\"exportTimestamp\":\"1743912313287\"}", "notification_timestamp": XXXXXXXXXXXXX, "sensor_path": [{"name": "interfaces"}, {"filters": {"name": "et-0/0/9"}, "name": "interface"}, {"name": "state"}, {"name": "counters"}], "system_id": "re0"}, "serialization": "json"}
{"event_type": "log", "seq": 70, "timestamp": "2025-XX-XX XX:XX:XX.632300", "telemetry_node": "10.99.0.2", "telemetry_port": 58164, "telemetry_data": {"/out-octets": "1390242", "extension": "{\"systemId\":\"re0\",\"sensorName\":\"sensor_1001\",\"subscribedPath\":\"/interfaces/interface/state/counters/out-octets/\",\"streamedPath\":\"/interfaces/interface/state/counters/out-octets/\",\"component\":\"evo-aftmand-bt\",\"sequenceNumber\":\"9\",\"payloadGetTimestamp\":\"XXXXXXXXXXXXX\",\"streamCreationTimestamp\":\"XXXXXXXXXXXXX\",\"exportTimestamp\":\"1743912313291\"}", "notification_timestamp": XXXXXXXXXXXXX, "sensor_path": [{"name": "interfaces"}, {"filters": {"name": "et-0/0/0"}, "name": "interface"}, {"name": "state"}, {"name": "counters"}], "system_id": "re0"}, "serialization": "json"}
```

```: Telegrafで修正後のデータ /var/log/telegraf/metrics.json
{"fields":{"in_octets":7481230},"name":"telemetrys","tags":{"host":"telegraf","host_ip":"10.99.0.2","if_name":"et-0/0/9","path":"/path/to/spool/telemetry-data.txt"},"timestamp":XXXXXXXXXX}
{"fields":{"out_octets":1390242},"name":"telemetrys","tags":{"host":"telegraf","host_ip":"10.99.0.2","if_name":"et-0/0/0","path":"/path/to/spool/telemetry-data.txt"},"timestamp":XXXXXXXXXX}
```


## Juniper 以外の Cisco / Huawai の機器で取得する場合

`pmtelemetryd-grpc-dialout.conf`の`#ipv4_socket_cisco = "0.0.0.0:20001";`
`#ipv4_socket_huawei = "0.0.0.0:20002";`をコメントアウトの部分を削除
また、受信したJSONの形式の内容が変わる可能性があるので、`telegraf/telegraf.conf`
の`[[inputs.tail]]`や`[[inputs.tail.json_v2]]`の内容を変えて Promtheus に連携できる形に変更する必要があります
[GitHubに保存している pmtelemetryd-grpc-dialout.conf](https://github.com/katsumi2018/grpc-dialout-collector-compose/blob/main/pmtelemetryd/pmtelemetryd-grpc-dialout.conf)


# 最後に

今回、いろいろ Telemetry のコレクターを探してる中で、Dial-In に対応した Telemetry コレクターは多くありましたが Dial-Out はなかなか見つかりませんでした。(20205/04/06時点)
今回も Cisco / Juniper / Huawai しか対応していないです。

参考に、自分が見つけた Dial-Out 対応の Telemetry コレクターソフトをメモしておきます

▼ gNMIc (Nokiaに対応)

https://gnmic.openconfig.net/cmd/listen/


▼ Telegrafの Cisco Model-Driven Telemetry (MDT) Input Plugin (Ciscoに対応)

https://github.com/influxdata/telegraf/blob/master/plugins/inputs/cisco_telemetry_mdt/README.md