6.9. OpenShift Container Platform クラスター内のノードへのリソース割り当て
より信頼性の高いスケジューリングを実現し、ノードにおけるリソースのオーバーコミットを最小限にするために、kubelet
および kube-proxy
などの基礎となるノードのコンポーネント、および sshd
および NetworkManager
などの残りのシステムコンポーネントに使用される CPU およびメモリーリソースの一部を予約します。予約するリソースを指定して、スケジューラーに、ノードが Pod で使用できる残りの CPU およびメモリーリソースの詳細を提供します。OpenShift Container Platform がノードに 最適な system-reserved
CPU およびメモリーリソースを自動的に決定できるようにする ことも、ノードに 最適なリソースを手動で決定して設定する こともできます。
リソース値を手動で設定するには、kubelet config CR を使用する必要があります。machine config CR は使用できません。
6.9.1. ノードにリソースを割り当てる方法について
OpenShift Container Platform 内のノードコンポーネントの予約された CPU とメモリーリソースは、2 つのノード設定に基づいています。
設定 | 説明 |
---|---|
|
この設定は OpenShift Container Platform では使用されません。確保する予定の CPU およびメモリーリソースを |
|
この設定は、CRI-O および Kubelet などのノードコンポーネントおよびシステムコンポーネント用に予約するリソースを特定します。デフォルト設定は、OpenShift Container Platform および Machine Config Operator のバージョンによって異なります。 |
フラグが設定されていない場合、デフォルトが使用されます。いずれのフラグも設定されていない場合、割り当てられるリソースは、割り当て可能なリソースの導入前であるためにノードの容量に設定されます。
reservedSystemCPUs
パラメーターを使用して予約される CPU は、kube-reserved
または system-reserved
を使用した割り当てには使用できません。
6.9.1.1. OpenShift Container Platform による割り当てられたリソースの計算方法
割り当てられたリソースの量は、以下の数式に基づいて計算されます。
[Allocatable] = [Node Capacity] - [system-reserved] - [Hard-Eviction-Thresholds]
Allocatable
の値がノードレベルで Pod に対して適用されるために、Hard-Eviction-Thresholds
を Allocatable
から差し引くと、システムの信頼性が強化されます。
Allocatable
が負の値の場合、これは 0
に設定されます。
各ノードは、コンテナーランタイムおよび kubelet によって利用されるシステムリソースを報告します。system-reserved
パラメーターの設定を簡素化するには、ノード要約 API を使用してノードに使用するリソースを表示します。ノードの要約は /api/v1/nodes/<node>/proxy/stats/summary
で利用できます。
6.9.1.2. ノードによるリソースの制約の適用方法
ノードは、Pod が設定された割り当て可能な値に基づいて消費できるリソースの合計量を制限できます。この機能は、Pod がシステムサービス (コンテナーランタイム、ノードエージェントなど) で必要とされる CPU およびメモリーリソースを使用することを防ぎ、ノードの信頼性を大幅に強化します。ノードの信頼性を強化するために、管理者はリソースの使用に関するターゲットに基づいてリソースを確保する必要があります。
ノードは、quality of service を適用する新規の cgroup 階層を使用してリソースの制約を適用します。すべての Pod は、システムデーモンから切り離された専用の cgroup 階層で起動されます。
管理者は quality of service のある Pod と同様にシステムデーモンを処理する必要があります。システムデーモンは、境界となる制御グループ内でバーストする可能性があり、この動作はクラスターのデプロイメントの一部として管理される必要があります。system-reserved
で CPU およびメモリーリソースの量を指定し、システムデーモンの CPU およびメモリーリソースを予約します。
system-reserved
制限を適用すると、重要なシステムサービスが CPU およびメモリーリソースを受信できなることがあります。その結果、重要なシステムサービスは、out-of-memory killer によって終了する可能性があります。そのため、正確な推定値を判別するためにノードの徹底的なプロファイリングを実行した場合や、そのグループのプロセスが out-of-memory killer によって終了する場合に重要なシステムサービスが確実に復元できる場合にのみ system-reserved
を適用することが推奨されます。
6.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 による強制終了が生じます。
6.9.1.4. スケジューラーがリソースの可用性を判別する方法
スケジューラーは、node.Status.Capacity
ではなく node.Status.Allocatable
の値を使用して、ノードが Pod スケジューリングの候補になるかどうかを判別します。
デフォルトで、ノードはそのマシン容量をクラスターで完全にスケジュール可能であるとして報告します。
6.9.2. プロセス ID の制限について
プロセス識別子 (PID) は、システム上で現在実行されている各プロセスまたはスレッドに Linux カーネルによって割り当てられる一意の識別子です。システム上で同時に実行できるプロセスの数は、Linux カーネルによって 4,194,304 に制限されています。この数値は、メモリー、CPU、ディスク容量などの他のシステムリソースへのアクセス制限によっても影響を受ける可能性があります。
OpenShift Container Platform では、クラスターで作業をスケジュールする前に、プロセス ID (PID) の使用に関してサポートされている次の 2 つの制限を考慮してください。
Pod あたりの PID の最大数。
OpenShift Container Platform 4.11 以降では、デフォルト値は 4,096 です。この値はノードに設定された
podPidsLimit
パラメーターによって制御されます。chroot
環境で次のコマンドを実行すると、ノード上の現在の PID 制限を表示できます。sh-5.1# cat /etc/kubernetes/kubelet.conf | grep -i pids
出力例
"podPidsLimit": 4096,
podPidsLimit
は、KubeletConfig
オブジェクトを使用して変更できます。「Kubelet パラメーターを編集するための KubeletConfig CR の作成」を参照してください。コンテナーは親 Pod から
podPidsLimit
値を継承するため、カーネルは 2 つの制限のうち低い方を適用します。たとえば、コンテナーの PID 制限が最大値に設定されていても、Pod の PID 制限が4096
の場合、Pod 内の各コンテナーの PID 制限は 4096 に制限されます。ノードあたりの PID の最大数。
デフォルト値はノードのリソースによって異なります。OpenShift Container Platform では、この値は kubelet 設定の
systemReserved
パラメーターによって制御されます。このパラメーターにより、ノードの合計リソースに基づいて各ノードの PID が予約されます。詳細は、「OpenShift Container Platform クラスター内のノードへのリソース割り当て」を参照してください。
Pod あたりの PID の最大許容数を超えると、Pod が正しく機能しなくなり、ノードから削除される可能性があります。詳細は、エビクションシグナルとしきい値に関する Kubernetes ドキュメント を参照してください。
ノードあたりの PID の最大許容数を超えると、ノードが不安定になる可能性があります。これは新しいプロセスに PID を割り当てることができなくなるためです。追加のプロセスを作成せずに既存のプロセスを完了できない場合、ノード全体が使用できなくなり、リブートが必要になる可能性があります。このような状況では、実行中のプロセスやアプリケーションによっては、データ損失が発生する可能性があります。このしきい値に達すると、お客様の管理者と Red Hat Site Reliability Engineering に通知が送信されます。また、Worker node is experiencing PIDPressure
という警告がクラスターログに表示されます。
6.9.2.1. OpenShift Container Platform Pod のプロセス ID 制限の設定を引き上げることのリスク
Pod の podPidsLimit
パラメーターは、その Pod 内で同時に実行できるプロセスとスレッドの最大数を制御するものです。
podPidsLimit
の値は、デフォルトの 4,096 から最大 16,384 まで増やすことができます。podPidsLimit
を変更するには、影響を受けるノードをリブートする必要があります。そのため、この値を変更すると、アプリケーションのダウンタイムが発生する可能性があります。
各ノードで多数の Pod を実行しており、ノードの podPidsLimit
値が高い場合は、ノードの PID 最大値を超えるおそれがあります。
1 つのノードでノードの PID 最大値を超えずに同時に実行できる Pod の最大数を確認するには、3,650,000 を podPidsLimit
値で割ります。たとえば、podPidsLimit
値が 16,384 で、Pod がそれに近い数のプロセス ID を使用すると予想される場合、1 つのノードで 222 個の Pod を安全に実行できます。
podPidsLimit
値が適切に設定されている場合でも、メモリー、CPU、および利用可能なストレージによって、同時に実行できる Pod の最大数が制限される場合があります。
6.9.3. ノードのリソースの自動割り当て
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 などのシステムコンポーネントのリソース不足によりノードが失敗することを防ぐことができます。この際、値を手動で計算し、更新する必要はありません。
この機能はデフォルトで無効にされています。
前提条件
次のコマンドを入力して、設定するノードタイプの静的な
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
手順
設定変更のためのカスタムリソース (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
- 「前提条件」セクションで設定したマシン設定プールからラベルを指定します。マシン設定プールのラベルは、
custom-kubelet: small-pods
などの任意のラベルか、デフォルトラベルのpools.operator.machineconfiguration.openshift.io/worker: ""
を選択できます。
上記の例では、すべてのワーカーノードでリソースの自動割り当てを有効にします。OpenShift Container Platform はノードをドレイン (解放) し、kubelet 設定を適用してノードを再起動します。
次のコマンドを入力して CR を作成します。
$ oc create -f <file_name>.yaml
検証
次のコマンドを入力して、設定したノードにログインします。
$ oc debug node/<node_name>
/host
をデバッグシェル内のルートディレクトリーとして設定します。# chroot /host
/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 のメモリーが割り当てられます。更新が適用されるまでに数分の時間がかかることがあります。
6.9.4. ノードのリソースの手動割り当て
OpenShift Container Platform は、割り当てに使用する CPU およびメモリーリソースタイプをサポートします。ephemeral-resource
リソースタイプもサポートされています。cpu
タイプの場合、リソース数量をコア単位で指定します (例: 200m
、0.5
、1
)。memory
および ephemeral-storage
の場合、リソース数量をバイト単位で指定します (例: 200Ki
、50Mi
、5Gi
)。デフォルトでは、system-reserved
CPU は 500m
で、system-reserved
メモリーは 1Gi
です。
管理者は、kubelet config カスタムリソース (CR) を使用して、一連の <resource_type>=<resource_quantity>
ペア (例: cpu=200m,memory=512Mi
) を設定できます。
リソース値を手動で設定するには、kubelet config CR を使用する必要があります。machine config CR は使用できません。
推奨される system-reserved
値の詳細は、推奨される system-reserved 値 を参照してください。
前提条件
次のコマンドを入力して、設定するノードタイプの静的な
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
手順
設定変更のためのカスタムリソース (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 #...
以下のコマンドを実行して CR を作成します。
$ oc create -f <file_name>.yaml