複数のポッドが同じノードで実行されている場合、ポッドは CPU リソースを競合します。各ポッドに割り当てられる CPU コアは頻繁に変更される可能性があり、パフォーマンスのジッターにつながります。パフォーマンス重視のアプリケーションでは、トポロジー対応 CPU スケジューリング機能を有効にして、ポッドをノード上の CPU コアに固定できます。このアプローチにより、CPU コンテキストの切り替えと、Non-Uniform Memory Access(NUMA)ノード間のメモリアクセスによって発生するパフォーマンスの問題が軽減されます。
この機能をより深く理解し、使用するには、Kubernetes の公式ドキュメントを参照して、ポッド QoS クラス、コンテナーとポッドへのメモリリソースの割り当て、ノード上の CPU 管理ポリシー(CPU 管理ポリシー、none ポリシー、static ポリシーなど)について学習することをお勧めします。
シナリオ
Kubernetes クラスターでは、複数のポッドが同じノード上の CPU コアを共有する場合があります。ただし、次のシナリオでは、一部のアプリケーションを特定の CPU コアに固定する必要がある場合があります。
クラウドネイティブのシナリオに適応していないアプリケーション。たとえば、スレッド数は、コンテナーの仕様ではなく、デバイスの物理コアの合計数に基づいて指定されます。その結果、アプリケーションのパフォーマンスが低下します。
Intel CPU または AMD CPU を搭載したマルチコア ECS ベアメタルインスタンスで実行され、NUMA ノード間のメモリアクセスが原因でパフォーマンスが低下するアプリケーション。
CPU コンテキストの切り替えに非常に敏感で、パフォーマンスのジッターを許容できないアプリケーション。
これらの懸念事項に対処するため、ACK は Kubernetes の新しいスケジューリングフレームワークに基づくトポロジー対応 CPU スケジューリングをサポートしています。これは、ポッドアノテーションを通じて有効化して、CPU に依存するワークロードのサービスパフォーマンスを最適化できます。
トポロジー対応 CPU スケジューリングは、Kubernetes によって提供される CPU マネージャー の制限を克服します。CPU マネージャーは、CPU アフィニティとパフォーマンス要件の高いアプリケーションに static ポリシーを構成することで、これらの問題を解決します。これにより、これらのアプリケーションはノード上の特定の CPU コアを排他的に使用して、安定した計算リソースを確保できます。ただし、CPU マネージャーはノードレベルの CPU スケジューリングソリューションのみを提供し、クラスターレベルで複数の CPU コアを割り当てる最適な方法を見つけることはできません。さらに、CPU マネージャーを介して static ポリシーを構成すると、Guaranteed ポッドのみに影響し、Burstable ポッドや BestEffort ポッドなどの他のポッドタイプには適用されません。Guaranteed ポッドでは、各コンテナーに CPU リクエストと CPU 制限の両方が構成され、これらの値は同じに設定されます。
前提条件
ACK Pro マネージドクラスター が作成されており、ノードプールの CPU ポリシー(
cpuManagerPolicy)が None に設定されています。cpuManagerPolicyを構成する方法については、「ノードプールの kubelet パラメーターをカスタマイズする」をご参照ください。ack-koordinator コンポーネントがインストールされており、コンポーネントのバージョンが 0.2.0 以降です。詳細については、「ack-koordinator」をご参照ください。
課金
ack-koordinator コンポーネントのインストールまたは使用に料金はかかりません。ただし、次のシナリオでは料金が発生する場合があります。
ack-koordinator は非マネージドコンポーネントであり、インストール後にワーカーノードリソースを占有します。コンポーネントをインストールするときに、各モジュールによってリクエストされるリソース量を指定できます。
デフォルトでは、ack-koordinator は、リソースプロファイリングや詳細スケジューリングなどの機能のモニタリングメトリックを Prometheus メトリックとして公開します。ack-koordinator の Prometheus メトリックを有効にすると、Managed Service for Prometheus を使用している場合、これらのメトリックは カスタムメトリック と見なされ、これらのメトリックに対して課金されます。料金は、クラスターのサイズやアプリケーションの数などの要因によって異なります。Prometheus メトリックを有効にする前に、Managed Service for Prometheus の 課金 に関するトピックを読み、カスタムメトリックの無料枠と課金ルールについて理解することをお勧めします。リソース使用量の監視と管理方法の詳細については、「監視対象データ量と料金をクエリする」をご参照ください。
手順
このトピックでは、NGINX アプリケーションを例として使用して、プロセッサアフィニティを実現するためにトポロジー対応 CPU スケジューリングを有効にする方法を示します。
手順 1: サンプルアプリケーションをデプロイする
次の YAML テンプレートを使用して、NGINX アプリケーションをデプロイします。
ポッドがデプロイされているノードで、次のコマンドを実行して、コンテナーにバインドされている CPU コアを表示します。
# パスは、ポッド UID とコンテナー ID を連結することで取得できます。 cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus期待される出力:
# 出力は、コンテナーが使用できる CPU コアのシリアル番号が、CPU コアをコンテナーにバインドする前は 0 から 31 の範囲であることを示しています。 0-31
手順 2: トポロジー対応 CPU スケジューリングを有効にする
ポッドアノテーションを介してトポロジー対応 CPU スケジューリングを有効にして、プロセッサアフィニティを実現できます。
トポロジー対応 CPU スケジューリングを使用する場合は、ポッドに nodeName を指定しないでください。 kube-scheduler は、このようなポッドのスケジューリングプロセスには関与しません。nodeSelector などのフィールドを使用して、アフィニティポリシーを構成してノードスケジューリングを指定できます。
標準 CPU コアバインディング
ポッドアノテーション cpuset-scheduler を介してトポロジー対応 CPU スケジューリングを有効にすると、システムがプロセッサアフィニティを実装します。
ポッド YAML ファイルの
metadata.annotationsで、cpuset-schedulerをtrueに設定して、トポロジー対応 CPU スケジューリングを有効にします。説明デプロイメントなどのワークロードに構成を適用するには、
template.metadataフィールドのポッドに適切なアノテーションを設定します。Containersフィールドで、resources.limits.cpuに整数値を設定して、CPU コア数を制限します。
自動 CPU コアバインディング
アノテーションを介して、トポロジー対応 CPU スケジューリングと自動 CPU コアバインディングポリシーを同時に有効にできます。構成後、スケジューラは NUMA 間のメモリアクセスを回避しようとしながら、ポッドの仕様に基づいてバインドされた CPU コア数を自動的に決定します。
ポッド YAML ファイルの
metadata.annotationsで、cpuset-schedulerをtrueに、cpu-policyをstatic-burstに設定して、自動 CPU コアバインディングを有効にします。説明デプロイメントなどのワークロードに構成を適用するには、
template.metadataフィールドのポッドに適切なアノテーションを設定します。Containersフィールドで、resources.limits.cpuを CPU コアの参照上限として整数値に設定します。
結果の検証
標準 CPU コアバインディングを例に、トポロジー対応 CPU スケジューリングが正常に有効になっているかどうかを確認します。自動 CPU コアバインディングの検証プロセスも同様です。
ポッドがデプロイされているノードで、自動 CPU コアバインディングを有効にした後、次のコマンドを実行して、コンテナーにバインドされている CPU コアを表示します。
# パスは、ポッド UID とコンテナー ID を連結することで取得できます。
cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus期待される出力:
# 出力は制限と同じです。
0-3期待される出力は、コンテナーが使用できる CPU コアのシリアル番号が 0 から 3 の範囲であることを示しています。使用可能な CPU コア数は、YAML ファイルで宣言された resources.limits.cpu と一致しています。
関連情報
Kubernetes は、ノード上の GPU リソースのトポロジーを認識しません。したがって、Kubernetes は GPU リソースをランダムにスケジュールします。その結果、トレーニングジョブの GPU アクセラレーションは、GPU リソースのスケジューリング結果に基づいて大きく異なります。トレーニングジョブの最適な GPU アクセラレーションを実現するために、トポロジー対応 GPU スケジューリングを有効にすることをお勧めします。詳細については、「GPU トポロジー対応スケジューリング」をご参照ください。
ポッドに割り当てられているが使用されていないリソースを定量化し、これらのリソースを優先度の低いジョブにスケジュールして、リソースのオーバーコミットを実現できます。詳細については、「動的リソースオーバーコミットの有効化」をご参照ください。