Kubernetes アップストリーム SLOs - Amazon EKS

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Kubernetes アップストリーム SLOs

Amazon EKS はアップストリーム Kubernetes リリースと同じコードを実行し、EKS クラスターが Kubernetes コミュニティで定義された SLOs 内で動作するようにします。Kubernetes Scalability Special Interest Group (SIG) は、スケーラビリティの目標を定義し、SLIs と SLOs。

SLIs は、システムの実行状況を判断するために使用できるメトリクスやメジャーなどのシステムを測定する方法です。例えば、リクエストのレイテンシーやカウントなどです。SLOs「well」を実行しているときに予想される値を定義します。たとえば、リクエストのレイテンシーは 3 秒未満のままです。Kubernetes SLOs と SLIs は Kubernetes コンポーネントのパフォーマンスに焦点を当て、EKS クラスターエンドポイントの可用性に焦点を当てる Amazon EKS Service SLAs とは完全に独立しています。

Kubernetes には、CSI ドライバー、アドミッションウェブフック、自動スケーラーなどのカスタムアドオンまたはドライバーを使用してシステムを拡張できる多くの機能があります。これらの拡張機能は、さまざまな方法で Kubernetes クラスターのパフォーマンスに大きな影響を与える可能性があります。つまり、 を使用するアドミッションウェブフックは、ウェブフックターゲットが使用できない場合に K8s API リクエストにレイテンシーを追加するfailurePolicy=Ignore可能性があります。Kubernetes Scalability SIG は、「お約束します」フレームワークを使用してスケーラビリティを定義します。

Kubernetes SLOs

Kubernetes SLOs は、ワーカーノードのスケーリングやアドミッションウェブフックなど、クラスターに影響を与える可能性のあるプラグインや外部の制限をすべて考慮しているわけではありません。これらの SLOs Kubernetes コンポーネントに焦点を当て、Kubernetes アクションとリソースが期待どおりに動作していることを確認します。SLOsKubernetes 開発者が Kubernetes コードを変更してもシステム全体のパフォーマンスが低下しないようにするのに役立ちます。

Kuberntes Scalability SIG では、以下の公式 SLO/SLIsを定義します。Amazon EKS チームは、これらの SLOs/SLIs の EKS クラスターでスケーラビリティテストを定期的に実行し、変更が行われ、新しいバージョンがリリースされるとパフォーマンスが低下するかどうかをモニタリングします。

目的 定義 SLO

API リクエストのレイテンシー (変更)

過去 5 分間の 99 パーセンタイルとして測定される、すべての (リソース、動詞) ペアの単一オブジェクトに対する変更 API コールの処理のレイテンシー

デフォルトの Kubernetes インストールでは、仮想リソースと集計リソースおよびカスタムリソース定義を除くすべての (リソース、動詞) ペアについて、クラスター日あたり 99 パーセンタイル <= 1

API リクエストのレイテンシー (読み取り専用)

すべての (リソース、スコープ) ペアの非ストリーミング読み取り専用 API コールを処理するレイテンシー。過去 5 分間の 99 パーセンタイルとして測定されます。

