Prometheusでさくらのクラウドを監視する

## この記事は？

この記事は、[さくらインターネット アドベントカレンダー](https://qiita.com/advent-calendar/2019/sakura)の11日目の記事です。
大遅刻しました( ˘ω˘)

ここでは、私が愛するプロダクトの一つであるPrometheusを使って、さくらのクラウドのリソースを監視する方法をご紹介します。

## Prometheusってなに？おいしいの？

**美味しいです。**

Prometheusは、端的に言えば次世代の監視プロダクトです。CNCFのプロジェクトの一つで、成熟したプロジェクトにとして認められた 'Graduate Project'の一つです。
特にPrometheusは、Kubernetesやクラウドなどのような **Cloud Native**な環境に最適化されており、世界中で多くの利用事例があります。

詳しいことは省きますが、ぜひこちらを見てください。

https://speakerdeck.com/takumanakagame/introduction-prometheus-ja

## Prometheusでさくらのクラウドを監視するってどういうこと？

さくらのクラウドでは、以下のようにサーバの詳細画面からいくつかのリソースの使用率を見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/c71a02a5-21d1-a729-6802-ba18b45319b5.png)

しかし、残念ながら分での細かい値や、これ以外のメトリクスを見ることはできません。
通常、こういった場合はサーバ側に監視用のエージェントを導入して細かい情報を収集することがほとんどです。

しかし、実はさくらのクラウドでは、各種APIを提供しており、その中に様々なメトリクス情報も提供しています。
このAPIを経由して、Prometheusからさくらのクラウドのリソースの情報を収集しようというのが、今回の目的です。

## sakuracloud exporter
APIのままでは、Prometheusから参照することはできません。
こういったとき、Prometheusでは**Exporter**と呼ばれる、いわゆる監視エージェントを使って情報を収集します。
Exporterを使うことで、Prometheusは様々なリソースから情報を収集することができます。

そして、そのExporterの一つに**sakuracloud exporter**があります。
これは、 @yamamoto-febc  氏によって主にContiributeされており、さくらのクラウドのAPIを使って各種メトリクスをPrometheusから参照可能にするExporterです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/093f3d2a-5dcc-2b10-03e9-4542a6e4084c.png)


https://github.com/sacloud/sakuracloud_exporter

これを使うことで、さくらのクラウド上のサーバや、DBアプライアンス、スイッチ、ルーターなど、多くのリソースのメトリクスを収集することができます。

## ここに加工済みのdocker-compose.ymlがあります
早速、sakuracloud exporterを使ってみましょう。
簡単に環境構築できるように、気づいたらリポジトリが生えていたので、これを使います。

https://github.com/TakumaNakagame/monitoring-prometheus-sakruacloud

README.mdにも書いてありますが、リポジトリをCloneしてTokenとSecretを渡して、`docker-compose up -d`すればPrometheusとsakuracloud expoterが立ち上がってきます。

これについて、解説していきましょう。

## とりあえず動かす
### APIキーの設定
リポジトリをCloneしたら、1つだけ手を加える必要があります。
それは、さくらのクラウドのAPIへアクセスするためのトークンとシークレットです。

- `--token` / `SAKURACLOUD_ACCESS_TOKEN`
- `--secret` / `SAKURACLOUD_ACCESS_TOKEN_SECRET`

これは、https://secure.sakura.ad.jp/cloud/#!/apikey/top/ から作成・参照することが可能です。
リポジトリにはダミーのTOKEN/SECRETが書いてあるので、同じように`docker-compose.yml`に書いてあげればOKです。

```
- --token=acea7a90-106f-4553-8b09-d710473e6de5
- --secret=9clOJhNWTzLOZdCvmNvMXnhgJ82SzU89qUOVp1UBo0eMSI9yGrdLFwj18LhtZE3M
```

トークンとシークレットを変更したら、早速起動してみましょう。

### コンテナを起動
`docker-compose.yml`と同じディレクトリで以下のコマンドを叩きます。

```
> ls
conf  README.md  docker-compose.yml
> docker-compose up -d
Creating network "monitoring-prometheus-sakruacloud_default" with the default driver
Creating prometheus ... done
Creating exporter   ... done
```

次のように各コンテナが立ち上がっていればOKです。

