PrometheusでService Discoveryを行う

## 背景
 Prometheusで監視対象を追加する場合、Prometheusのserviceを一度停止して、監視対象を追加することが手間だった。何か方法がないかと調べた時に、file-basedのService Discoveryが可能とわかり、以下に今回試した方法をまとめています。
### Service Discoveryとは
さくらインターネットさんの技術ブログでわかりやすい説明があるので、以下の説明を引用しています。
https://knowledge.sakura.ad.jp/20489/
> サービスメッシュが生まれた背景の1つとして、多くのクラウドやコンテナクラスタ環境においては、実行するサービスに割り当てられるIPアドレスを事前に知ることができないという制約の存在がある。そのため、何らかの方法を使ってサービスの稼働後にほかのサービスにアクセスするためのIPアドレスを知る必要がある（これは「サービスディスカバリ」などと呼ばれる）


### file-basedのService Discoveryとは
Prometheusの公式ドキュメントには、以下の説明が記載されています。
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#file_sd_config
> File-based service discovery provides a more generic way to configure static targets and serves as an interface to plug in custom service discovery mechanisms.

原文を翻訳すると、file-basedのService Discoveryは、静的なtargetsとservicesを、カスタム可能なService Discoveryのメカニズムを拡張するためのインターフェースを設定するより一般的な方法を提供します。

## 環境
今回使う各サービスのバージョンとファイル構成は以下となります。

```
# 各バージョン
Prometheus: 2.23.0
node-exporter: 1.0.1
docker-compose: 2.2

# ファイル構成
docker-compose.yaml
prometheus
-- prometheus.yaml
-- service_discovery.yaml
```
また下図のように、`node-exporter2`を追加したい場合に、`service_dicovery.yaml`に追加するだけで監視対象が増やせるようにします。
![Screen Shot 2021-01-03 at 3.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/8a02ef65-be10-2c1b-3984-9c0b1268b0fd.png)

## 構築
以下のdocker-compose環境を使って、Prometheusとnode-exporterのコンテナを構成します。後でService Discoveryを確認するために、`node-exporter1`と`node-exporter2`を準備しておきます。また`docker network create --subnet=172.19.0.0/19 prom_net`でdocker networkも構築しておきます。

``` docker-compose.yaml
version: '2.2'
services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes: 
       - ./prometheus:/etc/prometheus       
    command: "--config.file=/etc/prometheus/prometheus.yaml"
    ports: 
      - 9090:9090      
    restart: "no"
    networks: 
      prom_net:
        ipv4_address: 172.19.0.2
  node_exporter1:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter1  
    ports:
      - 9100:9100
    networks: 
      prom_net:
        ipv4_address: 172.19.0.3
  node_exporter2:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter2   
    ports:
      - 9100:9100
    networks: 
      prom_net:
        ipv4_address: 172.19.0.4
```
Prometheusの設定ファイルは以下になります。`file_sd_configs`配下にService Discoveryとして使う設定ファイルを`service_dicovery.yaml`と定義します。

``` prometheus.yaml
global:
  scrape_interval:     15s 
  evaluation_interval: 15s 

scrape_configs:        
  - job_name: 'node-exporter'
    file_sd_configs:
      - files:
        - service_discovery.yaml
```

以下が、先ほど定義した`service_dicovery.yaml`の内容となります。今回は`node-exporter1`だけをtargetとします。

``` service_discovery.yaml
- targets:
  - 172.19.0.3:9100
  labels:
    subsystem: "node-exporter1"
```

## 結果
docker-composeを起動して、Prometheusとnode exporterのコンテナを起動します。下図の通り、`node-exporter1`はきちんと表示されています。
![Screen Shot 2021-01-03 at 2.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/703d87fb-6e37-f5bd-478c-700cf421e437.png)
![Screen Shot 2021-01-03 at 2.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/88d84f46-108d-ecf1-600c-71c7ce10623a.png)
次に、`service_dicovery.yaml`に`node-exporter2`を新たに追加して、表示されるか確認します。

``` service_discovery.yaml
- targets:
  - 172.19.0.3:9100
  labels:
    subsystem: "node-exporter1"
# 新規で追加
- targets: 
  - 172.19.0.4:9100
  labels:
    subsystem: "node-exporter2"
```
下図の通り、`node-exporter1``node-exporter2`共にきちんと表示されています。
![Screen Shot 2021-01-03 at 3.02.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/b67ba706-fabc-0d4e-ad9b-ce2b4888507f.png)
![Screen Shot 2021-01-03 at 3.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/b4fd8a10-3c2c-a54a-7cdb-8c1b2d7d20e7.png)

## 所感
`service_discovery.yaml`を更新するだけで、Prometheusを稼働させたまま、監視対象を追加することができました。file-basedのService Discovery以外にもConsulを使った方法もあるので、時間あるときに試してみたいと思います。

## 参考文献
https://qiita.com/nekoneck/items/aefdbb9d2a1bb1f03513