ノードのパフォーマンスを調整する

コンテナベースのアプリケーションのパフォーマンスを向上させる方法の 1 つは、ノードを追加するか、リソース(CPU やメモリなど)をノードに追加することでクラスタ リソースを増やすことです。しかし、このアプローチはコストがかかる可能性があります。クラスタノードを調整してパフォーマンスを向上させると、ワークロードのリソース使用率を費用対効果の高い方法で最適化できます。このドキュメントでは、Performance Tuning Operator を使用してワーカーノードを調整し、GKE on Bare Metal のワークロード パフォーマンスを最適化する方法について説明します。

基盤となるハードウェアとソフトウェアを最大限に活用するには、さまざまなタイプのアプリケーション(特に高パフォーマンス アプリケーション)で、次のようなノード設定の調整が有効です。

  • パフォーマンス重視のワークロード専用の CPU
  • 標準の Kubernetes デーモンとサービス用に予約された CPU
  • 1 GiB(ギビバイト)または 2 MiB(メビバイト)の hugepage を持つメモリ ページ サイズの引き上げ
  • マルチコア プロセッサや NUMA など、システム アーキテクチャに基づくワークロードの分散

Performance Tuning Operator を使用し、パフォーマンス構成を適用する Kubernetes カスタム リソースを作成することで、ノードレベルのパフォーマンス設定を構成します。主なメリットは次のとおりです。

  • 単一の統合構成インターフェース: Performance Tuning Operator では、ノードセレクタを使用してワーカーノードに適用できる 1 つ以上の PerformanceTuningProfile マニフェストを更新します。複数の構成とポリシー設定で各ノードを個別に構成する必要はありません。この方法では、ノードレベルとコンテナレベルの構成を単一の統合された方法で管理できます。

  • 永続性と信頼性: Kubernetes による高可用性アーキテクチャの信頼性もすべて得られます。PerformanceTuningProfile カスタム リソースは必要なときにいつでも更新でき、その設定はアップグレードなどの主要なクラスタ オペレーション全体で保持されます。

Performance Tuning Operator は、次のパフォーマンス関連の Kubernetes とオペレーティング システム(OS)の機能とツールをオーケストレートすることで機能します。

競合を防ぐため、Performance Tuning Operator を使用する場合は、前述の Kubernetes および OS のツールと機能を独立して使用しないことをおすすめします。

前提条件と制限事項

Performance Tuning Operator を使用する際の前提条件と制限事項は次のとおりです。

  • Red Hat Enterprise Linux(RHEL)のみ: Performance Tuning Operator は、サポートされているバージョンの RHEL を実行しているノードでのみサポートされます。

  • ワーカーノードがあるユーザーまたはハイブリッド クラスタ: Performance Tuning Operator は、ユーザー クラスタまたはハイブリッド クラスタ内のワーカーノードでのみサポートされます。Performance Tuning Operator を使用してコントロール プレーン ノードを調整することはサポートされていません。Performance Tuning Operator は、ノードセレクタを使用して調整プロファイルを適用する方法を決定します。調整プロファイルがワーカーノードのみに適用されるようにするには、各プロファイル カスタム リソースの nodeSelector に標準のワーカーノード ラベル node-role.kubernetes.io/worker: "" を含める必要があります。調整プロファイルの nodeSelector がコントロール プレーン ノードのラベルと一致する場合、そのノードは調整されず、エラー条件が設定されます。エラー条件の詳細については、ステータスの確認をご覧ください。Performance Tuning Operator をインストールして調整プロファイルを適用する前に、クラスタが正しく動作していることを確認してください。

  • TuneD 2.22.0: Performance Tuning Operator では、調整するワーカーノードに TuneD バージョン 2.22.0 がプリインストールされている必要があります。インストール手順など、TuneD の詳細については、Red Hat Enterprise Linux のドキュメントの TuneD のスタートガイドをご覧ください。Performance Tuning Operator は、cpu-partitioning プロファイルで TuneD を使用します。このプロファイルがない場合は、次のコマンドを使用してインストールできます。

    dnf install -y tuned-profiles-cpu-partitioning
    
  • ワークロード リソースの要件: パフォーマンスの調整を最大限に活用するには、ワークロードのメモリと CPU の要件(リソースのリクエストと上限)をよく理解する必要があります。

  • 使用可能なノードリソース: ノードの CPU リソースとメモリリソースを確認します。ノードの CPU とメモリの詳細情報は、それぞれ /proc/cpuinfo ファイルと /proc/meminfo ファイルで取得できます。kubectl get nodes を使用して、ワーカーノードが Pod で使用できるコンピューティング リソースとメモリリソース(status.allocatable)の量を取得することもできます。

  • ドレインの要求: 調整プロセスの一環として、Performance Tuning Operator は、まずノードをドレインしてから、調整プロファイルを適用します。その結果、パフォーマンス調整中にノードが NotReady ステータスを報告することがあります。ワークロードの停止を最小限に抑えるため、バッチ アップデートではなく、ローリング アップデート方式(spec.updateStrategy.type: rolling)を使用することをおすすめします。

  • 再起動が必要: ノード調整の変更を有効にするため、調整プロファイルの適用後、Performance Tuning Operator によりノードが再起動されます。