デフォルトの Kubernetes インストールでは、仮想リソースと集計リソースおよびカスタムリソース定義を除くすべての (リソース、スコープ) ペアについて、クラスター日あたり 99 パーセンタイル: (a) <= scope=resource (b) <= 30s それ以外の場合は 1s ( scope=namespaceまたは の場合scope=cluster

ポッドの起動レイテンシー

スケジュール可能なステートレスポッドの起動レイテンシー。ただし、イメージをプルして init コンテナを実行する時間は除外され、ポッド作成のタイムスタンプから、すべてのコンテナが開始として報告され、Watch を介して観測されるまでの時間、過去 5 分間の 99 パーセンタイルとして測定されます。

デフォルトの Kubernetes インストールでは、クラスター日あたり 99 パーセンタイル <= 5s

API リクエストのレイテンシー

kube-apiserver1m0sデフォルトで と--request-timeout定義されています。つまり、リクエストはタイムアウトしてキャンセルされる前に最大 1 分 (60 秒) 実行できます。レイテンシー用に定義された SLOs は、変更または読み取り専用のリクエストのタイプによって分類されます。

変異

Kubernetes でリクエストをミューテーションすると、作成、削除、更新など、リソースが変更されます。これらのリクエストは、更新されたオブジェクトが返される前に etcd バックエンドに書き込む必要があるため、コストがかかります。Etcd は、すべての Kubernetes クラスターデータに使用される分散キーバリューストアです。

このレイテンシーは、Kubernetes リソースの (リソース、動詞) ペアの 5 分間で 99 パーセンタイルとして測定されます。たとえば、これにより、ポッドの作成リクエストとノードの更新リクエストのレイテンシーが測定されます。SLO を満たすには、リクエストのレイテンシーが <= 1 秒である必要があります。

[Read-only]

読み取り専用リクエストは、単一のリソース (ポッド X の取得など) またはコレクション (「名前空間 X からすべてのポッドを取得する」など) を取得します。はオブジェクトのキャッシュkube-apiserverを保持するため、リクエストされたリソースはキャッシュから返されるか、最初に etcd から取得する必要がある場合があります。これらのレイテンシーも 5 分間で 99 パーセンタイルで測定されますが、読み取り専用リクエストには個別のスコープを含めることができます。SLO は 2 つの異なる目標を定義します。

  • 単一のリソース ( など) kubectl get pod -n mynamespace my-controller-xxx に対して行われたリクエストの場合、リクエストのレイテンシーは <= 1 秒のままにする必要があります。

  • 名前空間またはクラスター ( などkubectl get pods -A) 内の複数のリソースに対して行われたリクエストの場合、レイテンシーは <= 30 秒のままにする必要があります

Kubernetes リソースのリストに対して行われたリクエストは、リクエスト内のすべてのオブジェクトの詳細が SLO 内で返されることを想定しているため、SLO にはリクエストスコープごとに異なるターゲット値があります。大規模なクラスターや大量のリソースコレクションでは、レスポンスサイズが大きくなり、返すまでに時間がかかる場合があります。例えば、JSON でエンコードされた各ポッドが約 1 KiB である数万個のポッドを実行しているクラスターでは、クラスター内のすべてのポッドを返すと 10MB 以上になります。Kubernetes クライアントは、APIListChunking を使用してリソースの大規模なコレクションを取得することで、このレスポンスサイズを減らすのに役立ちます。

ポッドの起動レイテンシー

この SLO は主に、Pod の作成からその Pod 内のコンテナが実際に実行を開始するまでの時間に関係します。これを測定するために、Pod に記録された作成タイムスタンプとの差を測定し、その Pod の WATCH がコンテナの開始をレポートすると、コンテナが計算されます (コンテナイメージのプル時間と初期化コンテナの実行時間を除く)。SLO を満たすには、このポッド起動レイテンシーのクラスター日あたりの 99 パーセンタイルが <=5 秒のままである必要があります。

この SLO は、ワーカーノードがこのクラスターに既に存在しており、ポッドをスケジュールする準備が整っていることを前提としていることに注意してください。この SLO は、イメージのプルや初期化コンテナの実行を考慮しておらず、永続的ストレージプラグインを活用しない「ステートレスポッド」にテストを制限します。

Kubernetes SLI メトリクス

Kubernetes は、これらの SLIs を経時的に追跡する Kubernetes コンポーネントに Prometheus メトリクスを追加することでSLIs に関するオブザーバビリティも改善しています。Prometheus クエリ言語 (PromQL) を使用すると、Prometheus や Grafana ダッシュボードなどのツールで SLI パフォーマンスを経時的に表示するクエリを構築できます。以下に、上記の SLOs の例をいくつか示します。

API サーバーリクエストのレイテンシー

メトリクス 定義

apiserver_request_sli_duration_seconds

動詞、グループ、バージョン、リソース、サブリソース、スコープ、コンポーネントごとのレスポンスレイテンシー分布 (ウェブフック期間、優先度と公平性キューの待機時間はカウントされません)。

apiserver_request_duration_seconds

verb、dry run 値、グループ、バージョン、リソース、サブリソース、スコープ、コンポーネントごとの、秒単位の応答遅延分布。

注: apiserver_request_sli_duration_secondsメトリクスは Kubernetes 1.27 以降で使用できます。

これらのメトリクスを使用して、API Server の応答時間と、Kubernetes コンポーネントや他のプラグイン/コンポーネントにボトルネックがあるかどうかを調査できます。以下のクエリは、コミュニティ SLO ダッシュボードに基づいています。

API リクエストレイテンシー SLI (変更) - 今回は、ウェブフックの実行やキューでの待機時間は含まれませんhistogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

API リクエストレイテンシー合計 (変更) - これはリクエストが API サーバーにかかった合計時間であり、ウェブフック実行と API Priority and Fairness 待機時間が含まれているため、この時間は SLI 時間よりも長くなる可能性があります。 histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

これらのクエリでは、 kubectl port-forwardまたは リクエスト (subresource!~"proxy|attach|log|exec|portforward") など、すぐに返されないストリーミング API kubectl execリクエストを除外し、オブジェクトを変更する Kubernetes 動詞 () のみをフィルタリングしますverb=~"CREATE|DELETE|PATCH|POST|PUT"。次に、過去 5 分間のレイテンシーの 99 パーセンタイルを計算します。

読み取り専用 API リクエストに同様のクエリを使用できます。フィルタリングする動詞を変更して、読み取り専用アクション LISTと を含めるだけですGET。1 つのリソースの取得や多数のリソースの一覧表示など、リクエストの範囲に応じて異なる SLO しきい値もあります。

API リクエストレイテンシー SLI (読み取り専用) - 今回は、ウェブフックの実行やキューでの待機時間は含まれません。単一のリソースの場合 (scope=resource、 threshold=1s) histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

同じ名前空間内のリソースのコレクションの場合 (scope=namespace、 threshold=5s) histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

クラスター全体のリソースのコレクションの場合 (スコープ = クラスター、しきい値 = 30 秒) histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

API リクエストレイテンシー合計 (読み取り専用) - これはリクエストが API サーバーにかかった合計時間であり、ウェブフックの実行と待機時間が含まれているため、この時間は SLI 時間よりも長くなる可能性があります。単一のリソースの場合 (scope=resource、 threshold=1s) histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

同じ名前空間内のリソースのコレクション (scope=namespace、 threshold=5s) histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

クラスター全体のリソースのコレクションの場合 (スコープ = クラスター、しきい値 = 30 秒) histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

SLI メトリクスは、リクエストが API Priority and Fairness キューで待機したり、アドミッションウェブフックやその他の Kubernetes 拡張機能を使用したりする時間を除外することで、Kubernetes コンポーネントのパフォーマンスに関するインサイトを提供します。合計メトリクスは、アプリケーションが API サーバーからのレスポンスを待っている時間を反映するため、より包括的なビューを提供します。これらのメトリクスを比較すると、リクエスト処理の遅延が発生する場所を把握できます。

ポッドの起動レイテンシー

メトリクス 定義

kubelet_pod_start_sli_duration_seconds

ポッドを起動する秒単位の期間。イメージをプルして init コンテナを実行する時間は除きます。これは、ポッド作成タイムスタンプから、そのすべてのコンテナが開始済みとして報告され、Watch を介して観測された時点まで測定されます。

kubelet_pod_start_duration_seconds

kubelet がポッドを初めて確認してからポッドの実行が開始されるまでの秒単位の期間。これには、ポッドをスケジュールしたり、ワーカーノード容量をスケールアウトしたりする時間は含まれません。

注: kubelet_pod_start_sli_duration_secondsは Kubernetes 1.27 以降で使用できます。

上記のクエリと同様に、これらのメトリクスを使用して、ノードスケーリング、イメージプル、初期化コンテナが Kubelet アクションと比較してポッドの起動を遅らせている時間を把握できます。

ポッドの起動レイテンシー SLI - これは、ポッドが作成されてからアプリケーションコンテナが実行中と報告されるまでの時間です。これには、ワーカーノードの容量が利用可能になり、ポッドがスケジュールされるまでにかかる時間が含まれますが、イメージのプルや init コンテナの実行にかかる時間は含まれません。 histogram_quantile(0.99, sum(rate(kubelet_pod_start_sli_duration_seconds_bucket[5m])) by (le))

ポッドの起動レイテンシー合計 - これは、kubelet がポッドを初めて起動するのにかかる時間です。これは、kubelet が WATCH 経由でポッドを受信したときから測定されます。これには、ワーカーノードのスケーリングまたはスケジューリングの時間は含まれません。これには、実行するイメージと初期化コンテナをプルする時間が含まれます。 histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))

