サービスレベル指標を用いたパフォーマンス監視

サービスレベル指標(SLI)とサービスレベル目標(SLO)を用いて、ユーザーが認識するパフォーマンスと信頼性を追跡します。

サービスレベル指標(SLI)とサービスレベル目標(SLO)は、本番環境におけるKeycloakのパフォーマンスと信頼性を監視および維持する上で不可欠な要素です。

Googleのサイト信頼性エンジニアリングの書籍では、これを次のように定義しています。

  • サービスレベル指標(SLI)とは、提供されるサービスレベルの側面を注意深く定義した定量的な尺度です。

  • サービスレベル目標(SLO)とは、SLIによって測定されるサービスレベルの目標値または値の範囲です。

これらをステークホルダーと合意し、追跡することで、サービスオーナーは、デプロイメントがユーザーの期待に沿っていること、および提供するサービスに対して過剰または過少に提供しないことを保証できます。

前提条件

  • Keycloakでメトリクスを有効にする必要があり、以下に定義するSLOを測定するには、http-metrics-slosオプションをレイテンシに設定する必要があります。詳細については、メトリクスによる洞察の獲得ガイドに従ってください。

  • メトリクスを収集する監視システム。以下の段落では、PromQLクエリ言語をサポートするPrometheusまたは同様のシステムが使用されていることを前提としています。

提供されるサービスの定義

以下のサービス定義は、適切なSLIとSLOを特定するための次のステップで使用されます。これは、ユーザーによって観察される動作を捉える必要があります。

Keycloakユーザーとして、

  • ログインできるようにしたい、

  • トークンを更新し、

  • ログアウトし、

Keycloakを認証に使用するアプリケーションを使用できるようにするため。

SLIとSLOの定義

以下は、上記のサービス記述とKeycloakで利用可能なメトリクスに基づいて、SLIとSLOの例を示します。

これらのSLOはシステムの実際の負荷とは独立していますが、これは、単一のユーザーが応答が遅い場合にシステム負荷を気にしないため、予想されることです。

同時に、ステークホルダーとサービスレベル契約(SLA)を締結する場合、Keycloakを実行する担当者は、Keycloakが受信するトラフィックの制限を定義することに関心を持つ必要があります。システムの負荷が増加し、スケーリングのしきい値に達すると、応答時間が長くなり、エラー率が上昇する可能性があるためです。

特性 サービスレベル指標 サービスレベル目標* メトリクスソース

可用性

監視システムによって測定された、Keycloakがリクエストに応答できる時間の割合

Keycloakは、1ヶ月のうち99.9%の時間(1ヶ月あたり44分の停止時間)利用可能である必要があります。

PrometheusサーバーがKeycloakインスタンスからメトリクスをスクレイピングできるかどうかを示すPrometheusのupメトリクスを使用します。

レイテンシ

サーバーによって測定された、認証関連のHTTPリクエストの応答時間

すべての認証関連リクエストの95%は、5分間の範囲内で250ミリ秒より速くする必要があります。

特定のエンドポイントのレイテンシを追跡するためのKeycloakサーバー側のメトリクスと、http_server_requests_seconds_bucketおよびhttp_server_requests_seconds_countを使用した応答時間分布。

エラー

サーバーによって測定された、サーバーの問題による認証リクエストの失敗

認証リクエストに対するサーバーの問題によるエラー率は、5分間の範囲内で0.1%未満である必要があります。

タグoutcomeの値がSERVER_ERRORであるhttp_server_requests_seconds_countメトリクスをフィルタリングして、サーバー側のエラーを特定します。

* これらのSLO目標値は例であり、ユースケースとデプロイメントに合わせて調整する必要があります。

PromQLクエリ

これらはKubernetes環境で作成されたクエリの例であり、監視ツールとしてPrometheusで使用されます。これらはブループリントとして提供されており、別のランタイムまたは監視環境に合わせて調整する必要があります。

本番環境では、アラートまたはライブダッシュボードに使用する場合にリソースを過度に使用しないように、これらのクエリまたはサブクエリを記録ルールに置き換えることをお勧めします。

