5.9. OpenShift Container Platform クラスター内のノードのリソースの割り当て

より信頼性の高いスケジューリングを実現し、ノードにおけるリソースのオーバーコミットを最小限にするために、kubelet および kube-proxy などの基礎となるノードのコンポーネント、および sshd および NetworkManager などの残りのシステムコンポーネントに使用される CPU およびメモリーリソースの一部を予約します。予約するリソースを指定して、スケジューラーに、ノードが Pod で使用できる残りの CPU およびメモリーリソースについての詳細を提供します。OpenShift Container Platform がノードについて 最適な system-reserved CPU およびメモリーリソースを自動的に判別 できるようにしたり、ノードに 最適なリソースを手動で判断して設定 したりすることができます。

5.9.1. ノードにリソースを割り当てる方法について

OpenShift Container Platform 内のノードコンポーネントの予約された CPU とメモリーリソースは、2 つのノード設定に基づいています。

設定説明

kube-reserved

この設定は OpenShift Container Platform では使用されません。確保する予定の CPU およびメモリーリソースを system-reserved 設定に追加します。

system-reserved

この設定は、CRI-O および Kubelet などのノードコンポーネントおよびシステムコンポーネント用に予約するリソースを特定します。デフォルト設定は、OpenShift Container Platform および Machine Config Operator のバージョンによって異なります。machine-config-operator リポジトリーでデフォルトの systemReserved パラメーターを確認します。

フラグが設定されていない場合、デフォルトが使用されます。いずれのフラグも設定されていない場合、割り当てられるリソースは、割り当て可能なリソースの導入前であるためにノードの容量に設定されます。

注記

reservedSystemCPUs パラメーターを使用して予約される CPU は、 kube-reserved または system-reserved を使用した割り当てには使用できません。

5.9.1.1. OpenShift Container Platform による割り当てられたリソースの計算方法

割り当てられたリソースの量は、以下の数式に基づいて計算されます。

[Allocatable] = [Node Capacity] - [system-reserved] - [Hard-Eviction-Thresholds]
注記

Allocatable の値がノードレベルで Pod に対して適用されるために、Hard-Eviction-ThresholdsAllocatable から差し引くと、システムの信頼性が強化されます。

Allocatable が負の値の場合、これは 0 に設定されます。

各ノードはコンテナーランタイムおよび kubelet によって利用されるシステムリソースについて報告します。system-reserved パラメーターの設定を簡素化するには、ノード要約 API を使用してノードに使用するリソースを表示します。ノードの要約は /api/v1/nodes/<node>/proxy/stats/summary で利用できます。

5.9.1.2. ノードによるリソースの制約の適用方法

ノードは、Pod が設定された割り当て可能な値に基づいて消費できるリソースの合計量を制限できます。この機能は、Pod がシステムサービス (コンテナーランタイム、ノードエージェントなど) で必要とされる CPU およびメモリーリソースを使用することを防ぎ、ノードの信頼性を大幅に強化します。ノードの信頼性を強化するために、管理者はリソースの使用についてのターゲットに基づいてリソースを確保する必要があります。

ノードは、QoS (Quality of Service) を適用する新規の cgroup 階層を使用してリソースの制約を適用します。すべての Pod は、システムデーモンから切り離された専用の cgroup 階層で起動されます。

管理者は Guaranteed QoS (Quality of Service) のある Pod と同様にシステムデーモンを処理する必要があります。システムデーモンは、境界となる制御グループ内でバーストする可能性があり、この動作はクラスターのデプロイメントの一部として管理される必要があります。system-reserved で CPU およびメモリーリソースの量を指定し、システムデーモンの CPU およびメモリーリソースを予約します。

system-reserved 制限を適用すると、重要なシステムサービスが CPU およびメモリーリソースを受信できなることがあります。その結果、重要なシステムサービスは、out-of-memory killer によって終了する可能性があります。そのため、正確な推定値を判別するためにノードの徹底的なプロファイリングを実行した場合や、そのグループのプロセスが out-of-memory killer によって終了する場合に重要なシステムサービスが確実に復元できる場合にのみ system-reserved を適用することが推奨されます。

5.9.1.3. エビクションのしきい値について

ノードがメモリー不足の状態にある場合、ノード全体、およびノードで実行されているすべての Pod に影響が及ぶ可能性があります。たとえば、メモリーの予約量を超える量を使用するシステムデーモンは、メモリー不足のイベントを引き起こす可能性があります。システムのメモリー不足のイベントを防止するか、またはそれが発生する可能性を軽減するために、ノードはリソース不足の処理 (out of resource handling) を行います。

--eviction-hard フラグで一部のメモリーを予約することができます。ノードは、ノードのメモリー可用性が絶対値またはパーセンテージを下回る場合は常に Pod のエビクトを試行します。システムデーモンがノードに存在しない場合、Pod はメモリーの capacity - eviction-hard に制限されます。このため、メモリー不足の状態になる前にエビクションのバッファーとして確保されているリソースは Pod で利用することはできません。

以下の例は、割り当て可能なノードのメモリーに対する影響を示しています。

  • ノード容量: 32Gi
  • --system-reserved is 3Gi
  • --eviction-hard は 100Mi に設定される。

このノードについては、有効なノードの割り当て可能な値は 28.9Gi です。ノードおよびシステムコンポーネントが予約分をすべて使い切る場合、Pod に利用可能なメモリーは 28.9Gi となり、この使用量を超える場合に kubelet は Pod をエビクトします。

トップレベルの cgroup でノードの割り当て可能分 (28.9Gi) を適用する場合、Pod は 28.9Gi を超えることはできません。エビクションは、システムデーモンが 3.1Gi よりも多くのメモリーを消費しない限り実行されません。

