ノード パフォーマンスをチューニングする

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

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

  • パフォーマンス重視のワークロード専用の CPU
  • 標準の Kubernetes デーモンと Service の予約済み 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)で構成され、プロファイル設定に基づいてノードを調整するため、相互にやりとりします。デフォルトでは、Google Distributed Cloud に Performance Tuning Operator はインストールされません。Cloud Storage から Performance Tuning Operator マニフェストをダウンロードし、kubectl apply を使用してクラスタに Performance Tuning Operator リソースを作成します。

クラスタのデフォルト値でパフォーマンス チューニングを有効にするには:

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

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

    gcloud storage cp gs://anthos-baremetal-release/node-performance-tuning/0.1.0-gke.47 . --recursive
    

    ダウンロードしたファイルには、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 をスケジュールするには:

  • 保証型 Quality of Service(QoS)用に Pod を構成します。

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

メモリ要件

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

パフォーマンス チューニング プロファイルを作成する

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

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

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

PerformanceTuningProfile カスタム リソースの名前空間を 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 コントローラはそのすべてのオペレーションを停止します。一時停止すると、Google Distributed Cloud コントローラのオペレーションと 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 省略可。変更可。整数。このフィールドは、起動時に作成する 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 省略可。変更可。ブール値。pausedtrue に設定すると、DaemonSet コントローラが選択したノードを一時的に調整できなくなります。
updateStrategy 省略可。変更可。選択したノードにチューニング構成の変更を適用する戦略を指定します。
updateStrategy.rollingUpdateMaxUnavailalble 省略可。変更可。整数。デフォルト: 1。同時に調整できるノードの最大数を指定します。このフィールドは、typerolling に設定されている場合にのみ適用されます。
updateStrategy.type 省略可。変更可。値: batch または rolling。デフォルト: rolling。選択したノードにプロファイルの更新を適用する方法を指定します。選択したすべてのノードに同時に更新を適用する場合は、typebatch に設定します。デフォルトでは、更新は個々のノードに順次ロールアウトされます。

ステータスを確認する

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

プロパティ 説明
conditions condition は、プロファイル リソースの現在の状態に関する、利用可能な最新の観測値を表します。
conditions.lastTransitionTime 常に返されます。文字列(日時形式)。ある状態から別の状態に遷移した最後の時刻。通常、この時刻は、基本的な状態が変更されたタイミングを示します。その時刻が不明な場合は、API フィールドが変更された時刻を示します。
conditions.message 省略可。文字列。移行の詳細を示す人間が読めるメッセージ。このフィールドは空の場合があります。
conditions.observedGeneration 省略可。整数。設定されている場合、このフィールドは、条件が設定された 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 カスタム リソースのノードセレクタに一致するノードの数です。

次のステップ