PrometheusとGrafanaでホストとコンテナのリソースを可視化してみた
はじめに
複数のコンテナサービスのリソースを監視するため、以下のコンポーネントを利用してダッシュボードで表示します。コンテナを利用した監視系サービスを構築したことが無かったので、初学者向けに、ダッシュボードで可視化するまでのクイックスタートを本記事で紹介します。
| コンポーネント | 概要 |
|---|---|
| Prometheus | メトリクスを収集し、時系列データとして保存する監視基盤 |
| Node Exporter | ホスト(コンテナを稼働させているOS側)のメトリクスを取得・表示するエージェント |
| cAdvisor | Dockerコンテナ単位のリソース使用状況メトリクスを収集・表示するコンポーネント |
| Grafana | 収集されたメトリクスを可視化するためのダッシュボードUIツール |
想定読者
- Docker は触ったことがあるが、監視はこれからの初学者
- 「ホスト資源(CPU/メモリ/ディスク/ネットワーク)と各コンテナの使用状況を可視化したい」
- まずはメトリクス監視から始めたい
- 構成をファイル管理(IaC)したい
ゴール
-
docker-compose up -dだけで Prometheus / Node Exporter / cAdvisor / Grafana が起動 - ダッシュボードテンプレートを利用してダッシュボードを表示
- ホストのリソース & コンテナの状況がダッシュボードで確認
0. 動作環境
| 項目 | バージョン |
|---|---|
| OS | Ubuntu 22.04 LTS |
| Docker | 28.5.2 |
| Docker Compose | 3.9 |
| ネットワーク | 社内ネットワーク 外部へHTTP(S) 到達できること |
| プロキシ | HTTP/HTTPS を必ず経由 |
1. 全体構成
[ Host OS ]
├─ docker-compose.yml
├─ prometheus/
│ └─ prometheus.yml
├─ grafana/
│ ├─ provisioning/
│ │ ├─ datasources/
│ │ │ └─ prometheus.yml
│ │ └─ dashboards/
│ │ ├─ dashboards.yml
│ │ └─ <任意のダッシュボードテンプレート>.json
│ ├─ grafana.ini
│ └─ .env
└─ certs/ (プロキシ環境下など証明書対応が必要な場合)
↓ (Docker network内部通信)
+------------------------------+
| prometheus | node-exporter|
| cadvisor | grafana |
+------------------------------+
2. ファイル構成
以下のファイルを用意します。
docker-compose.yml
version: "3.9"
services:
prometheus:
image: prom/prometheus:v3.7.3 # imageのバージョンは最新を指定
container_name: prometheus
restart: unless-stopped
volumes:
# 設定ファイルをコンテナ内へ読み取り専用マウント
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
# 時系列データベースの永続化
- prometheus-data:/prometheus
command:
# 設定ファイルを指定
- '--config.file=/etc/prometheus/prometheus.yml'
# データの保持期間
- '--storage.tsdb.retention.time=15d'
- '--storage.tsdb.retention.size=10GB'
ports:
- "9090:9090"
networks:
- monitor
node-exporter:
image: prom/node-exporter:v1.10.2
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro # ホストファイルシステム情報
- /var/run:/var/run:ro # Docker ソケットや cgroup 関連
- /sys:/sys:ro # CPU/メモリなどシステム情報
- /var/lib/docker/:/var/lib/docker:ro # コンテナレイヤ情報
- /var/run/docker.sock:/var/run/docker.sock:ro
- /dev/kmsg:/dev/kmsg:ro
networks:
- monitor
grafana:
image: grafana/grafana:12.4.0-19363970803
container_name: grafana
restart: unless-stopped
env_file:
- grafana/.env
volumes:
# Dashboards/ユーザ設定永続化
- grafana-data:/var/lib/grafana
# DataSource / Dashboard 自動プロビジョニング
- ./grafana/provisioning:/etc/grafana/provisioning
# 設定ファイル
- ./grafana/grafana.ini:/etc/grafana/grafana.ini:ro
# TLS証明書 (必要な場合のみ)
- ./certs:/certs:ro
ports:
- "3000:3000"
networks:
- monitor
networks:
monitor:
driver: bridge
# 匿名ボリュームではなく名前付きでライフサイクルを管理しやすく
volumes:
prometheus-data:
grafana-data:
prometheus/prometheus.yml
Prometheusと何を連携させるかを記述します。今回はprometheus自身とnode-exporter、cadvisorを連携するので、それぞれをjob_name毎に定義していきます。URLはdocker-compose.ymlで定義したサービス名に対応します。
global:
# データをスクレイピングする間隔
scrape_interval: 15s
# メトリクスが古くなるまでの時間
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["prometheus:9090"]
- job_name: node-exporter
static_configs:
# 環境により異なる
- targets: ["localhost:9100"]
- job_name: cadvisor
static_configs:
- targets: ["cadvisor:8080"]
grafana/provisioning/datasources/prometheus.yml
Grafanaで利用するPrometheusのデータソースを設定します。Grafanaがどのデータベースから値を取得するかを定義しています。
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
grafana/provisioning/dashboards/dashboards.yml
Grafanaでダッシュボードをプロビジョニングする方法を設定します。
apiVersion: 1
providers:
- name: 'local-dashboards'
orgId: 1
folder: ''
type: file
disableDeletion: true
updateIntervalSeconds: 30
options:
path: /var/lib/grafana/dashboards
grafana/provisioning/dashboards/<任意の名前>.json
Grafanaで表示するダッシュボードを定義したJSONファイルです。Grafanaが公開しているダッシュボードテンプレートを利用します。
ダッシュボードはテンプレートは以下リンクから好きなものを選択して、JSONファイルをダウンロードします。
今回は以下を利用します。
- Node Exporter:
Node Exporter Full(ID:1860) - cAdbvisor:
Docker Container & Host Metrics(ID:10619)
jsonファイルから、${DS_PROMETHEUS}と記載の部分をgrafana/provisioning/datasources/prometheus.ymlで定義したnameに置換します。
今回だとPrometheusになります。
ダッシュボードテンプレートによっては、${DS_PROMETHEUS}以外の変数(例: ${xxx})もデータソース名に置換する必要がある場合があります。
<<長いので省略>>
ダッシュボードテンプレートによっては、k8sを利用する前提になっていることもあったので、出来る限り現在の環境に近いものを選択する必要があります。
grafana/grafana.ini
Grafanaのアプリケーション側の設定ファイルです。このファイルは無くてもいいですが、個別設定をファイル管理する場合は利用してください。
[session]
; ユーザーがログイン状態を維持できる最大期間
cookie_max_age = 12h
[log]
; Grafanaの内部ログ設定(デバッグ用)
; level = info
; filters = alerting:debug rendering:info
[users]
; ユーザーが削除された際のダッシュボードやアノテーションの削除設定
auto_assign_org_role = Viewer
default_theme = dark
allow_sign_up = false ; 外部ユーザーのサインアップを許可しない
grafana/.env
Grafanaにログインするときのユーザ・パスワードです。本番運用では絶対に利用しないでください。
docker-compose.ymlにべた書きはセキュリティ上良くないので、環境変数ファイルに記載します。
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin
3. 起動手順
git clone <この構成を含むリポジトリURL>
# docker-compose.ymlが配置されているディレクトリへ移動
cd <xxx>
# コンテナを起動
docker compose up -d
コンテナ確認
起動確認
docker ps
# prometheus / node-exporter / cadvisor / grafana がすべて Up
ログの確認
各コンテナのログでERRORやWARNINGが無いかを確認します。
docker compose logs <コンテナ名> --follow
通信タイムアウトや証明書関連のエラーが出ていれば、証明書を設定します。
私の場合は以下を行いました。
- grafanaとprometheusの通信でエラーのため、プロキシを経由させずに通信する
NO_PROXYにprometheusを追加しました。 - Grafanaからの通信で証明書のエラーのため、grafanaの公開鍵を
/etc/ssl/certsへマウントしました。
各UIにアクセス
各画面が表示されればセットアップ完了です。
各サービスを表示
- Prometheus: http://localhost:9090
- cAdvisor: http://localhost:8080
- Grafana: http://localhost:3000
Grafanaのダッシュボードを表示
データソース設定やダッシュボードテンプレートの修正漏れがある場合は、ダッシュボード表示時にエラーが表示されます。
No DataやN/Aはデータが無い(アクセス権限なし・メトリクス収集に必要なマウント設定をしていない等)可能性があるので、表示が出来ていないかの切り分けが必要になります。

Discussion