Performance Tuning Operator をインストールする

Performance Tuning Operator は、主に 2 つのコントローラ(Deployment と DaemonSet)で構成され、プロファイル設定に基づいてノードを調整するため、相互にやりとりします。デフォルトでは、GKE on Bare Metal に Performance Tuning Operator はインストールされません。Cloud Storage から Performance Tuning Operator マニフェストをダウンロードし、kubectl apply を使用してクラスタに Performance Tuning Operator リソースを作成します。

クラスタのデフォルト値を使用してパフォーマンスの調整を有効にするには:

  1. 管理ワークステーションに performance-tuning ディレクトリを作成します。

  2. Cloud Storage リリース バケットの performance-tuning ディレクトリから、最新の Performance Tuning Operator パッケージをダウンロードします。

    gsutil cp -r gs://anthos-baremetal-release/node-performance-tuning/0.1.0-gke.47 .
    

    ダウンロードしたファイルには、performance-tuning-operator Deployment と nodeconfig-controller-manager DaemonSet のマニフェストが含まれています。関連機能(ロールベースのアクセス制御(RBAC)や動的アドミッション コントロールなど)のマニフェストも含まれています。

  3. root ユーザーとして、ユーザー(またはハイブリッド)クラスタにすべての Performance Tuning Operator マニフェストを繰り返し適用します。

    kubectl apply -f performance-tuning --recursive –-kubeconfig USER_KUBECONFIG
    

    一旦 Deployment と DaemonSet が作成されて実行されると、操作は、PerformanceTuningProfile マニフェストを編集して適用することだけになります。

ワークロードのリソース要件を確認する

ノードを調整する前に、ワークロードのコンピューティング リソースとメモリリソースの要件を理解する必要があります。ワーカーノードに十分なリソースがある場合、保証された Quality of Service(QoS)クラスのワークロードに対して保証されたメモリ(標準ページと hugepage)を提供するようにノードを調整できます。

Kubernetes は、関連するコンテナ用に指定したリソース制約に基づいて、各 Pod に QoS クラスを割り当てます。次に Kubernetes は、QoS クラスを使用して、Pod とコンテナのスケジュール設定方法を決定し、ワークロードにリソースを割り当てます。ワークロードのノード調整を最大限に活用するには、ワークロードに CPU またはメモリリソースのリクエスト設定または上限設定が必要です。

