PrometheusとGrafanaで監視環境を作ったら自分のアホさに今更気づいた話

はじめまして！
普段は自分のためだけに地震系のアプリやらなんやらを作っている変な人です。

# 背景
最近、ふと「システムちゃんと動いてるか監視したいなぁ（唐突）」と思い立ち、PrometheusとGrafanaを使って監視環境を作ることに挑戦してみました。
ですが、これが意外と大変でした…。今回はその奮闘記を少し共有しつつ、これから挑戦する人に少しでも参考になれば嬉しいです！
（誤字脱字や知識不足なところがあれば、やんわり教えていただけると助かります…！）

# 使ったツールや環境
- OS: **Ubuntu 24.04**
- VPN: **Tailscale（プライベートで構築したかったため）**
- 監視ツール: 
  - **Prometheus**（データ収集・監視）
  - **Grafana**（データの可視化）
  - **Node Exporter**（CPU、メモリ、ディスク情報の収集）

- 監視したいサーバー達:
  - 実機 3台
  - クラウド 2台

# 構築の流れ

- TailScaleのセットアップ
- Prometheusのセットアップ
- Grafanaのセットアップ
    - ダッシュボードの作成

## Tailscaleのセットアップ
**別にやらなくてもいいけど**、圧倒的に便利なので、Tailscaleでプライベートネットワークを構築する。
（外出先からsshを楽にしたいなどの理由で元から構築済み）

### 全てのサーバーにTailscaleをインストール & 起動
よほどのことがない限り多分コマンドは変わらない…はず…
``` bash
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
```

## Prometheusのセットアップ
各サーバーのデータを収集などをする中心となるツールのセットアップをする。

### Prometheusをインストール
```bash
# 1) 最新のバージョンを取得してダウンロード
VERSION=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep '"tag_name"' | sed -E 's/.*"v([^"]+)".*/\1/')
wget https://github.com/prometheus/prometheus/releases/download/v${VERSION}/prometheus-${VERSION}.linux-amd64.tar.gz

# 2) 解凍してバイナリ類を移動
tar -xvzf prometheus-${VERSION}.linux-amd64.tar.gz

# prometheus, promtool を /usr/local/bin/ に移動（バイナリはここにまとめる）
sudo mv prometheus-${VERSION}.linux-amd64/prometheus /usr/local/bin/
sudo mv prometheus-${VERSION}.linux-amd64/promtool /usr/local/bin/

# コンソール用のフォルダは /usr/local/prometheus/ に移動してあげる
sudo mkdir -p /usr/local/prometheus
sudo mv prometheus-${VERSION}.linux-amd64/consoles /usr/local/prometheus
sudo mv prometheus-${VERSION}.linux-amd64/console_libraries /usr/local/prometheus

# データディレクトリを作っておく
sudo mkdir -p /usr/local/prometheus/data

# 使い終わったら不要なフォルダ消す
rm -rf prometheus-${VERSION}.linux-amd64*
```

### `prometheus.service`の作成

```bash
sudo nano /etc/systemd/system/prometheus.service
```
```ini:prometheus.service
[Unit]
Description=Prometheus Monitoring
Wants=network-online.target
After=network-online.target

[Service]
User=ubuntu
ExecStart=/usr/local/bin/prometheus \
  --config.file=/usr/local/prometheus/prometheus.yml \
  --storage.tsdb.path=/usr/local/prometheus/data \
  --web.listen-address=0.0.0.0:9090
Restart=always

[Install]
WantedBy=multi-user.target
```
こんな感じに記入する

### Prometheusの設定ファイルを編集
```bash
sudo tailscale status
```
を実行してサーバーのアドレスを調べる。
```bash
000.000.000.000   statusserver        user linux   -
000.000.000.000   server1             user linux   active; direct 0.0.0.0:00000, tx 00000000 rx 000000000
000.000.000.000   server2             user linux   active; direct 0.0.0.0:00000, tx 00000000 rx 000000000
```
今回は`server1`と`server2`を監視する

Prometheusの設定ファイルを開く
```bash
sudo nano /usr/local/prometheus/prometheus.yml
```
```yml:prometheus.yml
scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090", "server1:9100", "000.000.000.000:9100"]
```
`targets`に**Tailscale**の各サーバーアドレスを入れる。（PC名でも行けるのでそっちの方をおすすめします！）ポートは`9100`でOK!

### Prometheusを起動
```bash
sudo systemctl daemon-reload
sudo systemctl enable prometheus
sudo systemctl start prometheus
```

`<サーバーのIP>:9090`にアクセスし、Prometheusが動作しているか確認。
（クライアントにもTailscaleを入れていると、今回の場合は`statusserver:9090`でもアクセスできるのでおすすめです！）

