メトリクスは二度数えられ、ラベルはお金がかかる
一言でいうと
サイドカーは、リクエストごとに標準のメトリクス(istio_requests_total・istio_request_duration_millisecondsなど)を上げ、アクセスログを残します。Telemetry APIは、それをネームスペース・ワークロード単位で変更する仕組みです。ラベルを加え(tagOverrides)、外し(REMOVE)、メトリクスを止め(disabled)、ログを条件で絞ります(filter)。
なぜ必要なのか
メッシュの約束の1つは、「コードを直さなくても、すべてのサービスのリクエスト数・エラー率・レイテンシを同じ形で見られる」ことです。サイドカーがすべてのリクエストを通るので可能です。ところが、そのままにしておくと2つの問題が生じます。
1つ目はコストです。標準メトリクスは、送信元・宛先・レスポンスコード・プロトコルのようなラベルをいくつも付け、レイテンシのヒストグラムはバケットごとに時系列ができます。サービスが数百あれば、Prometheusが先に音を上げます。2つ目は不足です。「どの顧客(tenant)のリクエストか」のような、業務に必要なディメンションは、標準ラベルにありません。
Telemetry APIは、この2つを1つの設定で扱います。メッシュ全体(istio-system)、ネームスペース、ワークロードセレクターの順に絞って適用できます。
どう動くのか
メトリクスは2回カウントされます。サイドカーモードでは、リクエスト1つを、送信側のサイドカー(reporter="source")と受信側のサイドカー(reporter="destination")がそれぞれ数えます。両方がメッシュの中なら、同じ数が2回積み上がるので、合計を出すときは、reporterを1つに固定する必要があります。受信側(destination)の基準が、普通は「サービスが受け取ったリクエスト」に近くなります。
Prometheusはスクレイプしに来ます。ディストリビューションのPrometheusアドオンは、Podのアノテーションを見て、サイドカーのマージ済みメトリクスのポートを定期的に(この設定では15秒)スクレイプします。そのため、リクエストを送ってから1周期ほど後に、クエリの結果に現れます。サイドカーが今持っている値は、pilot-agent request GET stats/prometheusですぐに見られます。
Telemetryで変更できるもの
| 設定 | 役割 |
|---|---|
tagOverrides: {tenant: {value: "request.headers['x-tenant']"}} |
リクエスト属性から新しいラベルを作る |
tagOverrides: {request_protocol: {operation: REMOVE}} |
標準ラベルを外す |
match: {metric: REQUEST_DURATION}, disabled: true |
そのメトリクスを作らない |
accessLogging: [{filter: {expression: "response.code >= 400"}}] |
条件に合うリクエストだけログを残す |
ラベルの値が際限なく増えるもの(ユーザーID・リクエストID)をラベルにすると、時系列が爆発します。ラベルを加えるときは、値の種類の数をまず考えます。そしてカウンターは消えないので、設定を変えた効果は、新しくできる時系列でしか見えません。
PromQLで比率を出します。エラー率はsum(5xx) / sum(전체)です(プレースホルダーは全体の件数です)。運用のダッシュボードはrate(…[5m])で直近の期間の比率を見ますが、リクエストが少ない実験では、カウンター同士を割っても構いません。どちらの場合も、分子と分母が同じreporter・同じ宛先を指す必要があります。
現場での姿
ダッシュボードのリクエスト数がロードバランサーの2倍の場合です。reporterで絞らずに足しています。
tenantラベルを付けたらPrometheusのメモリが跳ね上がった場合です。顧客が数万いました。ラベルではなく、ログやトレースで見るべきディメンションです。
アクセスログを減らしたら障害分析が難しくなった場合です。エラーだけを残すと、「正常だったリクエストがいつから遅くなったか」が見えません。条件式にレイテンシ(response.duration)を一緒に入れることが多いです。
公式ドキュメント: Telemetry API・Customizing Istio Metrics・Istio Standard Metrics・Envoy Access Logs・Prometheus addon
次のラボですること
ディストリビューションのPrometheusアドオンが一緒に載ったメッシュで、リクエストを流してistio_requests_totalをHTTP APIで尋ね、同じリクエストがsource・destinationとして2回カウントされるのを見ます。Telemetry APIでtenantラベルを加え、使わないラベルを外し、レイテンシのメトリクスを止め、アクセスログをエラーだけ残すように絞った後、最後に、エラー率をPromQL 1行で出します。