QoS 保証クラスを割り当てるには、Pod が以下の要件を満たしている必要があります。

  • Pod 内のコンテナそれぞれに対して:
    • メモリリソースのリクエスト(spec.containers[].resources.requests.memory)と上限(spec.containers[].resources.limits.memory)両方の値を指定します。
    • メモリ上限の値は、メモリ リクエストの値と同じでなければなりません。
    • CPU リソースのリクエスト(spec.containers[].resources.requests.cpu)と上限(spec.containers[].resources.limits.cpu)両方の値を指定します。
    • CPU 上限値は、CPU リクエスト値と同じでなければなりません。

次の Pod 仕様の例では、保証された QoS クラス要件を満たす CPU リソース設定を示します。

spec:
  containers:
  - name: sample-app
    image: images.my-company.example/app:v4
    resources:
      requests:
        memory: "128Mi"
        cpu: "2"
      limits:
        memory: "128Mi"
        cpu: "2"
  ...

kubectl get pods で Pod の詳細を取得する場合は、次の例に示すように、status セクションに割り当てられた QoS クラスが含まれている必要があります。

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2023-09-22T21:05:23Z"
  generateName: my-deployment-6fdd69987d-
  labels:
    app: metrics
    department: sales
    pod-template-hash: 6fdd69987d
  name: my-deployment-6fdd69987d-7kv42
  namespace: default
  ...
spec:
  containers:
  ...
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-09-22T21:05:23Z"
    status: "True"
    type: Initialized
  ...
  qosClass: BestEffort
  startTime: "2023-09-22T21:05:23Z"

QoS クラスの詳細については、Kubernetes ドキュメントの Pod の Quality of Service クラスをご覧ください。QoS クラスが割り当てられるように Pod とコンテナを構成する手順については、Pod の Quality of Service を構成するをご覧ください。

CPU 要件

ノードを調整する際、Kubernetes システム デーモン(kubelet やコンテナ ランタイムなど)を実行するために、一連の予約済みの CPU コア(spec.cpu.reservedCPUs)を指定できます。この同じ予約済みの CPU セットでは、オペレーティング システムのデーモン(sshdudev など)も実行されます。残りの CPU コアは、「分離」として割り当てられます。分離 CPU は、「CPU の制約を受ける」 アプリケーションを対象としています。このアプリケーションには、他のアプリケーションからの干渉やネットワークや他のデバイスからの割り込みがない専用の CPU 時間が必要です。

ワーカーノードの分離 CPU で Pod をスケジュールするには:

  • サービス品質(QoS)を保証するように Pod を構成します。

  • CPU の要件と上限は整数で指定する必要があります。cpu: 0.5cpu: 250m(250 ミリコア)など、Pod 仕様で部分的な CPU リソースを指定した場合、スケジューリングは保証されません。

メモリ要件

Performance Tuning Operator を使用してノードを調整する場合は、hugepage を作成し、マシン上の不均一メモリアクセス(NUMA)ノードに関連付けることができます。Pod とノードの設定に基づき、NUMA ノード アフィニティを使用して Pod をスケジュールできます。

パフォーマンス調整プロファイルを作成する

Performance Tuning Operator をインストールした後は、ワークロードを実行するクラスタのみを操作します。管理クラスタではなく、ユーザー クラスタまたはハイブリッド クラスタで PerformanceTuningProfile カスタム リソースを直接作成します。各 PerformanceTuningProfile リソースには、ノードに適用されるパフォーマンス構成を指定する一連のパラメータが含まれています。

リソース内の nodeSelector によって、調整プロファイルが適用されるノードが決まります。プロファイルをノードに適用するには、対応する Key-Value ペアのラベルをノードに配置します。調整プロファイルは、nodeSelector フィールドに指定されたすべてのラベルを持つノードに適用されます。

1 つのクラスタに複数の PerformanceTuningProfile リソースを作成できます。複数のプロファイルが指定されたノードと一致する場合は、PerformanceTuningProfile カスタム リソースの status にエラー条件が設定されます。status セクションの詳細については、ステータスの確認をご覧ください。

PerformanceTuningProfile カスタム リソースの Namespace を kube-system に設定します。

