狠狠撸

狠狠撸Share a Scribd company logo
Prometheus
入門から運用まで徹底解説
株式会社ホワイトプラス システム開発Gマネジャー 大和屋貴仁
July Tech Festa 2017
googleエンジニアが作った監視システム
大和屋貴仁
株式会社ホワイトプラス
システム開発G マネジャー
Microsoft MVP for Azure(2011-2018
Qiita : @t_Yamatoya
http://sqlazure.jp/r
富士フィルムイメージングシステムズと
共同開発したRFID検証。
宅配ネットクリーニングのリネット
会員数20万人突破!
Golang、RFIDなど新しい技術や物を活用したサービス改善に興味のあるエンジニア募集!!
Prometheus の話をはじめる前に、
何故、Prometheusか?
SRE サイトリライアビリティエンジニアリング
――Googleの信頼性を支えるエンジニアリングチーム
Prometheusは、特にルール言語にBorgmonと多くの
類似点があります。
依然としてBorgmonはGoogle内部のものですが、ア
ラートを発するためのデータソースとして時系列デー
タを扱うという発想は、今日ではPrometheus、
Riemann、Heka、Bosunといったオープンソースの
ツールを通じて広く受け入れられており…
Prometheus と google
SRE サイトリライアビリティエンジニアリング
――Googleの信頼性を支えるエンジニアリングチーム
Borgmanとは
? 10年以上に渡って利用されているgoogle内部のモニタ
リングツールの名称
? カスタムスクリプトを実行するのではなく、共通の
データ公開フォーマットを利用する
データのフォーマット
? 大量の収集を行うためにメトリックスのフォーマット
は標準化されている必要がある
? key/value式のプレーンテキストを返す
? スキーマ―を持たないテキストベースのインターフェ
イスが追加の障壁を低くする
go_gc_duration_seconds{quantile="0"} 8.007600000000001e-05
go_gc_duration_seconds{quantile="0.25"} 0.000297585
go_gc_duration_seconds{quantile="0.5"} 0.00030774400000000004
go_gc_duration_seconds{quantile="0.75"} 0.000317933
go_gc_duration_seconds{quantile="1"} 0.004497566000000001
go_gc_duration_seconds_sum 1059.847743361
Borgmanと同様の仕様
ターゲットの発見
? データ収集をする対象を自動で検出する
? サービスディスカバリ(Service Discovery)を利用すること
でリストのメンテナンスコストを下げる
Borgmanと同様の仕様
データの収集
? 指定された間隔でターゲットのURIからフェッチする
? HTTP経由でターゲットをスクレイピングする
? フェッチ時に合成変数も記録する
? ホスト名とポート番号に解決できるか
? レスポンスを返したか
? 収集が完了した時刻
Borgmanと同様の仕様
% curl http://webserver:80/varz
http_requests 37
errors_total 12
時系列データベース
? データをインメモリデータベースに格納し、定期的に
チェックポイントで時系列データベース(ディスク)
に書き出す
? timestampとvalue形式で、時系列データに沿って格納
する
Borgmanと同様の仕様
http_requests_total{status="200",method="GET"}@1434317560938 ? 94355
http_requests_total{status="200",method="GET"}@1434317561287 ? 94934
http_requests_total{status="200",method="GET"}@1434317562344 ? 96483
http_requests_total{status="404",method="GET"}@1434317560938 ? 38473
http_requests_total{status="404",method="GET"}@1434317561249 ? 38544
http_requests_total{status="404",method="GET"}@1434317562588 ? 38663
http_requests_total{status="200",method="POST"}@1434317560885 ? 4748
ラベル
ヒエラルキーのツリー構造ではなくラベルで表現する
key/value形式のラベル集合で実装される
ラベルは変数式と呼ばれる形式にまとめられる
Borgmanと同様の仕様
{var=http_requests,job=webserver,service=web,zone=us-west}
クエリ式
? クエリを実行するとベクタ内で最新の値をもつ行が返
される
? 期間を指定することができる
Borgmanと同様の仕様
{var=http_requests,job=webserver,instance=host0:80,service=web,zone=us-west} 10
{var=http_requests,job=webserver,instance=host1:80,service=web,zone=us-west} 9
{var=http_requests,job=webserver,instance=host2:80,service=web,zone=us-west} 11
{var=http_requests,job=webserver,instance=host3:80,service=web,zone=us-west} 0
{var=http_requests,job=webserver,instance=host4:80,service=web,zone=us-west} 10
{var=http_requests,job=webserver,service=web,zone=us-west}[10m]
{var=http_requests,job=webserver,instance=host0:80, ...} 0 1 2 3 4 5 6 7 8 9 10
アラート/Alertmanager
? 真偽で判断し、真になるとアラート発行
? アラートには式が使え、瞬間的な閾値越えへの対処が容易
? Altermanagerは通知先へのアラート転送を担当する
? アクティブになっているアラートに応じた他のアラート抑制
? 類似したラベルセットを持つ複数のアラートが発生した際の集約
Borgmanと同様の仕様
BorgmanとPrometheusの類似点まとめ
? データフォーマット:プレーンテキストのkey/value
? Target Discovery
? データの収集方法:URLフェッチ、スクレイピング
? 時系列データベース
? ラベル
? クエリ式
? アラート
Prometheus の歴史
2012秋
作成
2016/05
CNCF参加
2015/01
一般公開開始
2016/07
1.0 リリース
2017/08
2.0.0-beta.2 リリース
Prometheus の歴史
2012秋
作成
2016/05
CNCF参加
2015/01
一般公開開始
2016/07
1.0 リリース
2017/08
2.0.0-beta.2 リリース
SoundCloudがモニタリング開発の検証開始
Matt ProudがSoundCloudに入社し、Prometheusの方向性を決める
Matt Proud
2007/04-2012/08 google
2012/09-2013/09 Sound Cloud
2014/01- google
Prometheusの機能
? モニタリングシステムと時系列DB
? 測定
? メトリックス収集と保存
? 保存したメトリックスに対するクエリ
? アラート
? ダッシュボード
? 注力
? OSモニタリング
? 動的クラウド環境
Prometheusがしないこと
? 生ログ?イベントデータの収集
? リクエストトレース
? 例外発見
? 長期保存ストレージ
? 自動水平スケール
? ユーザー/認証管理
Prometheusの利用企業
? AbemaTV / Cyberagent
? Line
? Yahoo!Japan
? Freee
? ホワイトプラス
Prometheus 入門
Prometheusの利用企業
Prometheus ServerExporterExporterExporter
Pull
Grafana/API/Web UI
Altermanager
Push
Prometheusの構築
? 構築は単一バイナリを動かすだけでOK
? プリコンパイルされたバイナリをダウンロードして実行
? Sourceからmake
? Dockerコンテナー
docker run -p 9090:9090 -v /prometheus-data 
prom/prometheus -config.file=/prometheus-data/prometheus.yml
設定:Prometheus.yml
? Service Discoveryを利用する
? EC2をTargetにしてみる
? localhostも対象にしてみる
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key:
secret_key:
port: 9100
relabel_configs:
- source_labels: [__meta_ec2_tag_Name]
target_label: instance
exporterを動かす
? 監視対象でexporterを動かします
? node_exporter: *NIXカーネル用のハードウェアとOSのメト
リックス収集。
node_exporter --
collectors.enabled="conntrack,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,
stat,textfile,time,vmstat" >/dev/null 2>&1 &
準備完了!
? Prometheusサーバーの9090ポートにア
クセスするとステータスページを確認
できる
ビジュアライズ表示
? 標準でもグラフ機能はある
? けど、ダッシュボードなどのビジュアライズはGrafanaなどの
ビジュアライズツールに委任する方針
? PrometheusにアクセスできるNW環境にGrafanaをイン
ストール
? Dockerで用意するのが簡単
# create /var/lib/grafana as persistent volume storage
docker run -d -v /var/lib/grafana --name grafana-storage busybox:latest
# start grafana
docker run 
-d 
-p 3000:3000 
--name=grafana 
--volumes-from grafana-storage 
grafana/grafana
ビジュアライズ表示2
? Data SourceでPrometheusを追加
? グラフでクエリを书けば翱碍
Service Discovery
手動でtaarget設定する
? 新しいサーバー追加するとConfig更新が必要
? バージョンミスマッチ
? サーバーの喪失 scrape_configs:
- job_name: microservice1
target_groups:
- targets: [‘server1:8003’]
- targets: [‘server2:8003’]
- targets: [‘server3:8003’]
- targets: [‘server4:8003’]
- job_name: otherjob
target_groups:
- targets: [‘server3:8086’]
- targets: [‘server4:8087’]
Service Discovery
? DNS
? Consul / Azure / ec2
? ファイル
- job_name: pandora-exporter_nbg1
target_groups:
dns_sd_configs:
consul_sd_configs:
- server: 127.0.0.1:8500
datacenter: nbg1
services:
- pandora-exporter
- job_name: service2-exporter_fra1
target_groups:
dns_sd_configs:
consul_sd_configs:
- server: 127.0.0.1:8500
datacenter: fra1
services:
- service2-exporter
提供されているSD
? azure
? consul
? dns
? ec2
? file
? gce
? kubernetes
? marathon
? openstack
? triton
? zookeeper : nerve_sd_config / serverset_sd_config
relabelling
その1 ラベル何に使うの?
node_load15{instance=“hoge-jp-green",job="node"}
これがラベル
初期設定だと、IPがインスタンスに表示される
ラベルにある項目でしかメトリックスは絞り込めない
ラベルに無いものは使えない
relabeling とは?
Targetsでラベルの上にマウス持っていくと
いろんな情報が表示される
情報もってるのに、フィルターが反応しない!
relabeling とは?
しれっと、Before relabeling と记载されている
relabeling とは?
relabeling って?
https://prometheus.io/docs/operating/configuration/#<relabel_config>
いろんな情報あるけど、
最後には消しちゃうから
必要なものは定義して明示的に残してね
relabeling とは?
__meta_ で始まるラベルは破棄されるので
必要であればrelabellingする
relabeling とは?
結果、こんな定義にしてEC2のタグ名を無事取得
scrape_configs:
- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key:
secret_key:
port: 9100
relabel_configs:
- source_labels: [__meta_ec2_tag_Name]
target_label: instance
Relabellingとは
? Targetのメタデータを取り込み、収集する対象を選択
? 選択すると使用できる
? 既定
? __address__ラベル
? instanceラベル
Service
Discoveryから
Target選択
Configを元に
__param_*ラベルを
設定する
Job、__scheme__、
__metric_path__ラベルが設
定されていない場合は、
configを元に設定する
__addres
s_ラベル
があるか
どうか
Targetを
破棄
relabel_configs
Targetを
破棄
__address_
にポート番
号があるか
どうか
__scheme__がhttpか
空なら80、httpsなら
443を追加
__address_
に/が含ま
れているか
どうか
__meta_から始まる
すべてのラベルを削
除
Instanceラ
ベルがある
かどうか
__address__ラベルを
instanceラベルに
copyする
Targetを
破棄
Targetを作
成
無し
有り
含まれる
含まれ無い
有り
無し
Drop/Keep Action無し
有り
出典:Robust Perception Life of a Label : https://www.robustperception.io/life-of-a-label/
Service Discoveryから
Targetとラベルの生成
対象の選択
? 目的のデータを選択する方法
? 構造が少ない場合は、正規表現
relabel_configs:
- source_labels: ["__meta_consul_tags"]
regex: ".*,production,.*”
action: keep
維持[keep]と破棄[drop]
? もっとも単純なrelabellingの操作
? keepとdrop
? Keep
? 正規表現に合致すると、操作を継続します
? 合致しない場合は、処理を終了し、次の対象に移ります
? Drop
? 正規表現に合致すると処理を終了し、次の対象に移ります
Service
Discoveryから
Target選択
Configを元に
__param_*ラベルを
設定する
Job、__scheme__、
__metric_path__ラベルが設
定されていない場合は、
configを元に設定する
__addres
s_ラベル
があるか
どうか
Targetを
破棄
relabel_configs
Targetを
破棄
__address_
にポート番
号があるか
どうか
__scheme__がhttpか
空なら80、httpsなら
443を追加
__address_
に/が含ま
れているか
どうか
__meta_から始まる
すべてのラベルを削
除
Instanceラ
ベルがある
かどうか
__address__ラベルを
instanceラベルに
copyする
Targetを
破棄
Targetを作
成
無し
有り
含まれる
含まれ無い
有り
無し
Drop/Keep Action
無し
有り
出典:Robust Perception Life of a Label : https://www.robustperception.io/life-of-a-label/
Service Discoveryから
Targetとラベルの生成
2つのラベルに合致させたい場合
? source_labels
? リストで好きなように複数のラベルを指定できる
? 結果
? セミコロンで分割されて連結
? separator
? セパレターを変更できます
? 欠落しているラベルには空文字列が設定される
? relabel_configs
? リストで、好きなように複数のactionを設定できる
? dropかkeepで処理が完了するまで、アクションが適用される
ラベルの変更
? Relabellingのメイン機能は、置換です
? Source_lablesにregexを適用し、合致したものを
replacementで置き換え、target_labelに結果を書き込み
ます
? 空ラベルはラベルが削除されたことを表します
? __metaラベルはrelabellingの後、削除されます
EC2のNameタグをジョブ名にする例
relabel_configs:
- source_labels: ["__meta_ec2_tag_Name"]
regex: "(.*)”
action: replace
replacement: "${1}”
target_label: "job"
デフォルトのものはもっとシンプルに書ける
relabel_configs:
- source_labels: ["__meta_ec2_tag_Name"]
target_label: "job"
インスタンスラベル
? サービスディスカバリー
? __address__にhost:port を格納
? relabellingの終了までに、instanceラベルがない場合
? デフォルトで、__address__の値を設定
? EC2インスタンスIDやZookeeperのパスを設定可能
? 他のラベルを読みやすいインスタンス名として追加は
避ける
その他のラベル
? schema、metrics_path、paramsはデフォルト
? http/httpsかを確認できます
? __param_* ラベル
? 各URLパラメーターの最初の値が含まれる
? 最初の値をrelabelできる
Query
ラベル
{instance=“example1-com-green",job="node"} 0.005
{instance=“example2-com-green",job="node"} 0.005
{instance=“example3-com-green",job="node"} 0.005
node_load1{instance=~"(-hokan-jp|-batch|wh-plus-com|futon-jp|kutsu-jp|-jp)-green"}
/ count by(job, instance)(count by(job, instance, cpu)
(node_cpu{instance=~"(-hokan-jp|-batch|wh-plus-com
|futon-jp|kutsu-jp|-jp)-green"}))
クエリ
node_load1[1m]の[1m]て何?
irate(node_load1{instance=~".*-blue"}[1m])
使い始めぐらいで、こういうクエリを見て
フィーリングでクエリを書き始めてしまえる。あら、素敵。
クエリ書いてて、あれ?てなって、そーいえば[1m]の結果て何が返ってる??
node_load1[1m]の[1m]て何?
Range vector って?
https://prometheus.io/docs/querying/basics/#range-vector-selectors
現在から[ ]で指定した時間前までの
範囲内の値を
すべて返す結果セット
[5m]なら過去5分間
[1h]なら過去1時間
の記録全てを返すという意味
node_load1[1m]の[1m]て何?
Range vector って?
https://prometheus.io/docs/querying/basics/#range-vector-selectors
現在から[ ]で指定した時間前までの
範囲内の値を
すべて返す結果セット
[5m]なら過去5分間
[1h]なら過去1時間
の記録全てを返すという意味
5秒間隔で収集していると、1分範囲にすると約12個結果セットが返ってくる
node_load1[1m]の[1m]て何?
Range vector って?
https://prometheus.io/docs/querying/basics/#range-vector-selectors
現在から[ ]で指定した時間前までの範囲内
データ収集インターバールの指定時間が10秒にしてるときに
[9s]とすると結果セットが1つ、2つとばらける
PromQL
SQL:
SELECT job, instance, method, status, path, rate(value, 5m)
FROM api_http_requests_total
PromQL:
rate(api_http_requests_total[5m])
PromQL
SQL:
SELECT city, AVG(value)
FROM temperature_Celsius
WHERE country=”germany” GROUP BY city
PromQL:
avg by(city) (temperature_celsius{country=”germany”})
PromQL
SQL:
SELECT errors.job, errors.instance, […more labels…],
errors.value / total.value
FROM errors, total
WHERE errors.job=”foo” AND total.job=”foo” JOIN
[…some more complicated stuff here…]
PromQL:
errors{job=”foo”} / total{job=”foo”}
Exporter
Exporter
? 監視するサーバーにexporterという単一バイナリを配置
? daemonとして動かすだけ
1プロセス1Exporter
こっちのほうがデメリットが大きい
?1つのExporterだとボトルネックになりやすい
?単一障害ポイント
?値を選択して配信ができない
?監視が困難
?メタデータの関連付けが難しい
exporterの種類
https://prometheus.io/docs/instrumenting/exporters/
に100以上リストアップされています
exporterのライブラリ
https://prometheus.io/docs/instrumenting/exporters/
で提供されています
Clojure
Go
Java/JVM
Python-Django
node_exporterを利用したカスタムメトリック
/var/log など特定ディレクトリを監視したい場合
-collector.textfile.directory で
/var/lib/node_exporter/textfile_collector.を指定している
その配下にCronなどでファイルを出力するとメトリックを追
加できる
形式:*.promで、指定フォーマットに従う必要がある
骋谤补蹿补苍补连携
Grafanaで項目名を指定する
項目名を明示しないとラベルがそのまま表示される。
{instance=“example.com”,job=“node”}
Grafanaで項目名を指定する
項目名を明示しないとラベルがそのまま表示される。
{instance=“example.com”,job=“node”}
Legend format に {{instance}} のように表示したいラベルのkeyを「{{}}」でくくるといい。
GrafanaのSinglestatsでラベルの値を利用する
Grafana 4.0 以上の利用を推奨
mysql_version_info{innodb_version="5.6.23",
instance=“hoge.jp:9104",job="mysql",
version="5.6.23-log",version_comment="MySQL Community Server (GPL)"}
ラベルの値 をSinglestatで表示する
笔谤辞尘蚕尝のデバッグ
笔谤辞尘蚕尝のデバッグ
ブラウザエクステンション
https://github.com/weaveworks/weavecloud-browser-extension
Alerts
ALERT <alert name>
IF <PromQL vector expression>
FOR <duration>
LABELS { ... }
ANNOTATIONS { ... }
<elem1> <val1>
<elem2> <val2>
<elem3> <val3>
...
結果毎に一つのアラート
ALERT EtcdNoLeader
IF etcd_has_leader == 0
FOR 1m
LABELS {
severity=”page”
}
{job=”etcd”,alertname=”EtcdNoLeader”,severity=”page”,instance=”A”}
{job=”etcd”,alertname=”EtcdNoLeader”,severity=”page”,instance=”B”}
{job=”etcd”,instance=”A”} 0.0
{job=”etcd”,instance=”B”} 0.0
絞り込んだ結果
アラート発火
ALERT HighErrorRate
IF sum rate(request_errors_total[5m])) > 500
{} 534
閾値が絶対値
サービスの成長に伴い閾値の調整が必要になる
ALERT HighErrorRate
IF sum rate(request_errors_total[5m])) > 500
{} 534
ALERT HighErrorRate
IF sum rate(request_errors_total[5m])) > 500
{} 534
ALERT HighErrorRate
IF sum rate(request_errors_total[5m])) > 500
{} 534
ALERT HighErrorRate
IF sum rate(request_errors_total[5m]) /
sum rate(requests_total[5m]) * 100 > 1
{} 1.8354
ALERT HighErrorRate
IF sum rate(request_errors_total[5m]) /
sum rate(requests_total[5m]) * 100 > 1
{} 1.8354
高エラー/低トラフィック
低エラー/高トラフィック
合計
ALERT HighErrorRate
IF sum by(instance, path) rate(request_errors_total[5m]) /
sum by(instance, path) rate(requests_total[5m]) * 100 > 0.01
{instance=”web-2”, path=”/api/comments”} 2.435
{instance=”web-1”, path=”/api/comments”} 1.0055
{instance=”web-2”, path=”/api/profile”} 34.124
アラート発火
ALERT HighErrorRate
IF sum by(instance, path) rate(request_errors_total[5m]) /
sum by(instance, path) rate(requests_total[5m]) * 100 > 0.01
{instance=”web-2”, path=”/api/v1/comments”} 2.435
アラート発火
インスタンス1
インスタンス2~100
ALERT HighErrorRate
IF sum without(instance) rate(request_errors_total[5m]) /
sum without(instance) rate(requests_total[5m]) * 100 > 1
{method=”GET”, path=”/api/v1/comments”} 2.435
{method=”POST”, path=”/api/v1/comments”} 1.0055
{method=”POST”, path=”/api/v1/profile”} 34.124
アラート発火
Alertmanager
Alertmanagerの機能
? 同じアラート群をまとめる
? 誰に送るかルーティングする
? 再送やクローズのコントロール
アラートルール アラートルール アラートルール アラートルール
04:11 hey, HighLatency, service=”X”, zone=”eu-west”, path=/user/profile, method=GET
04:11 hey, HighLatency, service=”X”, zone=”eu-west”, path=/user/settings, method=GET
04:11 hey, HighLatency, service=”X”, zone=”eu-west”, path=/user/settings, method=GET
04:11 hey, HighErrorRate, service=”X”, zone=”eu-west”, path=/user/settings, method=POST
04:12 hey, HighErrorRate, service=”X”, zone=”eu-west”, path=/user/profile, method=GET
04:13 hey, HighLatency, service=”X”, zone=”eu-west”, path=/index, method=POST
04:13 hey, CacheServerSlow, service=”X”, zone=”eu-west”, path=/user/profile, method=POST
. . .
04:15 hey, HighErrorRate, service=”X”, zone=”eu-west”, path=/comments, method=GET
04:15 hey, HighErrorRate, service=”X”, zone=”eu-west”, path=/user/profile, method=POST
アラートルール アラートルール アラートルール アラートルール
Alert Manager
zone eu-west でServiceXで15個のイ
ンシデント発生
3x HighLatency
10x HighErrorRate
2x CacheServerSlow
個々のアラート: ...
Chat
JIRA
PagerDuty
Alertmanagerのアラート群
route:
receiver: infra # default receiver
group_by: ['alertname', 'Service', 'Stage', 'Role']
group_wait: 30s # wait for aggregating alert
group_interval: 5m # wait for alert (next time)
repeat_interval: 3h # wait for alert (re-sending same one)
同じアラート、
同じサービス、
同じステージ、
同じロール
が30秒以内に来たら、同じアラートとみなす
5分毎にアラート発砲する
次回送信されるのは、3時間後
Alertmanagerの送信先
メール?Webhook?Slack?Hipchat?PagerDuty?OpsGenie
{alertname=”DatacenterOnFire”, severity=”huge-page”, zone=”eu-west”}
{alertname=”LatencyHigh”, severity=”page”, ..., zone=”eu-west”}
...
{alertname=”LatencyHigh”, severity=”page”, ..., zone=”eu-west”}
{alertname=”ErrorsHigh”, severity=”page”, ..., zone=”eu-west”}
...
{alertname=”ServiceDown”, severity=”page”, ..., zone=”eu-west”}
アクティブになったら、
同一リージョンのすべてのアラートをミュートにする
macOSのメニューバー
? Line Engineerが書いたBitBarが便利
https://engineering.linecorp.com/ja/blog/detail/147
笔谤辞尘别迟丑别耻蝉入门から运用まで彻底解説
Prometheus
というgoogleのノウハウが組み込まれた
監視ツールのお話しでした
バージョン2の開発が進んでおり、間もなくリリースされる予定
http://sqlazure.jp/r/
コンタクト

More Related Content

笔谤辞尘别迟丑别耻蝉入门から运用まで彻底解説