上記の例ではシステムデーモンが予約分すべてを使い切らない場合も、ノードのエビクションが開始される前に、Pod では境界となる cgroup からの memcg OOM による強制終了が発生します。この状況で QoS をより効果的に実行するには、ノードですべての Pod のトップレベルの cgroup に対し、ハードエビクションしきい値が Node Allocatable + Eviction Hard Thresholds になるよう適用できます。

システムデーモンがすべての予約分を使い切らない場合で、Pod が 28.9Gi を超えるメモリーを消費する場合、ノードは Pod を常にエビクトします。エビクションが時間内に生じない場合には、Pod が 29Gi のメモリーを消費すると OOM による強制終了が生じます。

5.9.1.4. スケジューラーがリソースの可用性を判別する方法

スケジューラーは、node.Status.Capacity ではなく node.Status.Allocatable の値を使用して、ノードが Pod スケジューリングの候補になるかどうかを判別します。

デフォルトで、ノードはそのマシン容量をクラスターで完全にスケジュール可能であるとして報告します。

5.9.2. ノードのリソースの自動割り当て

OpenShift Container Platform は、特定のマシン設定プールに関連付けられたノードに最適な system-reserved CPU およびメモリーリソースを自動的に判別し、ノードの起動時にそれらの値を使用してノードを更新できます。デフォルトでは、system-reserved CPU は 500m で、system-reserved メモリーは 1Gi です。

ノード上で system-reserved リソースを自動的に判断して割り当てるには、KubeletConfig カスタムリソース (CR) を作成して autoSizingReserved: true パラメーターを設定します。各ノードのスクリプトにより、各ノードにインストールされている CPU およびメモリーの容量に基づいて、予約されたそれぞれのリソースに最適な値が計算されます。増加した容量を考慮に入れたスクリプトでは、予約リソースにもこれに対応する増加を反映させることが必要になります。

最適な system-reserved 設定を自動的に判別することで、クラスターが効率的に実行され、CRI-O や kubelet などのシステムコンポーネントのリソース不足によりノードが失敗することを防ぐことができます。この際、値を手動で計算し、更新する必要はありません。

この機能はデフォルトで無効にされています。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool オブジェクトに関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker
     ...

    1
    ラベルが Labels の下に表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    リソース割り当て CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: dynamic-node 1
    spec:
      autoSizingReserved: true 2
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 3

    1
    CR に名前を割り当てます。
    2
    true に設定された autoSizingReserved パラメーターを追加し、 OpenShift Container Platform が指定されたラベルに関連付けられたノード上で system-reserved リソースを自動的に判別し、割り当てることができます。それらのノードでの自動割り当てを無効にするには、このパラメーターを false に設定します。
    3
    マシン設定プールからラベルを指定します。

    上記の例では、すべてのワーカーノードでリソースの自動割り当てを有効にします。OpenShift Container Platform はノードをドレイン (解放) し、kubelet 設定を適用してノードを再起動します。

  2. 次のコマンドを入力して CR を作成します。

    $ oc create -f <file_name>.yaml

検証

  1. 次のコマンドを入力して、設定したノードにログインします。

    $ oc debug node/<node_name>
  2. /host をデバッグシェル内のルートディレクトリーとして設定します。

    # chroot /host
  3. /etc/node-sizing.env ファイルを表示します。

    出力例

    SYSTEM_RESERVED_MEMORY=3Gi
    SYSTEM_RESERVED_CPU=0.08

    kubelet は、/etc/node-sizing.env ファイルの system-reserved 値を使用します。上記の例では、ワーカーノードには 0.08 CPU および 3 Gi のメモリーが割り当てられます。更新が適用されるまでに数分の時間がかかることがあります。

5.9.3. ノードのリソースの手動割り当て

OpenShift Container Platform は、割り当てに使用する CPU および メモリーリソースタイプをサポートします。ephemeral-resource リソースタイプもサポートされます。cpu タイプについては、リソースの数量が、200m0.5、または 1 のようにコア単位で指定されます。memory および ephemeral-storage の場合、200Ki50Mi、または 5Gi などのバイト単位で指定されます。デフォルトでは、system-reserved CPU は 500m で、system-reserved メモリーは 1Gi です。

管理者として、(cpu=200m,memory=512Mi などの) <resource_type>=<resource_quantity> ペアのセットを使い、カスタムリソース (CR) を使用してこれらを設定することができます。

推奨される system-reserved 値の詳細は、推奨される system-reserved 値 を参照してください。

前提条件

  1. 次のコマンドを入力して、設定するノードタイプの静的な MachineConfigPool CRD に関連付けられたラベルを取得します。

    $ oc edit machineconfigpool <name>

    以下に例を示します。

    $ oc edit machineconfigpool worker

    出力例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      creationTimestamp: "2022-11-16T15:34:25Z"
      generation: 4
      labels:
        pools.operator.machineconfiguration.openshift.io/worker: "" 1
      name: worker

    1
    Labels の下にラベルが表示されます。
    ヒント

    ラベルが存在しない場合は、次のようなキー/値のペアを追加します。

    $ oc label machineconfigpool worker custom-kubelet=small-pods

手順

  1. 設定変更のためのカスタムリソース (CR) を作成します。

    リソース割り当て CR の設定例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-allocatable 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          pools.operator.machineconfiguration.openshift.io/worker: "" 2
      kubeletConfig:
        systemReserved: 3
          cpu: 1000m
          memory: 1Gi

    1
    CR に名前を割り当てます。
    2
    マシン設定プールからラベルを指定します。
    3
    ノードコンポーネントおよびシステムコンポーネント用に予約するリソースを指定します。
  2. 以下のコマンドを実行して CR を作成します。

    $ oc create -f <file_name>.yaml