Posted at

prometheus で雑に始めるサーバ監視

More than 1 year has passed since last update.


概要

prometheus をつかって個人サーバを監視するのを雑に始める。


使用するもの

prometheus はデータを pull 型で収集するアプリケーションで、メトリクス取得のために exporter とアプリケーションをそれぞれ必要に応じて利用する必要がある。prometheus および expoter は自前でインストールするといろいろ面倒なので docker のコンテナを使って構築する。ここでは grafana は扱っていない。

今回自分が構築した環境は下記のとおり。


  • Ubuntu 16.04.1 LTS

  • Docker 1.13.0

  • prometheus 1.5.0


内容

最初にここでやる全部の作業としてまとめを記載して、あとでそれぞれ詳細を書く。


まとめ


  • ここでは下記メトリクスが取得できるようにする


    • CPU やメモリなどの基本的な項目

    • docker コンテナそれぞれの基本的な項目



  • docker のコンテナで構成する


    • docker の User-defined network を使う


      • 直接外から見られないようにするため

      • コンテナの IP アドレスを固定するため





  • prometheus および alertmanger の UI 用にリバースプロキシする

  • アラート飛ばせるようにする


    • 設定例は gmail



当たり前だけど1台なので自身が落ちてたらどうしようもない。


構成

コンテナ情報

IP アドレスは範囲内ならなんでもいいので下記のは例。

コンテナ名
IPアドレス
ポート

prometheus-container
172.18.0.2
9090

node-exporter-container
172.18.0.3
9100

alertmanager-container
172.18.0.4
9093

cadviser-container
172.18.0.6
8080


手順

Docker の userdefined network 作成

$ docker network create --subnet=172.18.0.0/24 prometheus_nw

イメージの取得

$ echo "prom/prometheus prom/alertmanager google/cadvisor prom/node-exporter" | xargs -n 1 docker pull

prometheus および exporter でそれぞれ必要な設定ファイルを設置。ここでは /home/prometheus 以下とする。変更する場合は後述する 起動時の引き数も変更する。

$ pwd

/home/prometheus
$ tree -L 2
.
├── alertmanager
│ ├── alertmanager.yml
│ └── data
└── prometheus
├── alerts.rule
├── data
└── prometheus.yml
4 directories, 3 files


prometheus.yml

global:

scrape_interval: 15s # By default, scrape targets every 15 seconds.

rule_files:
- alerts.rule

scrape_configs:
- job_name: node
static_configs:
- targets: ['172.18.0.3:9100']
- job_name: docker
static_configs:
- targets: ['172.18.0.6:8080']



alerts.rule

ALERT InstanceDown

IF up == 0
FOR 5m
LABELS { severity = "page" }
ANNOTATIONS {
summary = "Instance {{ $labels.instance }} down",
description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
}

アラート飛ばす先の設定。

下記は Gmail で送る場合の例。


Sending email with the Alertmanager via Gmail

https://www.robustperception.io/sending-email-with-the-alertmanager-via-gmail/


アプリ毎にパスワード設定する場合のヘルプ


Sign in using App Passwords

https://support.google.com/accounts/answer/185833?hl=en


パスワードはここでつくる

https://security.google.com/settings/security/apppasswords


alertmanager.yml

route:

receiver: hogehoge-mail
receivers:
- name: hogehoge-mail
email_configs:
- to: "hogehoge@example.com"
from: "hogehoge@example.com"
smarthost: smtp.gmail.com:587
auth_username: "hogehoge@example.com"
auth_identity: "hogehoge@example.com"
auth_password: "brabrabrabra"

起動

$ docker run --name=prometheus-container -d --net=prometheus_nw --ip=172.18.0.2 -v /home/prometheus/prometheus:/prometheus prom/prometheus -config.file=/prometheus/prometheus.yml   -alertmanager.url=http://172.18.0.4

$ docker run --name=node-exporter-container -d --net=prometheus_nw --ip=172.18.0.3 -v "/proc:/host/proc" -v /sys:/host/sys -v /:/rootfs prom/node-exporter -collector.procfs /host/proc -collector.sysfs /host/sys -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
$ docker run --name=alertmanager-container -d --net=prometheus_nw --ip=172.18.0.4 -v /home/prometheus/alertmanager:/alertmanager prom/alertmanager -config.file=/alertmanager/alertmanager.yml -web.external-url=http://alertmanager.example.com
$ docker run --name=cadvisor-container -d --net=prometheus_nw --ip=172.18.0.6 --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --detach=true google/cadvisor:latest

nginx 設定して UI を見られるように

upstream prometheus {

server 172.18.0.2:9090;
}
upstream alertmanager {
server 172.18.0.4:9093;
}