1 つ以上のワーカーノードを調整するには:

  1. PerformanceTuningProfile マニフェストを編集します。

    マニフェストの各フィールドとサンプル マニフェストについては、PerformanceTuningProfile リソース リファレンスをご覧ください。

  2. (省略可)プロファイルを適用するワーカーノードに対しては、spec.nodeSelector Key-Value ペアと一致するラベルを追加します。

    PerformanceTuningProfile カスタム リソースに spec.nodeSelector Key-Value ペアが指定されていない場合、プロファイルはすべてのワーカーノードに適用されます。

  3. マニフェストをクラスタに適用します。

    kubectl apply -f PROFILE_MANIFEST --kubeconfig KUBECONFIG
    

    次のように置き換えます。

    • PROFILE_MANIFEST: PerformanceTuningProfile カスタム リソースのマニフェスト ファイルのパス。
    • KUBECONFIG: クラスタの kubeconfig ファイルのパス。

調整プロファイルを削除する

ノードを元の調整されていない状態にリセットするには:

  1. クラスタから PerformanceTuningProfile カスタム リソースを削除します。

  2. 再度調整プロファイルによって選択されないように、ノードのラベルを更新または削除します。

ノードに複数の調整プロファイルが関連付けられている場合は、必要に応じて前の手順を繰り返します。

調整プロファイルを一時停止する

クラスタのメンテナンスを行う必要がある場合は、PerformanceTuningProfile カスタム リソースを編集することで調整を一時停止できます。クラスタのアップグレードなどの重要なクラスタ オペレーションを実行する前に、調整を一時停止することをおすすめします。

別のプロファイル アプリケーションが失敗すると、調整が一時停止されることがあります。調整プロセスが失敗した場合は、コントローラがノードの調整を試行することがあり、その結果、ノードが再起動される場合があります。準備完了状態と準備未完了状態の間のノード ステータスが切り替わる場合は、壊れた状態から回復できるように調整を一時停止します。

調整を一時停止するには:

  1. PerformanceTuningProfile カスタム リソース マニフェストを編集して、spec.pausedtrue に設定します。

  2. kubectl apply を使用してリソースを更新します。

パフォーマンス調整が一時停止されると、Performance Tuning Operator コントローラはそのすべてのオペレーションを停止します。一時停止すると、GKE on Bare Metal コントローラのオペレーションと Performance Tuning Operator コントローラのオペレーションが競合するリスクを軽減できます。

PerformanceTuningProfile リソース リファレンス

このセクションでは、PerformanceTuningProfile カスタム リソースの各フィールドについて説明します。このリソースは、1 つ以上のクラスタノードの調整プロファイルの作成に使用されます。リソース内のすべてのフィールドは、プロファイルの作成後に変更できます。プロファイルは kube-system 名前空間に存在する必要があります。

以下の numa サンプル プロファイル マニフェストでは、8 CPU コアのノードに対して次のリソース割り当てを指定します。

  • 4 つの CPU コア(0-3)が、Kubernetes システムのオーバーヘッド用に予約されています。

  • 4 つの CPU コア(4-7)が、ワークロード用に確保されています。

  • ノードのメモリはデフォルトで、標準の 4 Ki ページではなく 2 MiB ページに分割されます。

  • NUMA ノード 0 が使用するために、1 GiB のサイズの 10 ページのメモリが確保されています。

  • NUMA ノード 1 が使用するために、2 MiB のサイズの 5 ページのメモリが確保されています。

  • Topology Manager は、ワークロードのスケジュール設定にベスト エフォート ポリシーを使用します。

apiVersion: anthos.gke.io/v1alpha1
kind: PerformanceTuningProfile
metadata:
  name: numa
  namespace: kube-system
spec:
  cpu:
    isolatedCPUs: 4-7
    reservedCPUs: 0-3
  defaultHugepagesSize: 2M
  nodeSelector:
    app: database
    node-role.kubernetes.io/worker: ""
  pages:
  - count: 10
    numaNode: 0
    size: 1G
  - count: 5
    numaNode: 1
    size: 2M
  topologyManagerPolicy: best-effort

