dockerを使ってPrometheus + node exporter + Grafanaでサーバー監視をするお話です。
dockerのcontainer間通信で苦労した(結局良く解ってない)ので、そのメモです。
最初の躓きはGrafanaの設定でした。
巷の手順では、Datasourceにlocalhost:9090を指定するとPrometheusを指定できるとありますが、UNKNOWN ERRORというのが出て設定できません。
ここはGrafanaをdockerではなくローカルOS(?)に直接入れる事で回避しました。
次にnode exporterをdockerで入れてPrometheusと繋げようとしますが、Prometheus側からnodeが見えません。
(targetsのページでerror表示される)
設定と起動はこんな感じです。
■node exporter
docker run -d -p 9100:9100 \ -v "/proc:/host/proc:ro" \ -v "/sys:/host/sys:ro" \ -v "/:/rootfs:ro" \ quay.io/prometheus/node-exporter \ -collector.procfs /host/proc \ -collector.sysfs /host/sys \ -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
■prometheus
# vi prometheus/prometheus.yml
global: scrape_interval: 15s evaluation_interval: 15s external_labels: monitor: 'codelab-monitor' scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node' static_configs: - targets: ['localhost:9100']
docker run -d -p 9090:9090 -v /root/prometheus/prometheus.yml:/prometheus.yml prom/prometheus -config.file=/prometheus.yml
telnet localhost 9100をやるとちゃんと見えますから、node exporterは正常に稼働しています。ただ、prometheusのdocker containerから見えないのです。
dockerのネットワークに関するこのへんの記事を見ると、dockerのnetworkは独立していて、container毎に別のipアドレスが割り当てられる事が解ります。
図を見る限り、container内でlocalhostと指定しても、container自身が指定されるだけでlocal machineを指すのでは無いように見えます。
Docker コンテナ・ネットワークの理解
そこで、試しにdocker network内のipアドレスでアクセスを試みます。
まずはnetwork状況の調査。
# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "649ee6c1ef55a7cd50796b5d0dcd1e4e9afadbcd72e64945e9ff0bd007398111",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Internal": false,
"Containers": {
"0c0cbbd10d08494ba8b14d8c5410dc69a994f897f2bcb6754be68f8617025660": {
"Name": "happy_carson",
"EndpointID": "5646964074b49a4c876a2e5c17475f24327324a17f4ec29eaa0e6571976c0d79",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"61667ec99c501c033e62e0274e9d143999937c911dc4a81a32a12453a3f29c3b": {
"Name": "pensive_stonebraker",
"EndpointID": "e01e31c810da89ecd65ff95a618a80130496e36faf329e3a62c865742e5bffce",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
nodeのipアドレスは172.17.0.3であることが解るので、prometheus.ymlの設定を変更します。
- targets: ['172.17.0.3:9100']
そしてprometheus再起動。
# docker restart containerID
prometheusのtargetsを確認します。http://IPアドレス:9090/targets
ちゃんと認識できていますね。
ネットワーク図的にはこんな感じ。
でもググって出てくるのはlocalhostの指定ばかり。
みんなこれでちゃんと動いているんでしょうね。docker daemon生成時の設定が何か違うのでしょうか・・・。
containerのIPアドレスは固定ではないのでこの方法は不安定です。container起動時にIPアドレスを指定する方法もありますが、なんかスマートじゃありませんよね。
もうちょっとdocker理解したら、再度挑戦してみます。