やったことのまとめ
- 自作Exporter,
Prometheus
,Alertmanager
,Grafana
をまとめてDocker Compose
で動かした nginx
コンテナを追加してリバースプロキシした
Prometheus
用のExporterを自作するときに動作確認の時点でGrafana
のグラフが見られたりAlertmanager
で通知されるメッセージとかが確認できるとメトリクスやラベルの設計がしやすい(気がする)ので,
それらが全部入りの環境をDocker Compose
で作ってみた.
version: '3.8' | |
services: | |
exporter: # 自作Exporter | |
build: ./ | |
container_name: exporter | |
prometheus: | |
image: prom/prometheus:v2.24.1 | |
container_name: prometheus | |
command: | |
[ | |
"--config.file=/etc/prometheus/prometheus.yml", | |
"--web.external-url=http://localhost/prometheus", | |
"--web.route-prefix=/", | |
] | |
volumes: | |
[ | |
"./deployment/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml", | |
"./deployment/prometheus/rules.yml:/etc/prometheus/rules.yml", | |
] | |
alertmanager: | |
image: prom/alertmanager:v0.21.0 | |
container_name: alertmanager | |
command: | |
[ | |
"--config.file=/etc/alertmanager/alertmanager.yml", | |
"--web.external-url=http://localhost/alertmanager", | |
"--web.route-prefix=/", | |
] | |
volumes: | |
[ | |
"./deployment/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml", | |
] | |
grafana: | |
image: grafana/grafana:7.3.7 | |
container_name: grafana | |
volumes: | |
[ | |
"./deployment/grafana/grafana.ini:/etc/grafana/grafana.ini", | |
"./deployment/grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml", | |
"./deployment/grafana/dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml", | |
"./deployment/grafana/dashboard.json:/var/lib/grafana/dashboards/dashboard.json", | |
] | |
nginx: | |
image: nginx:stable | |
container_name: nginx | |
volumes: | |
[ | |
"./deployment/nginx/default.conf:/etc/nginx/conf.d/default.conf", | |
"./deployment/nginx/index.html:/usr/share/nginx/html/index.html", | |
] | |
ports: | |
- 80:80 |
つかうもの
- macOS Mojave 10.14
- Docker Desktop for Mac
- Version 3.1.0
- Docker Engine Version 20.10.2
- docker-compose version 1.27.4
- Prometheus (Docker)
- version 2.24.1
- Alertmanager (Docker)
- version 0.21.0
- Grafana (Docker)
- version 7.3.7
- nginx (Docker)
- version 1.18.0
- 自作Exporter
- 2112番ポートで起動できて
Docker
コンテナ化できるものなら何でも良い
- 2112番ポートで起動できて
やったこと
とりあえず起動する
それぞれDocker image
が公式で提供されているのでそれをそのまま起動すれば良さそう.
自作Exporterの動作確認をしたときと同様に適当にdocker-compose.yml
を書いてみる.
version: '3.8' | |
services: | |
exporter: # 自作Exporter | |
build: ./ | |
container_name: exporter | |
ports: | |
- 2112:2112 | |
prometheus: | |
image: prom/prometheus:v2.24.1 | |
container_name: prometheus | |
volumes: | |
- ./deployment/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml | |
- ./deployment/prometheus/rules.yml:/etc/prometheus/rules.yml | |
ports: | |
- 9090:9090 | |
alertmanager: | |
image: prom/alertmanager:v0.21.0 | |
container_name: alertmanager | |
volumes: | |
- ./deployment/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml | |
ports: | |
- 9093:9093 | |
grafana: | |
image: grafana/grafana:7.3.7 | |
container_name: grafana | |
volumes: | |
- ./deployment/grafana/grafana.ini:/etc/grafana/grafana.ini | |
- ./deployment/grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml | |
- ./deployment/grafana/dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml | |
#- ./deployment/grafana/dashboard.json:/var/lib/grafana/dashboards/dashboard.json | |
ports: | |
- 3000:3000 |
重要なのは以下の設定ファイルをそれぞれのコンテナにマウントしていること.
Prometheus
- 自作Exporterなどをスクレイプするための設定(
prometheus.yml
)Docker Compose
で起動しているので他のコンテナについてはすべてコンテナ名で名前解決できる
- アラートルール(
rules.yml
)- 任意のルールで良い
- 自作Exporterなどをスクレイプするための設定(
Alertmanager
- アラート通知設定(
alertmanager.yml
)- 任意の設定で良い
- アラート通知設定(
Grafana
- 基本設定(
grafana.ini
)- ログイン不要の設定をしておく
- Data Source設定(
datasource.yaml
)Prometheus
コンテナを指定する
- Dashboard設定(
dashboard.yaml
,dashboard.json
)dashboard.json
は後から作っても良い
- 基本設定(
global: | |
scrape_interval: 10s | |
evaluation_interval: 10s | |
alerting: | |
alertmanagers: | |
- static_configs: | |
- targets: | |
- "alertmanager:9093" | |
rule_files: | |
- "rules.yml" | |
scrape_configs: | |
- job_name: "prometheus" | |
static_configs: | |
- targets: ["prometheus:9090"] | |
- job_name: "alertmanager" | |
static_configs: | |
- targets: ["alertmanager:9093"] | |
- job_name: "grafana" | |
static_configs: | |
- targets: ["grafana:3000"] | |
- job_name: "example-exporter" | |
static_configs: | |
- targets: ["exporter:2112"] |
(rules.yml
, alertmanager.yml
は何でも良いので前回のものを流用)
##################### Grafana Configuration Example ##################### | |
# | |
# Everything has defaults so you only need to uncomment things you want to | |
# change | |
# possible values : production, development | |
;app_mode = production | |
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty | |
;instance_name = ${HOSTNAME} | |
#################################### Anonymous Auth ###################### | |
[auth.anonymous] | |
# enable anonymous access | |
;enabled = false | |
enabled = true | |
# specify organization name that should be used for unauthenticated users | |
;org_name = Main Org. | |
# specify role for unauthenticated users | |
;org_role = Viewer | |
org_role = Editor | |
# mask the Grafana version number for unauthenticated users | |
;hide_version = false |
# config file version | |
apiVersion: 1 | |
# list of datasources that should be deleted from the database | |
deleteDatasources: | |
- name: Prometheus | |
orgId: 1 | |
# list of datasources to insert/update depending | |
# what's available in the database | |
datasources: | |
# <string, required> name of the datasource. Required | |
- name: Prometheus | |
# <string, required> datasource type. Required | |
type: prometheus | |
# <int> org id. will default to orgId 1 if not specified | |
orgId: 1 | |
# <string> url | |
url: prometheus:9090 |
apiVersion: 1 | |
providers: | |
# <string> an unique provider name. Required | |
- name: "Example" | |
# <string> name of the dashboard folder. | |
folder: "" | |
# <string> provider type. Default to 'file' | |
type: file | |
# <bool> disable dashboard deletion | |
disableDeletion: true | |
# <int> how often Grafana will scan for changed dashboards | |
updateIntervalSeconds: 10 | |
# <bool> allow updating provisioned dashboards from the UI | |
allowUiUpdates: false | |
options: | |
# <string, required> path to dashboard files on disk. Required when using the 'file' type | |
path: /var/lib/grafana/dashboards | |
# <bool> use folder names from filesystem to create folders in Grafana | |
foldersFromFilesStructure: true |
(dashboard.json
はあらかじめ作成済みのものがなければこの後作成する)
あとはこれらのファイルが以下のように配置されている状態でDocker Compose
でコンテナを立ち上げる.
# ローカルでビルドしない場合はDockerfileとGo関連のファイルは不要
$ tree .
.
├── Dockerfile
├── deployment
│ ├── alertmanager
│ │ └── alertmanager.yml
│ ├── grafana
│ │ ├── dashboard.json
│ │ ├── dashboard.yaml
│ │ ├── datasource.yaml
│ │ └── grafana.ini
│ └── prometheus
│ ├── prometheus.yml
│ └── rules.yml
├── docker-compose.yml
├── go.mod
├── go.sum
└── main.go
# コンテナを起動(コードを編集したなどの理由で再度ビルドしたい場合はさらに--buildを付与する)
$ docker-compose up -d --force-recreate
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
alertmanager /bin/alertmanager --config ... Up 0.0.0.0:9093->9093/tcp
exporter ./app Up 0.0.0.0:2112->2112/tcp
grafana /run.sh Up 0.0.0.0:3000->3000/tcp
prometheus /bin/prometheus --config.f ... Up 0.0.0.0:9090->9090/tcp
あとはそれぞれのエンドポイントで動作確認する.
- 自作Exporter
Prometheus
Alertmanager
Grafana
dashboard.json
が未作成の場合はここで動作確認も兼ねてGrafana
上でダッシュボード(自作Exporterのメトリクスがグラフ化できれば何でも良い)を作成し, Share
➔Export
➔Save to file
からJSON
をダウンロードして以降はそれを使うようにする.
設定が正しく効いていれば予めPrometheus
がData Source
として登録されていて, 全コンテナのメトリクスがスクレイプできていることも確認できる.
リバースプロキシする
このままでもいいんだけどせっかくなのでnginx
でリバースプロキシする.
docker-compose.yml
にnginx
コンテナを追加して, 以前やったときと同様の設定ファイルを作成してマウントする.
(リバースプロキシしているので, nginx
以外のそれぞれのコンテナのポートは閉じておく)
version: '3.8' | |
services: | |
exporter: # 自作Exporter | |
build: ./ | |
container_name: exporter | |
prometheus: | |
image: prom/prometheus:v2.24.1 | |
container_name: prometheus | |
command: | |
[ | |
"--config.file=/etc/prometheus/prometheus.yml", | |
"--web.external-url=http://localhost/prometheus", | |
"--web.route-prefix=/", | |
] | |
volumes: | |
[ | |
"./deployment/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml", | |
"./deployment/prometheus/rules.yml:/etc/prometheus/rules.yml", | |
] | |
alertmanager: | |
image: prom/alertmanager:v0.21.0 | |
container_name: alertmanager | |
command: | |
[ | |
"--config.file=/etc/alertmanager/alertmanager.yml", | |
"--web.external-url=http://localhost/alertmanager", | |
"--web.route-prefix=/", | |
] | |
volumes: | |
[ | |
"./deployment/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml", | |
] | |
grafana: | |
image: grafana/grafana:7.3.7 | |
container_name: grafana | |
volumes: | |
[ | |
"./deployment/grafana/grafana.ini:/etc/grafana/grafana.ini", | |
"./deployment/grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml", | |
"./deployment/grafana/dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml", | |
"./deployment/grafana/dashboard.json:/var/lib/grafana/dashboards/dashboard.json", | |
] | |
nginx: | |
image: nginx:stable | |
container_name: nginx | |
volumes: | |
[ | |
"./deployment/nginx/default.conf:/etc/nginx/conf.d/default.conf", | |
"./deployment/nginx/index.html:/usr/share/nginx/html/index.html", | |
] | |
ports: | |
- 80:80 |
Prometheus
prometheus.yml
,rules.yml
: そのまま- command(CMD)にリバースプロキシ用の設定1を追加
Alertmanager
alertmanager.yml
: そのまま- command(CMD)にリバースプロキシ用の設定を追加
Grafana
datasource.yaml
,dashboard.yaml
,dashboard.json
: そのままgrafana.ini
- リバースプロキシ用の設定2を追加
nginx
- リバースプロキシ設定(
default.conf
) - リンク用ページ(
index.html
)
- リバースプロキシ設定(
##################### Grafana Configuration Example ##################### | |
# | |
# Everything has defaults so you only need to uncomment things you want to | |
# change | |
# possible values : production, development | |
;app_mode = production | |
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty | |
;instance_name = ${HOSTNAME} | |
#################################### Server #################################### | |
[server] | |
# Protocol (http, https, h2, socket) | |
;protocol = http | |
# The ip address to bind to, empty will bind to all interfaces | |
;http_addr = | |
# The http port to use | |
;http_port = 3000 | |
# The public facing domain name used to access grafana from a browser | |
;domain = localhost | |
# Redirect to correct domain if host header does not match domain | |
# Prevents DNS rebinding attacks | |
;enforce_domain = false | |
# The full public facing url you use in browser, used for redirects and emails | |
# If you use reverse proxy and sub path specify full url (with sub path) | |
;root_url = %(protocol)s://%(domain)s:%(http_port)s/ | |
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/ | |
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. | |
;serve_from_sub_path = false | |
serve_from_sub_path = true | |
# Log web requests | |
;router_logging = false | |
# the path relative working path | |
;static_root_path = public | |
# enable gzip | |
;enable_gzip = false | |
# https certs & key file | |
;cert_file = | |
;cert_key = | |
# Unix socket path | |
;socket = | |
#################################### Anonymous Auth ###################### | |
[auth.anonymous] | |
# enable anonymous access | |
;enabled = false | |
enabled = true | |
# specify organization name that should be used for unauthenticated users | |
;org_name = Main Org. | |
# specify role for unauthenticated users | |
;org_role = Viewer | |
org_role = Editor | |
# mask the Grafana version number for unauthenticated users | |
;hide_version = false |
server { | |
listen 80; | |
location / { | |
root /usr/share/nginx/html; | |
index index.html; | |
} | |
location /exporter/ { | |
proxy_pass http://exporter:2112/; | |
} | |
location /prometheus/ { | |
proxy_pass http://prometheus:9090/; | |
} | |
location /alertmanager/ { | |
proxy_pass http://alertmanager:9093/; | |
} | |
location /grafana/ { | |
proxy_pass http://grafana:3000/; | |
} | |
} |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>nginx</title> | |
</head> | |
<body> | |
<header> | |
<div class="title"> | |
<h1>nginx</h1> | |
</div> | |
</header> | |
<div class="main"> | |
<ul class="link"> | |
<li><a href="/exporter/metrics">Exporter</a></li> | |
<li><a href="/prometheus">Prometheus</a></li> | |
<li><a href="/alertmanager">Alertmanager</a></li> | |
<li><a href="/grafana">Grafana</a></li> | |
</ul> | |
</div> | |
<footer></footer> | |
</body> | |
</html> |
再度コンテナを起動する.
$ tree .
.
├── Dockerfile
├── deployment
│ ├── alertmanager
│ │ └── alertmanager.yml
│ ├── grafana
│ │ ├── dashboard.json
│ │ ├── dashboard.yaml
│ │ ├── datasource.yaml
│ │ └── grafana.ini
│ ├── nginx
│ │ ├── default.conf
│ │ └── index.html
│ └── prometheus
│ ├── prometheus.yml
│ └── rules.yml
├── docker-compose.yml
├── go.mod
├── go.sum
└── main.go
$ docker-compose up -d --force-recreate
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------
alertmanager /bin/alertmanager --config ... Up 9093/tcp
exporter ./app Up
grafana /run.sh Up 3000/tcp
nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp
prometheus /bin/prometheus --config.f ... Up 9090/tcp
ここまでの設定に問題がなければそれぞれのパスでコンテナの動作確認ができる.
- 自作Exporter
Prometheus
Alertmanager
Grafana
もしくは, http://localhost/でリンクを張ったHTML
(index.html
)が表示できるのでそこから飛んでも良い.
最後に一応Alertmanager
の動作確認をする.
rules.ymlでInstanceDown
(upが0になるだけで発火)のアラートルールを設定しているので, 試しに自作Exporterのコンテナを落としてみる.
$ docker-compose stop exporter
$ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------
alertmanager /bin/alertmanager --config ... Up 9093/tcp
exporter ./app Exit 2
grafana /run.sh Up 3000/tcp
nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp
prometheus /bin/prometheus --config.f ... Up 9090/tcp
それぞれのコンテナでメトリクスの変化に対応した処理が行われていることが確認できる.
アラートはAlertmanagerからGmail経由で送る設定にしているのでメールが届くことも確認できる.
やったぜ.
自作ExporterとPrometheus
, Alertmanager
, Grafana
を同時に動かして動作確認することができた.
おわり
終わってみれば大したことはないんだけど, 一回この構成をつくっておくと自作Exporterの開発が楽しくなる(メトリクスがすぐ可視化されアラートの動作確認までできる)のでやってよかったと思う.
Docker Compose
の練習にもなってよかった.