関連する PerformanceTuningProfile カスタム リソース定義は、クラスタ内の anthos.gke.io グループから取得できます。プレビュー機能のアノテーションがセルフマネージド クラスタ リソースに追加されると、カスタム リソース定義がインストールされます。

CPU 構成

プロパティ 説明
cpu.reservedCPUs 必須。変更可。文字列。このフィールドは、Kubernetes システム デーモン(kubelet、コンテナ ランタイム、ノードの問題検出機能など)用に予約する一連の CPU コアを定義します。これらの CPU コアは、オペレーティング システム(OS)のシステム デーモン(sshdudev など)にも使用されます。

cpu.reservedCPUs フィールドには、CPU 番号のリストか CPU 番号の範囲を指定します。CPU のリストは、cpu.isolatedCPUs で指定されたリストと重複しないようにしてください。この 2 つのフィールドに指定された CPU を合わせたものには、そのノードのすべての CPU が含まれている必要があります。

cpu.isolatedCPUs 省略できます。変更可。文字列。cpu.isolatedCPUs フィールドは、パフォーマンス重視のアプリケーション専用に使用される一連の CPU を定義します。CPU マネージャーは、Kubernetes の Quality of Service(QoS)クラスに応じて、予約されていない CPU に対してのみコンテナをスケジュールします。分離 CPU でワークロードが実行されるようにするには、保証された QoS クラスで Pod を構成し、および Pod またはコンテナに CPU リソースを割り当てます。Pod のスケジューリングを保証するには、CPU リソースの一部(cpu: "0.5")ではなく、整数で CPU ユニット数を指定する必要があります。

apiVersion: v1
kind: Pod
...
spec:
  containers:
  ...
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "1"
  ...

ワークロードに対して分離 CPU を最大化することで、最高のパフォーマンス効果が得られます。このフィールドには、CPU 番号のリストか、CPU 番号の範囲を指定します。CPU のリストが cpu.reservedCPUs で指定されたリストと重複しないことと、この 2 つのフィールドのリストを合わせたものにノードのすべての CPU が含まれるようにしてください。

cpu.balanceIsolated 省略できます。変更可。データ型はブール値です。デフォルト: trueこのフィールドは、分離 CPU のセットが CPU 全体のワークロードの自動ロード バランシングの対象となるかどうかを指定します。このフィールドを false に設定すると、ワークロードは各スレッドを特定の CPU に明示的に割り当て、CPU 間で負荷を分散する必要があります。明示的な CPU の割り当てを使用すると、保証されたワークロードに対して最も予測可能なパフォーマンスが得られますが、ワークロードはより複雑になります。
cpu.globallyEnableIRQLoadBalancing 必須。変更可。データ型はブール値です。デフォルト: trueこのフィールドは、分離 CPU セットで割り込みリクエスト(IRQ)ロード バランシングを有効にするかどうかを指定します。

メモリ構成

プロパティ 説明
defaultHugePageSize 省略できます。変更可。値: 1G または 2M。このフィールドは、カーネルのブート パラメータにあるデフォルトの hugepage サイズを定義します。hugepage は起動時にメモリが断片化される前に割り当てられます。hugepage のデフォルト サイズを 1G に設定すると、2M の関連フォルダがすべてノードから削除されることに注意してください。デフォルトの hugepage サイズを 1G にすると、ノードに 2M の hugepage は構成できなくなります。
pages 省略できます。変更可。データ型は int です。このフィールドは、起動時に作成する hugepage の数を指定します。このフィールドには、ページの配列を指定できます。hugepage を指定する前に、ノードで使用可能なメモリを確認してください。必要以上の大容量のページをリクエストすることや、hugepage 用にすべてのメモリを予約することはしないでください。ワークロードには標準メモリも必要です。

ノード選択

