TT Lab
はじめる
学ぶ 学習パス コース

Istio 実測ラボ

メトリクスは二度数えられ、ラベルはお金がかかる

TT Labで続きを見る

一言でいうと

サイドカーは、リクエストごとに標準のメトリクス(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行で出します。