Catalyst9300でPrometeus ExporterをDockerコンテナとして動かす


# はじめに

Catalyst9300のIOS XE 16.12.1からDockerコンテナがネイティブサポートされたので、Prometeus ExporterをDockerコンテナとして動かします。

Catalyst9300でのネイティブDockerコンテナサポートについては以下のドキュメントを参照ください。

**[Qiita] Catalyst9300のDockerアプリケーションホスティングを試してみる**
https://qiita.com/tetsusat/items/ec11ddb70197b24175e8

**[Cisco公式] Programmability Configuration Guide: Application Hosting**
https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/1612/b_1612_programmability_cg/application_hosting.html

# 実現方法

設定が複雑になりがちなSNMP Exporterではなく、Telegrafを使ってTelemetryデータとして入力した情報をPrometeus Exporter形式の情報として出力します。こうすることで、ルータから出力したいメトリクス情報ががどのようなものであったとしても一つの設定で対応できます。

## Telegrafとは

Telegrafは、さまざまな入力からメトリックを収集し、さまざまな出力に送信するためのプラグイン駆動型のサーバーエージェントです。データの入力と出力の両方に対してプラグイン駆動であるため、簡単に拡張できます。 Goで記述されており、外部の依存関係のない単一のバイナリにコンパイルされ、必要となるメモリフットプリントは最小限で済みます。

**[InfluxData公式] Telegraf**
https://www.influxdata.com/time-series-platform/telegraf/

## cisco_telemetry_mdtプラグイン

`cisco_telemetry_mdt`はTelegraf Inputプラグインで、Cisco IOS XR、IOS XE、およびNX-OSプラットフォームからのTelemetryデータを収集します。

**[Github] cisco_telemetry_mdt**
https://github.com/influxdata/telegraf/tree/master/plugins/inputs/cisco_telemetry_mdt

## prometheus_clientプラグイン

`prometheus_client`はTelegraf Outputプラグインで、Telegrafで収集したメトリクデータをPrometheusサーバのためにExportします。

**[Github] prometheus_client**
https://github.com/influxdata/telegraf/tree/master/plugins/outputs/prometheus_client

# 準備

まずは、通常のLinuxサーバでやってみます。Dockerイメージには、InfluxData社がメンテナンスするDocker公式イメージを利用します。

* https://hub.docker.com/_/telegraf

Dockerイメージをプルします。

```console
$ docker pull telegraf:1.12.4-alpine
```

Telegrafの設定ファイルの雛形を作ります。

```console
$ docker run --rm telegraf:1.12.4-alpine \
      telegraf -sample-config \
      --input-filter cisco_telemetry_mdt \
      --output-filter prometheus_client > telegraf.conf
```

`outputs.prometheus_client`のセクションの`collectors_exclude`の行をコメントを外します。

```toml:telegraf.conf
...
# Configuration for the Prometheus client to spawn
[[outputs.prometheus_client]]
  ## Address to listen on
  listen = ":9273"

  ## Use HTTP Basic Authentication.
  # basic_username = "Foo"
  # basic_password = "Bar"

  ## If set, the IP Ranges which are allowed to access metrics.
  ##   ex: ip_range = ["192.168.0.0/24", "192.168.1.0/30"]
  # ip_range = []

  ## Path to publish the metrics on.
  # path = "/metrics"

  ## Expiration interval for each metric. 0 == no expiration
  # expiration_interval = "60s"

  ## Collectors to enable, valid entries are "gocollector" and "process".
  ## If unset, both are enabled.
  collectors_exclude = ["gocollector", "process"]
...
```

起動します。

```
$ docker run -d --name=telegraf \
      -p 57000:57000 \
      -p 9273:9273 \
      -v $PWD/telegraf.conf:/etc/telegraf/telegraf.conf:ro \
      telegraf:1.12.4-alpine
```

ちゃんと起動できていることを確認します。

```console
$ docker logs -f telegraf
2019-11-11T12:15:52Z I! Starting Telegraf 1.12.4
2019-11-11T12:15:52Z I! Using config file: /etc/telegraf/telegraf.conf
2019-11-11T12:15:52Z I! Loaded inputs: cisco_telemetry_mdt
2019-11-11T12:15:52Z I! Loaded aggregators:
2019-11-11T12:15:52Z I! Loaded processors:
2019-11-11T12:15:52Z I! Loaded outputs: prometheus_client
2019-11-11T12:15:52Z I! Tags enabled: host=2cd9e20e70b1
2019-11-11T12:15:52Z I! [agent] Config: Interval:10s, Quiet:false, Hostname:"2cd9e20e70b1", Flush Interval:10s
```

# Catalystアプリケーションホスティング

通常のLinuxサーバで実行したときのように、Telegrafの設定ファイルをDockerコンテナを起動するタイミングでCatalyst上のFlash等から渡せるといいのですが、その方法が見当たらなかったので、Telegrafの設定ファイルをDockerイメージに直接埋め込みます。前述のとおり、Telemetryデータにかかわらず、Telegrafの設定ファイルは一パターンで済むので、これでよしとしましょう。ドンマイ俺:sweat_smile:

まずは、Dockerイメージをビルドするため、Linux環境で作業します。

カレントディレクトリに以下のようなDockerfileを作成します。

```Dockerfile:Dockerfile
FROM telegraf:1.12.4-alpine
COPY telegraf.conf /etc/telegraf/telegraf.conf
```

Dockerイメージをビルドします。

```console
$ docker build -t telegraf_prom .
```

ビルドしたDockerイメージをTar形式で出力します。

```console
$ docker save telegraf_prom -o telegraf.tar
```

何らかの方法でTar形式のDockerイメージをCatalystのFlashへコピーします。

ここからはCatalyst上で作業します。

アプリケーションホスティングの設定をします。

```
app-hosting appid telegraf
 app-vnic management guest-interface 0
  guest-ipaddress 192.0.2.101 netmask 255.255.255.0
 app-default-gateway 192.0.2.254 guest-interface 0
 app-resource docker
  run-opts 1 "-p 57000:57000"
  run-opts 2 "-p 9273:9273"
 app-resource profile custom
  cpu 7400
  memory 2048
```

先ほど作ったDokcerイメージをアプリケーションホスティングにインストールします。

```
Switch#app-hosting install appid telegraf package flash:telegraf.tar
```

アプリケーションホスティングを有効化します。

```
Switch#app-hosting activate appid telegraf
```

アプリケーションホスティングを起動します。

```
Switch#app-hosting start appid telegraf
```

CatalystでTelemetryの設定をします。

```
telemetry ietf subscription 1
 encoding encode-kvgpb
 filter xpath /process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/five-seconds
 source-vrf Mgmt-vrf
 stream yang-push
 update-policy periodic 1000
 receiver ip address 192.0.2.101 57000 protocol grpc-tcp
!
netconf-yang
```

ブラウザから`http://192.0.2.101:9273/metrics`へアクセスすると以下のようにPrometeusサーバへエクスポートできているはずです。ちなみに、`source`で見えるのはTelemetryの送信元となっているCatalystの管理インターフェイスのIPアドレスです。

```
$ curl 192.0.2.101:9273/metrics
# HELP Cisco_IOS_XE_process_cpu_oper:cpu_usage_cpu_utilization_five_seconds Telegraf collected metric
# TYPE Cisco_IOS_XE_process_cpu_oper:cpu_usage_cpu_utilization_five_seconds untyped
Cisco_IOS_XE_process_cpu_oper:cpu_usage_cpu_utilization_five_seconds{host="772599aa3993",source="192.0.2.1",subscription="1"} 3
```

おしまい