プロパティ 説明
nodeSelector 必須。変更可。このフィールドには、常に Kubernetes ワーカーノード ラベル node-role.kubernetes.io/worker:"" が必要です。これにより、パフォーマンス調整がワーカーノードだけで行われるようになります。このフィールドには、オプションのノードラベルを Key-Value ペアとして指定します。Key-Value ペアのラベルは、一致するラベルを持つ特定のワーカーノードを選択するために使用されます。nodeSelector ラベルがワーカーノードのラベルと一致すると、そのノードにパフォーマンス プロファイルが適用されます。プロファイルで Key-Value ラベルを指定しない場合、ラベルはクラスタ内のすべてのワーカーノードに適用されます。

たとえば、次の nodeSelector は、調整プロファイルが app: database ラベルと一致するワーカーノードにのみ適用されることを示しています。


...
spec:
  nodeSelector:
    app: database
    node-role.kubernetes.io/worker: ""
  ...

Kubelet 構成

プロパティ 説明
topologyManagerPolicy 省略できます。変更可。値: nonebest-effortrestricted、または single-numa-node。デフォルト: best-effort。このフィールドには、割り当てられたサービス品質(QoS)クラスに基づいて、ワークロードにリソースを割り当てるために使用される Kubernetes Topology Manager ポリシーを指定します。QoS クラスの割り当ての詳細については、Pod のサービス品質を構成するをご覧ください。

プロファイルのオペレーション

プロパティ 説明
paused 省略できます。変更可。データ型はブール値です。DaemonSet コントローラが選択したノードを一時的に調整しないようにするには、pausedtrue に設定します。
updateStrategy 省略できます。変更可。選択したノードに調整構成の変更を適用する方法を指定します。
updateStrategy.rollingUpdateMaxUnavailalble 省略できます。変更可。データ型は int です。デフォルト: 1同時に調整できるノードの最大数を指定します。このフィールドは、typerolling に設定されている場合にのみ適用されます。
updateStrategy.type 省略できます。変更可。値: batch または rolling。デフォルト: rolling。選択したノードにプロファイルの更新を適用する方法を指定します。選択したすべてのノードに同時に更新を適用する場合は、typebatch に設定します。デフォルトでは、更新は個々のノードに順番にロールアウトされます。

ステータスを確認

PerformanceTuningProfile カスタム リソースが作成または更新された後、コントローラは、リソースで提供される構成に基づいて選択したノードを調整します。PerformanceTuningProfile のステータスを確認するため、Status に次のフィールドを公開します。

プロパティ 説明
conditions condition は、プロファイル リソースの現在の状態に関する、利用可能な最新の観測値を表します。
conditions.lastTransitionTime 常に返されます。文字列(日時形式)。ある状態から別の状態に遷移した最後の時刻。通常、この時刻は、基本的な状態が変更されたタイミングを示します。その時刻が不明な場合は、API フィールドが変更された時刻を示します。
conditions.message 省略できます。文字列。遷移の詳細を示す、人が読めるメッセージ。このフィールドは空の場合があります。
conditions.observedGeneration 省略できます。データ型は int です。設定されている場合、このフィールドは、条件が設定された metadata.generation を表します。たとえば、metadata.generation12 であるにもかかわらず、status.condition[x].observedGeneration9 である場合、その状態はインスタンスの現在の状態に関して古くなっています。
conditions.reason 必須。文字列。最後の状態遷移の理由。
conditions.status 必須。状態のステータス: TrueFalse、または Unknown
conditions.type 必須。タイプは状態のタイプ: Stalled または Reconciling
readyNodes 調整プロファイルが正常に適用されたノードの数。
reconcilingNodes nodeconfig-controller-manager DaemonSet によって最新の調整プロファイルでの調整途中にある、選択された(または以前に選択された)ノードの数。
selectedNodes 選択されたノードの数。つまり、この PerformanceTuningProfile カスタム リソースのノードセレクタに一致するノードの数です。

次のステップ