Azure Kubernetes Service (AKS) での大規模なワークロードのパフォーマンスとスケーリングに関するベスト プラクティス

Note

この記事では、大規模なワークロードに関する一般的なベスト プラクティスに焦点を当てます。 小規模から中規模のワークロードに固有のベスト プラクティスについては、Azure Kubernetes Service (AKS) での中小規模のワークロードのパフォーマンスとスケーリングのベスト プラクティスに関する記事をご覧ください。

AKS でクラスターをデプロイして管理するときは、次のベスト プラクティスを使って、パフォーマンスとスケーリングを最適化できます。

"大規模" とは相対的な用語であることに注意してください。 Kubernetes には多次元のスケール エンベロープがあり、ワークロードのスケール エンベロープは使用するリソースによって異なります。 たとえば、100 個のノードと数千個のポッドまたは CRD を含むクラスターは、大規模と見なされるかもしれません。 1,000 個のポッドと他のさまざまなリソースを含む 1,000 ノードのクラスターは、コントロール プレーンの観点からは小規模と見なされる可能性があります。 Kubernetes コントロール プレーンのスケールの最もよい判断基準は、API サーバーの HTTP 要求の成功率と待ち時間です。これは、コントロール プレーンでの負荷量の代わりになるものです。

この記事では、次の内容について説明します。

  • AKS と Kubernetes コントロール プレーンのスケーラビリティ。
  • バックオフ、監視、改ページなど、Kubernetes クライアントのベスト プラクティス。
  • Azure API とプラットフォームのスロットリングの制限。
  • 機能の制限。
  • ネットワークとノード プールのスケーリングのベスト プラクティス。

AKS と Kubernetes コントロール プレーンのスケーラビリティ

AKS での "クラスター" は、Kubernetes エージェントを実行し、AKS でホストされる Kubernetes コントロール プレーンによって管理されする、一連のノード (物理マシンまたは仮想マシン (VM)) で構成されます。 AKS は、スケーラビリティとパフォーマンスに関して Kubernetes コントロール プレーンとそのコンポーネントを最適化しますが、それでもアップストリーム プロジェクトの制限による制約を受けます。

Kubernetes には多次元のスケール エンベロープがあり、各リソースの種類が 1 つの次元を表します。 すべてのリソースが似ているわけではありません。 たとえば、"監視" はシークレットに対して一般に設定され、その結果、kube-apiserver への list 呼び出しが発生してコストが増え、監視のないリソースと比較してコントロール プレーンの負荷が不釣り合いに高くなります。

コントロール プレーンはクラスター内のすべてのリソースのスケーリングを管理するため、特定の次元内でのクラスターのスケーリングが増えるほど、他の次元内でのスケーリングは減ります。 たとえば、AKS クラスターで数十万個のポッドを実行すると、コントロール プレーンでサポートできるポッドのチャーン (1 秒間にポッドが変化する回数) の量に影響します。

エンベロープのサイズは、Kubernetes コントロール プレーンのサイズに比例します。 AKS では、Base SKU の一部として、Free レベル、Standard レベル、Premium レベルという 3 つのコントロール プレーン レベルがサポートされています。 詳しくは、AKS クラスター管理での Free、Standard、Premium の価格レベルに関する記事をご覧ください。

重要

運用環境または大規模なワークロードには、Standard または Premium レベルを使うことを強くお勧めします。 AKS では、次のスケール制限に対応するために、Kubernetes コントロール プレーンが自動的にスケールアップされます。

  • AKS クラスターあたり最大 5,000 ノード
  • AKS クラスターあたり 200,000 ポッド (Azure CNI オーバーレイを使用)

ほとんどの場合、スケール制限のしきい値を超えるとパフォーマンスが低下しますが、クラスターがすぐにフェールオーバーすることはありません。 Kubernetes コントロール プレーンでの負荷を管理するには、現在のスケールの最大 10% から 20% のスケーリングをバッチで行うことを検討してください。 たとえば、5,000 ノードのクラスターの場合は、500 から 1,000 ノードの増分でスケーリングします。 AKS はコントロール プレーンを自動スケーリングしますが、すぐには行われません。

