背景
コンテナ数も増え,それに依存したサービスも増える中,サーバのapt upgrade
後にPT3が行方不明になってこのすばの録画が死んだこともあり,いずれこれは把握できる範囲を超えるなと思ったため,監視ツールを何か導入する必要があると考えました.
いくつか候補は挙がったのですが,最終的にZabbixを選ぶか,Prometheusを選ぶかで悩んでGrafanaが最初からサポートしているという理由でPrometheusを選択しました.
今回はPrometheusでcAdvisorから情報を取得,Grafanaで可視化するまでを行います.Alertmanagerなどの導入はちゃんとできたらまた記事にします.
使うもの
Prometheus
Prometheusはサーバ側から監視先を叩きに行くPull型の監視ツールです.詳しいことはQiitaの先人におまかせします.
exporterと呼ばれるエンドポイントを建てて情報を収集します.今回はホストの情報を収集するためにnode-exporterを使用します.
cAdvisor
cAdvisorはDockerホスト上のコンテナの監視ツールとしてGoogleが開発しているものです.Googleさまさまです.
単体で監視を行いますが,メモリ上に直近60秒の情報を保持するのみで保存しないため,InfluxDBとよく組み合わせられています*1.このcAdvisorは実はPrometheusに対応しており,デフォルトでhttp://cAdvisorへのアドレス:8080/metrics
で各種のメトリクスを取得できます.
一つのDockerホストに一つずつcAdvisorが起動していれば後はまとめて叩いて回ってデータを集計するだけでいいというわけですね(うちにはホスト一つしか無いですが
Grafana
かっこいいダッシュボードを作るアプリケーションです(ざっくり
テンプレートが多数公開されており,それらをカスタマイズするだけで十分な機能を得られます.
環境
- Ubuntu Server 16.04 LTS
- Docker version 1.13.1
- Docker compose version 1.8.0
設定
今回は全てDockerコンテナとして建てます.
ディレクトリ構造は以下の様にします.
. ├── docker-compose.yml ├── grafana └── prometheus └── prometheus.yml
外側からアクセスするGrafanaと(一応)Prometheusには静的なIPを振っておきます*2.cAdvisorは直接触らないので,Dockerのネットワーク内に閉じ込めておきます.
以下の様なネットワークを作っておきます.
$ docker network create -d bridge -o "com.docker.network.bridge.name"="monitor_nw" monitor_nw
また,下記の過去記事で作成したmacvlanドライバのdmz_nw
を使用します.
Prometheusの設定
がつがつdocker-compose.ymlを書いていきます.
version: "2" services: prometheus: image: prom/prometheus container_name: prometheus volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml expose: - "9090" networks: default: aliases: - prometheus dmz_nw: ipv4_address: xxx.xxx.xx.y restart: always networks: default: external: name: monitor_nw dmz_nw: external: name: dmz_nw
macvlanでIPアドレスを割り振っているのでホストのポートとのマッピングはしていません.
設定ファイルであるprometheus.yml
はとりあえず最低限のことを書いておきます.
prometheus自身のメトリクスを取得する設定,後述のnode-exporterとcAdvisorから情報を取得する設定です.15秒間隔で情報を取りに行くようにしています.
global: scrape_interval: 15s external_labels: monitor: "monitor" scrape_configs: - job_name: "prometheus" static_configs: - targets: ["prometheus:9090"] - job_name: "node" static_configs: - targets: ["ホストのアドレス:9100"] labels: group: "docker-host" - job_name: "docker" static_configs: - targets: ["cadvisor:8080"] labels: group: "docker-container"
localhost
を指定するとうまく動かないので,わざわざホストのアドレスも直打ちしています.
詳しい設定は公式ドキュメントを参照してください.
node-exporterの設定
node-exporterはホストの様々な情報を取得するexporterです.そのため,ホストのルートディレクトリをマウントする必要があります..また,host
ネットワークを使用する必要があるため,ホストのポートとのマッピングを行いアクセスできるようにしています.
# 省略 node-exporter: image: prom/node-exporter container_name: node-exporter volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro ports: - "9100:9100" network_mode: host restart: always # 省略
cAdvisorの設定
権限を多く要求する怖いコンテナです.外側から直接アクセスできないようにDockerネットワークに封じ込めます.
# 省略 cadvisor: image: google/cadvisor:latest container_name: cadvisor volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker:/var/lib/docker:ro expose: - "8080" privileged: true networks: default: aliases: - cadvisor restart: always # 省略
特にprivileged: true
が怖いのですが,僕の環境ではこれをオンにしないと動きませんでした*3
Grafanaの設定
最後にフロントエンドのGrafanaをセットアップします.今回はわざとしていませんが,過去記事のnginxとdocker-genを組み合わせたシステムでサブドメインを割り当てることも出来ると思います.
また,普通に起動するとusernameがadmin
,パスワードもadmin
の状態になっており,サインアップも勝手に出来るようになっているので環境変数でそのあたりを制御します.
# 省略 grafana: image: grafana/grafana container_name: grafana volumes: - ./grafana:/var/lib/grafana networks: default: aliases: - grafana dmz_nw: ipv4_address: xxx.xxx.xx.z restart: always environment: GF_SECURITY_ADMIN_USER: hoge GF_SECURITY_ADMIN_PASSWORD: fuga GF_USERS_ALLOW_SIGN_UP: "false" GF_USERS_ALLOW_ORG_CREATE: "false" # 省略
GF_SECURITY_ADMIN_USER
とGF_SECURITY_ADMIN_PASSWORD
がそれぞれ初期管理ユーザのユーザ名とパスワードになります.
GF_USERS_ALLOW_SIGN_UP
はサインアップの無効化で,トップページからサインアップの項目が消えます.GF_USERS_ALLOW_ORG_CREATE
は管理権限のあるユーザ以外のorgnizationの作成を無効にします.
起動
$ docker-compose up -d
この状態でまずprometheusに割り当てたアドレスxxx.xxx.xx.y:9090
にアクセスして表示されるかを確認します.
次に,Grafanaに割り当てたxxx.xxx.xx.z:3000
を開いて設定したユーザ名とパスワードでログインします.DataSourceを追加するときソースの種類をPrometheusで選択するとhttp://localhost:9090
がサジェストされますがこれは使いません.prometheusで名前解決できるようになっているので,http://prometheus:9090/
を指定します.
Grafanaのテンプレートは以下のものを使用しました.
何もいじっていない状態で以下の様になりました.loadの値が取れていませんが,まぁおいおい自分でいじくっていきたいと思います.
まとめ
思ったより簡単に値を取るところまではできました.後はGrafanaからクエリを叩いて表示していくだけです.難しそう.
また今回はAlertmanagerを含めていません.ここまではcAdvisor + InfluxDBでもできることになってしまうので,次はアラートの設定もしていこうと思います.