Cloudproberとは
Cloudproberは、システムやサービスを監視するためのGoogle謹製のオープンソースモニタリングソフトフェアで、Go言語で実装されています。HTTP、UDP、PING、DNS Probeが組み込みで実装されている他、External Probeという仕組みにより標準入出力でやりとりする外部の実行プログラムを通じてProbe機能をカスタムで拡張できます。Probeの結果はStackDriverとPrometheusにエクスポートできます。さらに、(今回は扱いませんが、)Google Cloud上ではターゲットを自動検出することができます。
[Google Open Source Blog] Cloudprober: open source black-box monitoring software
https://opensource.googleblog.com/2018/03/cloudprober-open-source-black-box.html
cloudprober.org
https://cloudprober.org/
Github
https://github.com/google/cloudprober/
前提
この記事では、以下の環境を用いています。
- Ubuntu 16.04.3
- Cloudprober 0.9.3
- Prometheus 2.3.1
- Grafana 5.2.1
Cloudproberのセットアップ
CloudproberはGo言語で実装されていてバイナリ一つで動作します。プラットフォーム毎にバイナリ化されたものが用意されているので、手っ取り早くこれを使います。
https://github.com/google/cloudprober/releases
$ wget https://github.com/google/cloudprober/releases/download/0.9.3/cloudprober-0.9.3-linux-x86_64.zip
$ unzip cloudprober-0.9.3-linux-x86_64.zip
HTTP Probe
手始めに、HTTP Probeを試します。
HTTP Probe用の設定ファイルを用意します。
probe {
name: "ping-probe-to-google"
type: HTTP
targets {
host_names: "www.google.com"
}
}
Cloudproberのバイナリを展開したディレクトリに移動して、Cloudproberを実行します。
$ ./cloudprober -config_file cloudprober.cfg
すると、定期的にデータを取得し始めます。
最初の4行分は設定内容にかかわらずデフォルトで取得されるデータのようです。
最後の行がHTTP Probeで取得したデータになります。
cloudprober 1531202334854079988 1531202344 labels=ptype=sysvars,probe=sysvars hostname="vagrant"
cloudprober 1531202334854079989 1531202344 labels=ptype=sysvars,probe=sysvars cpu_usage_msec=163.139
cloudprober 1531202334854079990 1531202344 labels=ptype=sysvars,probe=sysvars uptime_msec=10002.874 uptime=10 gc_time_msec=0 mallocs=11847 frees=567
cloudprober 1531202334854079991 1531202344 labels=ptype=sysvars,probe=sysvars goroutines=15 mem_stats_sys_bytes=3903488
cloudprober 1531202334854079992 1531202344 labels=ptype=http,probe=http-probe-to-google,dst=www.google.com total=1 success=1 latency=216295.213 timeouts=0 resp-code=map:code,200:1 resp-body=map:resp
...
Cloudproberを動作させると、同時に裏側でPrometheus Exporterが動作します。
ブラウザからhttp://<Cloudprobeが動作しているサーバのIP>:9313/metrics
にアクセスすると以下のような結果になります。HTTP Probeと関係ない項目は割愛してます。
#TYPE hostname gauge
...
#TYPE total counter
total{ptype="http",probe="http-probe-to-google",dst="www.google.com"} 1 1531202344854
#TYPE success counter
success{ptype="http",probe="http-probe-to-google",dst="www.google.com"} 1 1531202344854
#TYPE latency counter
latency{ptype="http",probe="http-probe-to-google",dst="www.google.com"} 216295.213 1531202344854
#TYPE timeouts counter
timeouts{ptype="http",probe="http-probe-to-google",dst="www.google.com"} 0 1531202344854
#TYPE resp_code counter
resp_code{ptype="http",probe="http-probe-to-google",dst="www.google.com",code="200"} 1 1531202344854
PING Probe
PING Probeは、Root権限が必要なRawソケットとRoot権限の要らないICMP Echoの送受信に制限されたDatagramソケットで動作する2種類があります。
ICMP用途のDatagramソケットで動作させるためのHTTP Probe用の設定ファイルを用意します。
probe {
type: PING
name: "ping-probe-to-google"
targets {
host_names: "www.google.com"
}
ping_probe {
use_datagram_socket: true
source_interface: "eth0"
}
}
ICMP用途のDatagramソケットは多くのシステムでデフォルトでは有効ではないので、以下のようにカーネルパラメータを設定します。
$ sudo sysctl -w net.ipv4.ping_group_range="0 5000"
Cloudproberを実行すると、以下のようになります。PING Probeと関係ない項目は割愛してます。
$ ./cloudprober -config_file ping_probe.cfg
...
cloudprober 1531207071003333543 1531207081 labels=ptype=ping,probe=ping-probe-to-google,dst=www.google.com total=10 success=10 latency=1513849.826
...
DNS Probe
DNS Probe用の設定ファイルを用意します。
probe {
type: DNS
name: "dns-probe-to-google"
targets {
host_names: "8.8.8.8,8.8.4.4"
}
dns_probe {
resolved_domain: "www.google.com."
}
}
Cloudproberを実行すると、以下のようになります。DNS Probeと関係ない項目は割愛してます。
$ ./cloudprober -config_file dns_prove.cfg
...
cloudprober 1531207394187566637 1531207404 labels=ptype=dns,probe=dns-probe-to-google,dst=8.8.8.8 total=4 success=4 latency=142839.218 timeouts=0
cloudprober 1531207394187566638 1531207404 labels=ptype=dns,probe=dns-probe-to-google,dst=8.8.4.4 total=4 success=4 latency=164540.74 timeouts=0
PrometheusおよびGrafanaとの連携
最後に、PrometheusおよびGrafanaとの連携を説明します。
それっぽい例として、同じターゲット(www.google.com)に対して、PING ProbeとHTTP Probeを実行します。ユーザーが体感するレスポンスが遅いときに、それがネットワーク側の問題なのか、サービス側の問題なのかを切り分けることができます。出張先のホテルのWIFI環境で試しているためいい具合に(!?)遅延が発生してます。
複数のProbeを設定する方法を一瞬迷いましたが、単純に一つの設定ファイルに複数記述してあげればOKでした。
probe {
name: "http-probe-to-google"
type: HTTP
targets {
host_names: "www.google.com"
}
}
probe {
type: PING
name: "ping-probe-to-google"
targets {
host_names: "www.google.com"
}
ping_probe {
use_datagram_socket: true
source_interface: "eth0"
}
}
前述のとおりCloudproberはPrometheus Exporterとして動作しているので、Prometheusの設定は以下のようになります。PrometheusはCloudproberと同じサーバで動作している前提です。
scrape_configs:
- job_name: 'cloudprober'
scrape_interval: 10s
static_configs:
- targets: ['localhost:9313']
あとは、GrafanaのデータソースとしてPrometheusを指定して、グラフを作成します。
ちなみに、Grafanaでグラフ作成用に設定したクエリーはそれぞれ以下のとおりです。
PING Probe
rate(latency{probe="ping-probe-to-google"}[20s])/rate(total{probe="ping-probe-to-google"}[20s])
HTTP Probe
rate(latency{probe="http-probe-to-google"}[20s])/rate(total{probe="http-probe-to-google"}[20s])
トラブルシューティング
実行時に-logtostderr
フラグを付与すると、ログを標準エラーに出力してくれます。
$ ./cloudprober -config_file pg_probe.cfg -logtostderr
たとえば、PING Probeで当初source_interface
を指定していなかったためにうまく動作していませんでした。そのときに、-logtostderr
フラグ付与したところ、以下のようなログが出力されていたため、設定ミスに気づくことができました。
W0709 13:57:39.626037 1731 logger.go:181] write udp 127.0.1.1:10->172.217.8.4:0: sendto: invalid argument
おしまい