API の優先順位と公平性 (APF) を利用して、特定のクライアントと要求の種類をスロットルし、高いチャーンと負荷の間にコントロール プレーンを保護できます。

Kubernetes クライアント

Kubernetes クライアントは、Kubernetes クラスターにデプロイされたオペレーターや監視エージェントなどのアプリケーション クライアントであり、読み取りまたは変更操作を実行するために kube-api サーバーと通信する必要があります。 これらのクライアントの動作を最適化して、kube-api サーバーと Kubernetes コントロール プレーンに加わる負荷を最小限に抑えることが重要です。

Kube 監査ログを使用し、API サーバーのトラフィックとクライアントの動作を分析できます。 詳しくは、Kubernetes コントロール プレーンのトラブルシューティングに関する記事をご覧ください。

LIST 要求はコストがかかる場合があります。 数千を超える小さなオブジェクトまたは数百を超える大きなオブジェクトを含むリストを操作するときは、次のガイドラインを考慮する必要があります。

  • 新しいリソースの種類 (CRD) を定義するときに、最終的に存在することが予想されるオブジェクト (CR) の数を検討します
  • etcd と API サーバーにかかる負荷は、主に、返されるオブジェクトの数ではなく、存在するオブジェクトの数に依存します。 フィールド セレクターを使ってリストをフィルター処理し、少数の結果のみを取得するようにした場合でも、これらのガイドラインは引き続き当てはまります。 唯一の例外は、metadata.name による単一のオブジェクトの取得です。
  • コードでオブジェクトの更新されるリストをメモリに維持する必要がある場合は、可能な限り LIST を繰り返し呼び出さないようにします。 代わりに、ほとんどの Kubernetes ライブラリで提供されている Informer クラスを使うことを検討します。 Informer は、LIST と WATCH の機能を自動的に組み合わせて、メモリ内のコレクションを効率的に維持します。
  • Informer でニーズを満たせない場合は、厳密な整合性が必要かどうかを検討します。 クエリを発行した正確な時点までの、最新のデータを見る必要がありますか。 そうでない場合は、ResourceVersion=0 を設定します。 このようにすると、etcd ではなく API サーバー キャッシュが要求を処理します。
  • Informer または API サーバー キャッシュを使用できない場合は、大きなリストをチャンクで読み取ります
  • 必要以上に頻繁にリストを操作しないようにします。 Informer を使用できない場合は、アプリケーションでリソースのリストを作成する頻度を検討します。 大きなリストの最後のオブジェクトを読み取った後は、すぐに同じリストのクエリを再実行しないでください。 そうせずに、しばらく待つ必要があります。
  • クライアント アプリケーションの実行するインスタンスの数を検討します。 1 つのコントローラーでオブジェクトのリスト処理を行うのと、ノードごとのポッドで同じことを行うのでは、大きな違いがあります。 クライアント アプリケーションの複数のインスタンスで多数のオブジェクトのリスト処理を定期的に行うことを計画している場合、ソリューションは大規模なクラスターにスケーリングされません。

Azure API とプラットフォームのスロットリング

クラウド アプリケーションに対する負荷は、アクティブなユーザーの数や、ユーザーが実行するアクションの種類などの要因に応じて、時間と共に変化する場合があります。 システムの処理要件が利用できるリソースの容量を超えると、システムが過負荷になり、パフォーマンスが低下したり、障害が発生したりする可能性があります。

