接尾辞とコロンは規約ではなく契約だ
一言でいうと
Prometheusのメトリクス名のルールは好みではなく、ツールが依存する契約です。_totalはカウンターという宣言で、_bucket・_sum・_countはヒストグラムの3つの構成要素であり、コロンはレコーディングルールにだけ許可されます。名前を見ただけで何なのかがわかってこそ、ダッシュボードとアラートが互いを信頼できます。
なぜ必要なのか
型を間違えると、あとからやりたい計算が原理的に不可能になります。最もよくある事故は、レイテンシをゲージとして記録することです。
last_latency = Gauge("http_request_duration_seconds", "요청 처리 시간")
last_latency.set(elapsed) # 앞선 값들은 전부 사라진다
スクレイプ間隔が15秒で毎秒のリクエストが500件なら、7,500件のうち1件の値だけが保存されます。残りは、存在したことすらないことになります。この時系列ではp99を求められず、あとでデータを再処理しても復元されません。
どう動くのか
エクスポジション形式は、人が読めるテキストです。1行にメトリクス名、波括弧の中のラベル、値が入り、# HELPと# TYPEのコメントが付きます。標準の経路は/metricsで、別の経路を使うなら、スクレイプ設定でmetrics_pathを指定する必要があります。OpenMetricsはこの形式を標準化したもので、exemplarとcreated timestampを追加しました。
4つの型
| 型 | 公開される時系列 | 答える質問 |
|---|---|---|
| Counter | x_total |
毎秒どれだけ増えるか(rateが必要) |
| Gauge | x |
今の値がいくつか |
| Histogram | x_bucket{le}、x_sum、x_count |
分布がどうか(サーバーで分位数を推定) |
| Summary | x{quantile}、x_sum、x_count |
このプロセスの中での分位数 |
Summaryがサービスレベルで役に立たない理由は、前のモジュールで扱った性質1つのためです。分位数は合算できません。Summaryは、クライアントがすでに計算してしまった分位数を出力するので、Pod40個のp99を1つにまとめる方法がありません。Histogramは、精度をバケットの解像度の分だけ手放す代わりに、集計可能性を得ます。分散システムでは、ほとんどの場合、後者が正しい取引です。
どこから出るメトリクスかも、試験の常連です。
node_cpu_seconds_total: Node Exporter(ホストのハードウェア・OS)container_cpu_usage_seconds_total: cAdvisor(kubeletに内蔵、コンテナのリソース)kube_deployment_spec_replicas: kube-state-metrics(APIオブジェクトの状態)process_cpu_seconds_total: クライアントライブラリが自動で付けるプロセスメトリクスprobe_success: Blackbox Exporter(HTTP・TCP・DNSのプローブ)
レコーディングルールは、計算をクエリの時点から評価の時点に移します。作る基準は4つです。同じ式が3か所以上で繰り返されるとき、クエリが2秒を超えるとき、アラートが重い式を評価のたびに実行するとき、高カーディナリティの元データを集計して長く保管したいとき。
名前は、수준:메트릭:연산(プレースホルダーはレベル、メトリクス、演算です)の規約に従います。route:http_requests:rate5mを見れば、ルートレベルで集計されたリクエスト数の5分のrateだということが、名前だけで読み取れます。コロンは元のメトリクス名には絶対に使わないため、名前を見ただけで「これは派生した時系列だ」とわかります。
階層構造が核心です。階層1が元データを一度スキャンしておけば、階層2はその結果だけを参照するので、元データのスキャンが1回で済みます。ただし、グループの中では上から下へ評価されるので、階層1が階層2より上にある必要があります。
現場での姿
レコーディングルール2,000個を一度に入れて、約100万の時系列が生まれ、WALが急増したことがあります。デプロイ前の計算は簡単です。ルートが120個あり、ウィンドウ5種類それぞれについてルールを作ると600個、ルールが50個なら3万個です。ルールファイルはコードのようにレビューしますが、コストは新しいメトリクスと同じです。
検証はCIで行います。promtool check rulesで文法を、promtool test rulesで期待値を確認します。特に、単体テストに期待値を自分で計算して書いておけば、あとで誰かがルールを「最適化」して意味を変えてしまったとき、CIが見つけてくれます。promtoolが見つけられないものもあります。ルール同士の循環参照は、人がレビューで見る必要があります。
次のラボですること
/root/pca-rules/の下に、レコーディングルールのファイルとアラートルールのファイルを書き、level:metric:operationsの命名で2段の階層を作ります。そのあと、promtoolの単体テストファイルに入力の時系列と期待値を自分で計算して入れ、最後に、同じ内容をPrometheus Operatorが読むPrometheusRule CRに移します。