server {
listen 80
server_name prometheus.example.com;

location / {
proxy_pass http://prometheus;

auth_basic "Prometheus";
auth_basic_user_file ".htpasswd";
}
}
server {
listen 80
server_name alertmanager.example.com;

location / {
proxy_pass http://alertmanager;

auth_basic "AlertManager";
auth_basic_user_file ".htpasswd";
}
}

htpasswd 作る

$ cd /etc/nginx/

$ sudo htpasswd -c .htpasswd prometheus

nginx を reload するなり restart するなりして prometheus.example.com および alertmanager.example.com が表示できることを確認。

以上、あとは自分の環境用に設定を変更したり必要なものをインストールしたり、 grafana を使ってダッシュボードを作ったりする。


雑記


prometheus について

サーバ監視するにはいろいろあるようだけど、最近は prometheus というのがホットらしい。

prometheus は それ自身と exporter で構成される


exporter の一覧

https://prometheus.io/docs/instrumenting/exporters/


prometheus を動かすには apt などのパッケージ管理システムを使ってインストールすることも出来るけど、わりと古かったりするのが面倒なので公式で提供されている docker イメージを使うことにする。

ちなみに 一旦 apt で入る prometheus は最新のものと設定ファイルなどが異なる可能性があるので 既存のものから docker イメージの prometheus に移行する際は注意が必要。


prometheus on docker


prometheus 公式の docker イメージ

https://hub.docker.com/u/prom/


とりあえず prometheus だけ起動する場合


Using Docker

https://prometheus.io/docs/introduction/install/#using-docker


ここのようにホスト側のポート使ってもいいけど、expoter 系が外部から直接見られるのって怖いなーという感じ。 iptables などで設定しても良いんだろうけど、今回は docker のユーザ定義ネットワークを使っている。

https://docs.docker.com/engine/userguide/networking/

また、適当にネットワークにアタッチする場合 IP アドレスが起動するたびに変わってしまう。prometheus の設定に直書きだと思うので個々らへんは固定でやる。 ここらへんはコンテナ起動時に設定する。起動したままネットワークにアタッチする場合は固定にできなかった気がする。

http://qiita.com/paihu/items/17aa47906dd2bf935a25

http://qiita.com/takara@github/items/2349fff473474d7fcf47

下記のようなコマンドで監視系のコンテナをぶら下げるネットワークを作ることができる。たぶんこれだけ。このネットワークを指定してコンテナを作ったり起動途中でアタッチしたりするとこのネットワークに入る。指定せずに起動した場合はデフォルトのネットワークの方に入る。

$ docker network create --subnet=172.18.0.0/24 prometheus_nw


docker コンテナについて

ざっくり docker pull すると下記のようになる。(横着して xargs で書いてる)

$ echo "prom/prometheus prom/alertmanager google/cadvisor prom/blackbox_exporter prom/node-exporter" | xargs -n 1 docker pull

説明

名前
雑な説明
リポジトリ

prometheus
メトリクスを exporter から pull してファイルシステムに保存する
https://github.com/prometheus/prometheus

node-expoter
CPU とか メモリ とか見られるからとりあえずいれとけって exporter
https://github.com/prometheus/node_exporter

alertmanager
アラート飛ばすときにどこに飛ばすかとか静観するかとか設定できる。ルール自体は prometheus で指定するけど。
https://github.com/prometheus/alertmanager

cadvisor
Docker コンテナの監視に使うらしい。 mysql-exporter と同じポートを使うのでホストに紐付ける場合は注意。
https://github.com/google/cadvisor

今回は下記のように設定する。 container を suffix にしてるのはコマンドなどと混同しないようにするため。


起動コマンド

prometheus

$ docker run --name=prometheus-container --net=prometheus_nw --ip=172.18.0.2 -d -v /home/prometheus/prometheus:/prometheus prom/prometheus -config.file=/prometheus/prometheus.yml   -alertmanager.url=http://172.18.0.4

node_exporter

$ docker run --name node-exporter-container -d --net=prometheus_nw --ip=172.18.0.3 -v "/proc:/host/proc"  -v "/sys:/host/sys" -v "/:/rootfs" prom/node-exporter -collector.procfs /host/proc -collector.sysfs /host/sys -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"

参考 https://github.com/prometheus/node_exporter

今回の場合、 docker を動かしてるので README の最後にあるように起動する。

alertmanager

UI の URL は自分の環境に合わせて。

$ docker run --name alertmanager-container -d --net=prometheus_nw --ip=172.18.0.4 -v /home/prometheus/alertmanager:/alertmanager prom/alertmanager -config.file=/alertmanager/alertmanager.yml -web.external-url=http://alertmanager.example.com

cadvisor

$ docker run --name=cadvisor-container --net=prometheus_nw --ip=172.18.0.6 --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --detach=true  google/cadvisor:latest


configuration for prometheus

設定ファイルなどはホスト側に置くことになる。置く場所は好きな場所でよい。自分の場合はもともと apt で入った prometheus ユーザで動かしていたので とりあえず /home 以下に prometheus 設定を入れた。