クラウド アプリケーションでの負荷の大きさの変化に対処するには、指定した制限まではアプリケーションによるリソースの使用を許可し、制限に達したらスロットルすることができます。 Azure では、スロットリングは 2 つのレベルで行われます。 Azure Resource Manager (ARM) は、サブスクリプションとテナントに対する要求をスロットルします。 要求がサブスクリプションとテナントのスロットリング制限を下回っている場合、ARM は要求をリソース プロバイダーにルーティングします。 その後、リソース プロバイダーによって、その操作に合わせて調整されたスロットリング制限が適用されます。 詳しくは、ARM による要求のスロットリングに関する記事をご覧ください。

AKS でのスロットリングを管理する

Azure API の制限は、通常、サブスクリプションとリージョンの組み合わせのレベルで定義されます。 たとえば、特定のリージョン内のサブスクリプション内のすべてのクライアントが、Virtual Machine Scale Sets の PUT API など、特定の Azure API に対する API 制限を分け合います。 すべての AKS クラスターで、複数の AKS 所有クライアント (クラウド プロバイダーやクラスター オートスケーラーなど) または顧客所有のクライアント (Datadog やセルフホステッド Prometheus など) が Azure API を呼び出します。 特定のリージョン内の 1 つのサブスクリプションで複数の AKS クラスターを実行すると、そのクラスター内の AKS 所有と顧客所有のすべてのクライアントが、共通の API 制限のセットを共有します。 そのため、サブスクリプションのリージョンにデプロイできるクラスターの数は、デプロイされるクライアントの数、その呼び出しパターン、クラスターの全体的なスケールと弾力性の関数になります。

上記の考慮事項に留意し、お客様は通常、サブスクリプションとリージョンの組み合わせごとに 20 から 40 個の小規模から中規模のクラスターをデプロイできます。 サブスクリプションのスケールは、次のベスト プラクティスを使って最大化できます。

Kubernetes クラスターを常に最新バージョンにアップグレードします。 バージョンが新しいほど、パフォーマンスとスロットリングの問題に対処する多くの機能強化が組み込まれています。 アップグレードされたバージョンの Kubernetes を使っていて、それでもまだ、実際の負荷またはサブスクリプション内のクライアント数によってスロットリングが発生する場合は、次のオプションを試すことができます。

  • AKS の問題の診断と解決を使ってエラーを分析する: AKS の問題の診断と解決を使って、エラーを分析し、根本原因を特定して、解決に関する推奨事項を取得できます。
  • クラスターを異なるサブスクリプションまたはリージョンに分割する: 多数のクラスターとノード プールが Virtual Machine Scale Sets を使っている場合は、それらを同じサブスクリプション内の複数のサブスクリプションまたはリージョンに分割できます。 ほとんどの Azure API の制限はサブスクリプションとリージョンのレベルで共有されるため、クラスターを別のサブスクリプションまたはリージョンに移動またはスケーリングすることで、Azure API のスロットリングのブロックを解除できます。 このオプションは、クラスターのアクティビティが高いことが予想される場合に特に役立ちます。 これらの制限に関する一般的なガイドラインはありません。 具体的なガイダンスが必要な場合は、サポート チケットを作成できます。

機能の制限

AKS クラスターをさらに大きなスケール ポイントにスケーリングするときは、機能に関する次の制限に注意してください。

Note

コントロール プレーンをスケーリングする操作中に、API サーバーの待機時間が長くなったり、最大 15 分間のタイムアウトが発生したりする可能性があります。 サポートされている限度までスケーリングできない問題が引き続き発生する場合、サポート チケットを登録します。

kubectl describe configmap control-plane-scaling-status -n kube-system

ネットワーク