```
> docker-compose ps
Name                 Command               State           Ports
----------------------------------------------------------------------------
exporter     /usr/bin/sakuracloud_expor ...   Up      0.0.0.0:9542->9542/tcp
prometheus   /bin/prometheus --config.f ...   Up      0.0.0.0:9090->9090/tcp
```

なお、もしも`State`が`Exit`となっていた場合はログを確認してみましょう。
以下の例では、APIの認証が失敗したため、起動できていません。別のAPIキーを与えるなどしてみましょう。

```
> docker-compose ps
Name                 Command               State            Ports
-----------------------------------------------------------------------------
exporter     /usr/bin/sakuracloud_expor ...   Exit 2
prometheus   /bin/prometheus --config.f ...   Up       0.0.0.0:9090->9090/tcp

> docker-compose logs exporter
Attaching to exporter
exporter      | level=info ts=2019-12-12T09:40:22.621147868Z caller=main.go:52 msg="starting sakuracloud_exporter" rate-limit=5 version=0.8.0 revision=289c46a goVersion=go1.12.9
exporter      | 2019/12/12 09:40:22 [TRACE] AuthStatusAPI.Read start
exporter      | 2019/12/12 09:40:22 [TRACE]     args: {}
exporter      | 2019/12/12 09:40:22 [TRACE]     results: {"AuthStatus":null,"Error":{}}
exporter      | 2019/12/12 09:40:22 [TRACE] AuthStatusAPI.Read end
exporter      | panic: unauthorized: invalid API key is applied
exporter      |
exporter      | goroutine 1 [running]:
exporter      | main.main()
exporter      |         /go/src/github.com/sacloud/sakuracloud_exporter/main.go:62 +0x1c67
```

さて、無事起動が確認できたらPrometheusを確認してみましょう。
一緒に起動したPrometheusではすでにsakuracloud expoterのScrape設定を行っているため、すぐにメトリクスを参照することができます。

### Prometheusへ接続

例えばローカルで起動した場合は http://localhost:9090/targets へアクセスしましょう。
以下のようにScrapeしているターゲット一覧が出てくるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/7ab118c3-9e36-67c5-79fa-42ce9a046b90.png)

### PromQLを叩いてみる
起動したら、早速PromQLを叩いて値を参照してみましょう。
Graphページで、次のように入力してみましょう。`sakuracloud_`から始まるメトリクスが参照できると思います。

```
sakuracloud
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/ddedcd71-5191-3ed8-73d6-f5a64862b52e.png)

例えば、サーバの一覧を出す場合は `sakuracloud_server_info` を使用してみましょう。
以下のようにサーバの一覧が取得できます。
※一部ホスト名等を非表示にしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/961ff01a-171d-acb1-6179-59183cc640e9.png)


他にも、`sakuracloud_server_up`でサーバのUp/Downを取得できます。
また、さくらのクラウドにはサーバ以外に多くのコンポーネントが存在しています。それらの情報を取得することもできます。
例えば、DBアプライアンスの情報は`sakuracloud_database_info`などで取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/645bfe50-6fda-8357-8467-b89b1b8c4206.png)

その他のメトリクスについてはGitHubのREADMEを参照ください。

https://github.com/sacloud/sakuracloud_exporter#user-content-metrics

## sakuracloud expoter活用
さくらのクラウドの各種メトリクスを簡単に取得できるsakuracloud expoterですが、実はそのままでは活用しきれないことがあります。
ここでは、sakuracloud expoterを利用する上でのチューニングや活用方法をご紹介します。

### `scrape_timeout`を変更する
sakuracloud expoterは、APIを叩いてサーバの情報を取得するため、その性質上大量高速にメトリクスを収集することは苦手です。
そのため、そのままではPrometheusのフォルトのScrapeTimeoutである10sを超えてしまい、Scrape Failedとなってしまいます。
そこで、Prometheus側の`scrape_timeout`を変更することで、Failedしないようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182057/452f7680-3326-fd83-b57f-4882c62625b9.png)

今回使用しているPrometheusの設定は、60秒に変更しています。

```
global:
  scrape_interval: 60s
  scrape_timeout: 60s
  evaluation_interval: 15s