クラスターSLOs

EKS クラスターの Kubernetes リソースから Prometheus メトリクスを収集している場合は、Kubernetes コントロールプレーンコンポーネントのパフォーマンスに関するより深いインサイトを得ることができます。

パフォーマンステストリポジトリには、テスト中のクラスターのレイテンシーと重要なパフォーマンスメトリクスを表示する Grafana ダッシュボードが含まれています。perf-tests 設定は、Kubernetes メトリクスを収集するように設定されたオープンソースプロジェクトである kube-prometheus-stack を活用しますが、Amazon Managed Prometheus と Amazon Managed Grafana を使用することもできます。

kube-prometheus-stack または同様の Prometheus ソリューションを使用している場合は、同じダッシュボードをインストールしてクラスターの SLOs をリアルタイムで監視できます。

  1. まず、 でダッシュボードで使用される Prometheus ルールをインストールする必要がありますkubectl apply -f prometheus-rules.yaml。ルールのコピーは、https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/prometheus-rules.yaml からダウンロードできます。

    1. ファイルの名前空間が環境と一致することを確認してください。

    2. を使用している場合は、ラベルが prometheus.prometheusSpec.ruleSelector helm 値と一致することを確認します。 kube-prometheus-stack

  2. その後、Grafana にダッシュボードをインストールできます。生成する JSON ダッシュボードと Python スクリプトは、https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards から入手できます。

    1. slo.json ダッシュボードには、Kubernetes SLOs

SLOs はクラスター内の Kubernetes コンポーネントのパフォーマンスに焦点を当てていますが、クラスターにさまざまな視点やインサイトを提供する追加のメトリクスを確認できます。Kube-state-metrics などの Kubernetes コミュニティプロジェクトは、クラスターの傾向をすばやく分析するのに役立ちます。Kubernetes コミュニティの一般的なプラグインやドライバーは、Prometheus メトリクスも出力するため、オートスケーラーやカスタムスケジューラなどを調査することができます。

オブザーバビリティのベストプラクティスガイドには、さらなるインサイトを得るために使用できる他の Kubernetes メトリクスの例が記載されています。