AKS クラスターをさらに大きなスケール ポイントにスケーリングするときは、ネットワークに関する次のベスト プラクティスに留意してください。

  • NAT ゲートウェイ上に少なくとも 2 つのパブリック IP があるクラスター エグレスに対して、マネージド NAT を使います。 詳しくは、AKS クラスターに対するマネージド NAT ゲートウェイの作成に関する記事をご覧ください。
  • クラスターあたり 200,000 ポッドと 5,000 ノードまでスケールアップするには、Azure CNI オーバーレイを使います。 詳しくは、「Azure Kubernetes Service (AKS) で Azure CNI オーバーレイ ネットワークを構成する」をご覧ください。
  • アプリケーションでクラスターをまたぐポッド間の直接通信が必要な場合は、動的 IP 割り当てで Azure CNI を使い、ポッドごとに 1 つのルーティング可能な IP を使って、クラスターあたり 50,000 アプリケーション ポッドまでスケールアップします。 詳しくは、AKS での動的 IP 割り当てのための Azure CNI ネットワークの構成に関する記事をご覧ください。
  • 内部ロード バランサーの内側で内部 Kubernetes サービスを使う場合は、スケーリングのパフォーマンスとロード バランサーの弾力性を最適にするため、作成する内部ロード バランサーまたはサービスのノード スケールを 750 未満にすることをお勧めします。
  • Azure npm では、最大 250 個のノードのみがサポートされます。 大規模なクラスターにネットワーク ポリシーを適用したい場合は、Cilium を利用する Azure CNI の使用を検討してください。これは、Azure CNI の堅牢なコントロール プレーンと Cilium のデータ プレーンを組み合わせて、高パフォーマンスのネットワークとセキュリティを提供するものです。

ノード プールのスケーリング

AKS クラスターをさらに大きなスケール ポイントにスケーリングするときは、ノード プールのスケーリングに関する次のベスト プラクティスに留意してください。

  • システム ノード プールの場合は、Standard_D16ds_v5 SKU または同等のコア/メモリ VM SKU とエフェメラル OS ディスクを使って、kube-system ポッドに十分なコンピューティング リソースを提供するようにします。
  • AKS にはノード プールあたり 1,000 ノードの制限があるため、5,000 ノードまでスケールアップするには、少なくとも 5 つのユーザー ノード プールを作成することをお勧めします。
  • 大規模な AKS クラスターを実行する場合は、可能な限りクラスター オートスケーラーを使用して、コンピューティング リソースの需要に基づいてノード プールが動的にスケーリングされるようにします。 詳細については、アプリケーションの需要を満たすための AKS クラスターの自動スケールに関する記事を参照してください。
  • 1,000 ノードを超えてスケーリングし、クラスター オートスケーラーを "使わない" 場合は、一度に 500 から 700 ノードをバッチでスケーリングすることをお勧めします。 スケーリング操作では、Azure API のスロットリングを防ぐため、異なるスケールアップ操作の間に、2 分から 5 分の待ち時間を設ける必要があります。 詳しくは、API Management でのキャッシュとスロットルのポリシーに関する記事をご覧ください。

クラスターのアップグレードに関する考慮事項とベスト プラクティス

  • クラスターがノード制限 5,000 に達すると、クラスターのアップグレードはブロックされます。 最大サージ プロパティの制限内でローリング更新を実行するために使用可能なノード容量がないため、この制限によりアップグレードが防止されます。 この制限でクラスターがある場合、クラスターのアップグレードを試みる前に、3,000 ノード未満にクラスターをスケールダウンすることをお勧めします。 これにより、ノード チャーンに容量が追加され、コントロール プレーンの負荷が最小限に抑えられます。
  • 500 ノードを超えるクラスターをアップグレードする場合、ノード プールの容量の 10-20% となる最大サージ構成を使用することをお勧めします。 AKS では、最大サージに対して既定値の 10% でアップグレードを構成します。 最大サージ設定をノード プールごとにカスタマイズすることで、アップグレードの速度とワークロードによる中断とのトレードオフが可能になります。 最大サージ設定を大きくするとアップグレード プロセスはより速く完了しますが、アップグレード プロセス中に中断が発生する可能性があります。 詳細については、「ノード サージ アップグレードのカスタマイズ」を参照してください。
  • 詳細については、「AKS クラスターのアップグレード」を参照してください。