```

なお、`scrape_timeout`を設定する場合は、`scrape_interval`以下の値にする必要があります。
`scrape_interval`に30sを指定した場合、`scrape_timeout`は30s以下でなければなりません。

そのため、`scrape_timeout`を60sにしたい場合は、`scrape_interval`が60s以上にしなければなりません。
上記の場合は、`global`に記載しているため、すべてのScrape設定に適用されます。
しかし、Targetによってはもっと高頻度で取得したいということもあるでしょう。そういった場合は、`scrape_configs`のjobごとに個別で指定することができます。指定がなければ`global`の値を参照します。

例えば次ように設定すると、`job: sakuracloud_exporter`のみ60sごとにScrapeされ、他のScrapeには影響しません。

```
scrape_configs:
- job_name: sakuracloud_expoter
  scrape_timeout: 60s
  scrape_interval: 60s
```

### fakeモードを利用する
sakuracloud expoterでは、例えばさくらのクラウドのメンテナンス情報などを取得し、対象のサーバかどうかチェックすることも可能です。
しかし、こういった機能のテストはユーザ側でハンドリングすることはできず、運良くメンテナンス対象になった場合にテストするか、きっとうまくいっているだろうと祈ることしかできません。

しかし、sakuracloud expoterには、**fakeモード**というものが存在し、擬似的に環境を再現することができます。
fakeモードを活用することで、わざわざサーバを構築しなくともテストができ、更には上記のような再現の難しい状況を作り上げることができます。

fakeモードについては、メンテナーである @yamamoto-febc さんのブログでご紹介されているので、ここでは詳細は割愛します。

[sakuracloud_exporter v0.7.0 − コレクターごとの無効化/fakeモードの追加 など - febc技術メモ](https://febc-yamamoto.hatenablog.jp/entry/2019/08/06/120844)

fakeモードを利用するには、対象の環境を定義したjsonを用意する必要があります。
今回は、公式のリポジトリに存在するjsonファイルを使用します。

https://github.com/sacloud/sakuracloud_exporter/blob/master/examples/fake/generate-fake-store-json/example-fake-store.json

fakeモードを有効にすると、ログのアカウント名がjsonに指定した名前になっています。

```
exporter      | level=info ts=2019-12-16T09:05:34.630893542Z caller=main.go:52 msg="starting sakuracloud_exporter" rate-limit=5 version=0.8.0 revision=289c46a goVersion=go1.12.9
exporter      | 2019/12/16 09:05:34 file watch start: "/etc/sakuracloud_exporter/fake-store.json"
exporter      | 2019/12/16 09:05:34 [TRACE] AuthStatusAPI.Read start
exporter      | 2019/12/16 09:05:34 [TRACE]     args: {}
exporter      | 2019/12/16 09:05:34 [TRACE]     results: {"AuthStatus":{"AccountID":123456789012,"AccountName":"fakeアカウント","AccountCode":"fake","AccountClass":"member","MemberCode":"fake-member","MemberClass":"member","AuthClass":"account","AuthMethod":"apikey","IsAPIKey":true,"ExternalPermission":"bill+eventlog+cdn","OperationPenalty":"none","Permission":"create"},"Error":null}
exporter      | 2019/12/16 09:05:34 [TRACE] AuthStatusAPI.Read end
exporter      | level=info ts=2019-12-16T09:05:34.638831833Z caller=main.go:134 msg=listening addr=:9542
```

あとは通常通りのsakuracloud_exporterと同様に使えます。

### その他
他にも、一部のコンポーネントのスクレイプを意図的にさせない `--no-collector.`という引数があり、任意のコンポーネントを指定することで対象の情報の取得を行いません。
こうすることで、不要なコンポーネントの収集をやめ、より効率的にメトリクスを収集することができます。

これらは、GitHubの[README.meに記載](https://github.com/sacloud/sakuracloud_exporter#user-content-flags)されているので、一度確認してみましょう。

## 終わりに
ということで、sakuracloud expoterのご紹介をさせていただきました！
Node Exporterなどを導入できないデータベースアプライアンスやネットワーク系のコンポーネントなどの情報取得や、サーバ側にエージェントレスでメトリクスを収集できるなど、大きなメリットを持ちます。
ただし、API経由であるため、Node Exporterなどに比べて高頻度高速に収集することは苦手なため、環境に併せて取捨選択するのが良いでしょう。