$ pwd

/home/prometheus
$ tree -L 2
.
├── alertmanager
│   ├── alertmanager.yml
│   └── data
└── prometheus
├── alerts.rule
├── data
└── prometheus.yml
4 directories, 3 files

prometheus 自体の設定

参考URL


https://prometheus.io/docs/operating/configuration/

https://prometheus.io/docs/introduction/getting_started/


下記のものはとりあえず node_exporter と docker のものを pull するようにする設定。exporter を増やしたりした場合は適宜変更するファイル。


prometheus.yml

global:

scrape_interval: 15s # By default, scrape targets every 15 seconds.

rule_files:
- alerts.rule

scrape_configs:
- job_name: node
static_configs:
- targets: ['172.18.0.3:9100']
- job_name: docker
static_configs:
- targets: ['172.18.0.6:8080']


アラートルールは別ファイルに書く。

参考URL


https://prometheus.io/docs/alerting/rules/


とりあえず node_expoter が落ちてたらアラート飛ばす例。アラートルールの知見ほしいですね。


alerts.rule

ALERT InstanceDown

IF up == 0
FOR 5m
LABELS { severity = "page" }
ANNOTATIONS {
summary = "Instance {{ $labels.instance }} down",
description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
}

alertmanager 側の設定

ここではアラート飛ばす先の設定をする。

下記は Gmail で送る場合の例。


Sending email with the Alertmanager via Gmail

https://www.robustperception.io/sending-email-with-the-alertmanager-via-gmail/


アプリ毎にパスワード設定する場合のヘルプ


Sign in using App Passwords

https://support.google.com/accounts/answer/185833?hl=en


パスワードはここでつくる

https://security.google.com/settings/security/apppasswords

その他いろいろ対応しているので必要な通知先を設定する。prometheus で付与した job やラベルによって通知先や通知メッセージを変えたりできるのでうまいことやる。


alertmanager.yml

route:

receiver: hogehoge-mail
receivers:
- name: hogehoge-mail
email_configs:
- to: "hogehoge@example.com"
from: "hogehoge@example.com"
smarthost: smtp.gmail.com:587
auth_username: "hogehoge@example.com"
auth_identity: "hogehoge@example.com"
auth_password: "brabrabrabra"


設定反映について

docker で起動した prometheus や exporter の設定を変更した場合、 docker stop && docker start でよい。

または systemd が使える場合は事項のように設定して systemctl restart で行っても良さそう。


起動の管理およびアップデート

Ubuntu 16.04.1 では systemd 使ってるのでこれで起動管理できたら楽そう


Start containers automatically

https://docs.docker.com/engine/admin/host_integration/


下記の様に設定する。run のものは -d または --detach=true を削除する必要がある。


Make sure you don’t use “-d” for “detached mode”. The command run from “ExecStart” needs to run in the foreground.



/etc/systemd/system/prometheus-container.service

[Unit]

Description=prometheus container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=
ExecStart=/usr/bin/docker run --name=prometheus-container --net=prometheus_nw --ip=172.18.0.2 -v /home/prometheus/prometheus:/prometheus prom/prometheus -config.file=/prometheus/prometheus.yml -alertmanager.url=http://172.18.0.4
ExecStop=/usr/bin/docker stop -t 2 prometheus-container
ExecStopPost=/usr/bin/docker rm -f prometheus-container

[Install]
WantedBy=default.target


このようにしておけば、 アプリケーションのアップデートは下記のようにするだけでよい。

$ docker pull prom/prometheus 

$ sudo systemctl restart prometheus-container.service

下記記事のように ExecStartPre で pull しても良いかもしれないが、 restart するだけでアップデートされるのは個人的に好みではないのでやってない。


dockerコンテナをsystemdで管理させる

http://qiita.com/74th/items/e8dc1ac1295140413dc8



UserInterface

UI を見られるようにするために 適当に nginx に設定書く。下記はざっくりした例。cadviser にも UI があるが cadviser の UI も確認したければ同様に追加すると良い。

簡単に見られると困りそうなので雑に BASIC 認証入れてる。grafana を使う場合にデータソースとして prometheus を指定して利用することになるが、この場合でも grafana の設定で BASIC 認証書けるので問題なし。

upstream prometheus {

server 172.18.0.2:9090;
}
upstream alertmanager {
server 172.18.0.4:9093;
}

server {
listen 80
server_name prometheus.example.com;

location / {
proxy_pass http://prometheus;

auth_basic "Prometheus";
auth_basic_user_file ".htpasswd";
}
}
server {
listen 80
server_name alertmanager.example.com;

location / {
proxy_pass http://alertmanager;

auth_basic "AlertManager";
auth_basic_user_file ".htpasswd";
}
}

とりあえず .htpasswd 作る例

$ cd /etc/nginx/

$ sudo htpasswd -c .htpasswd prometheus