可用性

Keycloakインスタンスが利用可能でPrometheusスクレイピングリクエストに応答している場合、このメトリクスは少なくとも1の値を持ち、サービスがダウンしているか、または到達不能な場合は0になります。

次に、Grafanaのようなツールを使用して30日間の時間範囲を表示し、その時間枠内のメトリクスの平均を計算させます。

count_over_time(
  sum (up{
    container="keycloak", (1)
    namespace="$namespace"
  } > 0)[30d:15s]
) (2)
/
count_over_time(vector(1)[30d:15s]) (3)
1 追加のタグでフィルタリングして、Keycloakノードを識別します。
2 少なくとも1つのKeycloakノードが利用可能だった場合、指定された範囲と間隔内のすべてのデータポイントをカウントします。
3 同じ範囲と間隔内のすべてのデータポイントの数で割ります。
Grafanaでは、ダッシュボードで選択した時間範囲で可用性SLIを計算するために、値30d:15s$__range:$__intervalに置き換えることができます。

認証リクエストのレイテンシ

このPrometheusクエリは、特定のKeycloakエンドポイントに対するすべての認証リクエストに対する、過去5分間の特定の名前空間とポッドをターゲットとする、0.25秒以内に完了した認証リクエストの割合を計算します。

この例では、250ミリ秒より速いリクエストと遅いリクエストのバケットを記録する必要があることを示す値250http-metrics-slosのKeycloak構成に含める必要があります。http-metrics-histograms-enabledtrueに設定すると、パフォーマンスのトラブルシューティングに役立つ追加のバケットをキャプチャできます。

sum(
  rate(
    http_server_requests_seconds_bucket{
      uri=~"/realms/{realm}/protocol/{protocol}.*|/realms/{realm}/login-actions.*", (1)
      le="0.25", (2)
      container="keycloak", (3)
      namespace="$namespace"}
    [5m] (4)
  )
) without (le,uri,status,outcome,method,pod,instance) (5)
/
sum(
  rate(
    http_server_requests_seconds_count{
      uri=~"/realms/{realm}/protocol/{protocol}.*|/realms/{realm}/login-actions.*", (1)
      container="keycloak",
      namespace="$namespace"}
    [5m] (3)
  )
) without (le,uri,status,outcome,method,pod,instance) (5)
1 ログインに関連するURL
2 SLOで定義された応答時間
3 追加のタグでフィルタリングして、Keycloakノードを識別します。
4 SLOで指定された時間範囲
5 単一の合計を作成するために必要なだけラベルを無視します。
Grafanaでは、ダッシュボードで選択した時間範囲でレイテンシSLIを計算するために、値5m$__rangeに置き換えることができます。

認証リクエストのエラー

このPrometheusクエリは、過去5分間に特定の名前空間をターゲットとする、すべての認証リクエストに対するサーバー側のエラーを返した認証リクエストの割合を計算します。

sum(
  rate(
    http_server_requests_seconds_count{
      uri=~"/realms/{realm}/protocol/{protocol}.*|/realms/{realm}/login-actions.*", (1)
      outcome="SERVER_ERROR", (2)
      container="keycloak", (3)
      namespace="$namespace"}
    [5m] (4)
  )
) without (le,uri,status,outcome,method,pod,instance) (5)
/
sum(
  rate(
    http_server_requests_seconds_count{
      uri=~"/realms/{realm}/protocol/{protocol}.*|/realms/{realm}/login-actions.*", (1)
      container="keycloak", (3)
      namespace="$namespace"}
    [5m] (4)
  )
) without (le,uri,status,outcome,method,pod,instance) (5)
1 ログインに関連するURL
2 サーバーエラー(HTTPステータス5xx)で応答したすべてのリクエストをフィルタリングします。
3 追加のタグでフィルタリングして、Keycloakノードを識別します。
4 SLOで指定された時間範囲
5 単一の合計を作成するために必要なだけラベルを無視します。
このページについて