## Grafanaのセットアップ
### 1. Grafanaのインストール
今回は安定版リリースとOSS版を使用
```bash
sudo apt-get install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install grafana
```
### 2. Grafanaの起動と初期設定
```bash
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
```
`<サーバーIP>:3000`にアクセスするとこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/2a34560a-d3c4-0c1a-55d2-d167131dd246.png)

ユーザー名とパスワードを求められるので
- ユーザー名: `admin`
- パスワード: `admin`（初回ログイン後に変更を求められます）

### Prometheusをデータソースとして追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/4a314ea0-76f0-6b70-8c3e-b91c55c8fc3b.png)
サイドバーから`Connections` → `Data sources`にある`Add new data source`で新規追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/10f4a714-9e64-6c19-846f-3f713849acf1.png)
`Prometheus`を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/58b950d5-fd7e-ff4f-6aea-8d75e84cff57.png)
`Connection`項目のURLを`http://localhost:9090`
`Save & test`で追加完了

**一旦Grafanaの初期設定は終了**

---
## 各サーバーにNodeExporterのインストール
### 監視対象サーバーにてインストールをする
```bash
# 1) 最新のバージョンを取得してダウンロード
VERSION=$(curl -s https://api.github.com/repos/prometheus/node_exporter/releases/latest | grep '"tag_name"' | sed -E 's/.*"v([^"]+)".*/\1/')
wget https://github.com/prometheus/node_exporter/releases/download/v${VERSION}/node_exporter-${VERSION}.linux-amd64.tar.gz

# 2) 解凍してバイナリを /usr/local/bin/ に移動
tar -xvzf node_exporter-${VERSION}.linux-amd64.tar.gz
sudo mv node_exporter-${VERSION}.linux-amd64/node_exporter /usr/local/bin/

# 3) 後始末
rm -rf node_exporter-${VERSION}.linux-amd64*
```

### `node_exporter.service`を作成
```bash
sudo nano /etc/systemd/system/node_exporter.service
```

```ini:node_exporter.service
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=always

[Install]
WantedBy=multi-user.target
```
こんな感じに記入する（本日2回目）

そしてNode Exporterを起動する！
```bash
sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter
```

## Grafanaにてダッシュボードの作成
もちろん最初からダッシュボードを作るなんて~~面倒なんで~~やりません！（なまけものですすんません）
どっかの神様が作成した完成品を~~パクり~~お借りしましょう！

やり方は超簡単！

サイドバーから`Dashboards`を選択し`New`から`Import`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/9e8e5962-d6ab-2922-c757-604057b09213.png)

今回は動作確認済みの`1860`([Node Exporter Full](https://grafana.com/grafana/dashboards/1860-node-exporter-full/))をインポートする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/8afc0c60-6fec-686d-86af-7f3a4192f208.png)

先ほど追加したデータソースを選択しインポートする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/556d7ffb-95f6-ea1b-ffc3-c17af0aac0eb.png)

こうなれば成功！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974433/e3caf66b-0e9e-032a-d347-55e49ad5cabb.png)

**お疲れ様でした！**

# 私がやってつまずいた場所
## Node Exporterのエラー（`status=217/USER`）
### 問題
Prometheusの`Status` → `Targets`を確認したら、エンドポイントが`down`になっていました。
`sudo systemctl status node_exporter`で確認するとNode Exporterが正しく起動していないことが判明。

どうやらNode Exporterが専用ユーザーで起動できず失敗したようなので`node_exporter`ユーザーを作成して実行ファイルの権限を設定してあげる。
```bash
sudo useradd -r -s /bin/false node_exporter
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
sudo systemctl daemon-reload
sudo systemctl restart node_exporter
```
`sudo systemctl status node_exporter`でrunningが確認できれば成功！
この手順で私は問題を解決しました！

# 私のアホすぎるエピソード
実はですね...最初は「Node Exporterを外部公開しても大丈夫でしょ！」って謎の自信で、Nginxを使ってリバースプロキシでポートを外部に向けようとしてたんですよ。

今考えれば、セキュリティ的に**アウトオブアウト**だし、効率的にも最悪。「何してんねん！？」って感じです。

**作業してる途中**で「あれ！？これTailscale使えば秒で解決じゃん！えぇー！バカじゃーん！」って気づいた瞬間の虚無感、今でも忘れられません…。

監視環境を作ってセキュリティ的にもなんか少し学べた気がしますし圧倒的にやってよかったと思っています！
（これから気をつけます........）

# まとめ
構築するのは割と引っかかったりして大変でしたけど、完成したシステムには大満足しています！何と言っても*ｶｯｸｲｰ*んですねこれが！ついでにサーバーも監視できて更に安心感が増しました！

最後に、初めての投稿で色々と教えてくださった@Bacalhauさんに感謝します！サポートありがとうございました！