1台の物理マシンでPrometheusやらGrafanaやらを建てる(Docker使用)

「1台の物理マシンだけで、かつDockerコンテナを使用してPrometheusなどの監視環境を整える。」
みたいな記事が無かったのでメモ。

## 前書き

- 全部Dockerコンテナで動かします
- 1台の物理マシンだけで完結するように構成しています
    - 監視に際してこの構成を奨励するものではありません
- 今回は各ソフトウェアを立ち上げるのがメインなのです
    - 「Prometheusとは」とか「監視とは」とか「正しいアラートとは」とかは書いてないのであしからず

## 今回のゴール

1. 以下の図の通りに構成を完了する
2. GrafanaのData SourcesにPrometheusを指定する

構成のイメージ図↓
![prometheus_goal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474496/3feba32f-ff9a-a72c-08e6-42fcfe93543d.png)

### 軽く説明
- ノートPCの図：あなたが操作するマシン
- `prom-network`：Dockerで生成するネットワーク。ノートPC内に存在していると考えてください
- `:9090`とか：ソフトウェアが使用するポート番号
- 盾みたいなアイコン：アラートマネージャ(多分公式のロゴではない)

## 構築手順
### Dockerイメージを取得する
```
$ docker pull prom/alertmanager
$ docker pull prom/node-exporter
$ docker pull prom/prometheus
$ docker pull grafana/grafana
```

今回はこの4つを建てます。

### Dockerのネットワークを作成する
参考：https://knowledge.sakura.ad.jp/16082/

```
$ docker network create prom-network
```
これだけでおkです。`prom-network`の部分は好きな名前をつけても問題ありません。
ネットワークが作成されたかどうかは以下のコマンドで確認できます。

```
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6bd30c077705        bridge              bridge              local
9bc0dad85516        host                host                local
7a2d5aa36f0b        none                null                local
1c7e57c599f6        prom-network        bridge              local  <- いま作ったやつ
```

### Prometheus用の設定ファイルを用意する
```yml:/tmp/prometheus.yml
global:
  scrape_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
      - targets: ['alertmanager:9093']
rule_files:
  - rules.yml

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']
```
#### tips
- `prometheus.yml`は`docker`コマンドを使うユーザが編集できる場所に配置してください
    - (`docker run`時に、権限の問題でエラーになる可能性があるため)
- `targets:`で定義されている`alertmanager`や`node-exporter`の部分を変更した場合、以降の操作では適宜読みかえて下さい
    - `docker run`のときにコンテナにつける名前と合致する必要があります


### 各コンテナを起動する
#### Prometheusの起動

```
$ docker run --rm -d -p 9090:9090 --net prom-network -v /tmp/prometheus.yml:/prometheus/prometheus.yml --name prometheus prom/prometheus --config.file=/prometheus/prometheus.yml
```

ちょっと複雑なので部分的に解説。

- `--net prom-network`：コンテナを指定したネットワークに参加させます
- `-v /tmp/prometheus.yml:/prometheus/prometheus.yml`：さっき作った`prometheus.yml`をPrometheusのコンテナにマウントします
- `--name prometheus`：コンテナにprometheusという名前をつけます(重要)
- `--config.file=/prometheus/prometheus.yml`：コンテナにマウントされた設定ファイルを使用してPrometheusを起動します

#### Node Exporterの起動
```
$ docker run --rm -d -p 9100:9100 --net prom-network --name node-exporter prom/node-exporter
```

#### AlertManagerの起動
```
$ docker run --rm -d -p 9093:9093 --net prom-network --name alertmanager prom/alertmanager
```

#### Grafanaの起動
```
$ docker run --rm -d -p 3000:3000 --net prom-network --name grafana grafana/grafana
```

### GrafanaのData Sourcesを設定する
とりあえずwebブラウザで`localhost:3000`でGrafanaにアクセスしましょう。
admin/adminでログインできます。
![grafana_login.png]
(https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474496/06380fc6-5682-2f00-7b91-04a7003f7036.png)

ログインしたら左側の歯車アイコンからAdd data sourceでデータソース追加画面に移ります。
ここでHTTPセクションのURLを以下のように入力し、ページの一番下にある「Save & Test」を押下します。
緑のポップアップ通知が出ればPrometheusからデータを正しく受信する設定が整っています。
![grafana_datasource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474496/46f35912-1665-a313-f3e1-09fa07df318f.png)

#### tips

- ここでURLを`http://prometheus:9090`と指定したのは、PrometheusのDockerコンテナ名が`prometheus`だからです
   - `docker run`時に別のコンテナ名にした場合はココを変更する必要があります



Prometheusでnodeメトリクスを確認するところまでは書きません。


## 補足
Dockerのネットワーク詳細は以下のコマンドで確認できます。

```
$ docker network inspect prom-network
```
各コンテナをネットワークに参加させた状態で実行すると以下のような結果が得られるはずです。

```
[
    {
        "Name": "prom-network",
...中略
        "Containers": {
            "5786ef7a1c41bd01bd5528d01634105e5c7c6580b33a18711834bce449d1f91c": {
                "Name": "grafana",
                "EndpointID": "826a0ae110b09f1b1cc5ea3e55bfcfea54d32e75deb19f170b9e3c78571364e2",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "754eaf3ff20da12a4937edeba5c914464423102d78441679130afd15c540e767": {
                "Name": "prometheus",
                "EndpointID": "6d77c55693db68989e87f1ed72561a26576130a32ae3be49463d1bafce0f2fe8",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "fc035a73e5a01352f82e9d698662b1058d6b1b0ea9ca4cd8b38a21ca31115e3e": {
                "Name": "node-exporter",
                "EndpointID": "cb989db9d71a435aaf920be0c2f17f4015d2b30a24639d46c955b865e6eececc",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "fc5f4fadc352e6039f165c7bd141cb4787e2236d200c4259edb87b75b065143b": {
                "Name": "alertmanager",
                "EndpointID": "82578bf4a51996640ef61404eab6944eb637b28f9adbaae4ffe798eb7ce62849",
                "MacAddress": "02:42:ac:12:00:05",
                "IPv4Address": "172.18.0.5/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
```

ユーザ定義のDockerネットワーク(bridge)において、各コンテナは`"Name"`で指定されている値をDNSとして使用することで通信を行うことができる、というわけです。