6.12. OpenShift Container Platform クラスター内のノードへのリソース割り当て
デフォルトでは、ノードの起動時に、OpenShift Container Platform は、kubelet や kube-proxy などの基盤となるノードコンポーネントと、sshd や NetworkManager などの残りのシステムコンポーネントが使用する CPU およびメモリーリソースの一部を自動的に計算して予約します。このセクションの情報を確認し、これらの自動設定がご使用のクラスターに適しているか判断してください。
Kubelet Config CR を作成することで、必要に応じてこれらのノードおよびシステムコンポーネントの CPU およびメモリーリソースを変更できます。
クラスターをバージョン 4.21 より前のバージョンから更新した場合、システムリソースの自動割り当てはデフォルトで無効化されます。この機能を有効化するには、50-worker-auto-sizing-disabled マシン設定を削除してください。
6.12.1. ノードへのリソースの割り当て方法を理解する リンクのコピーリンクがクリップボードにコピーされました!
OpenShift Container Platform は、スクリプトを使用して、ノードおよびノード上のシステムコンポーネントに最適な CPU とメモリーのリソースを決定します。または、必要に応じてこれらの値を手動で設定することもできます。これらのサービスに適切なリソースを確保することで、クラスターを効率的に運用できるようになります。
これらのリソース計算は、各ノードにインストールされている CPU とメモリー容量に基づいて行われ、ノードの起動時に割り当てられます。これらのリソースは、CRI-O や kubelet など、systemd system.slice cgroup 内のノードおよびシステムコンポーネント用に予約されています。デフォルトでは、スクリプトが実行される前に、OpenShift Container Platform はノードおよびシステムコンポーネント用として CPU を 500m、メモリーを 1 Gi 予約します。
Kubernetes の kubeReserved パラメーターは、OpenShift Container Platform ではサポートされていません。
このスクリプトは、デフォルトで以下の計算式を使用します。
- メモリー予約
メモリー予約には重み付けがされています。小規模なノードの場合、OpenShift Container Platform はより高い割合のメモリーを予約します。ノードの規模が大きい場合、OpenShift Container Platform は残りの容量のうち、より小さな割合を予約します。
OpenShift Container Platform は、ノードおよびシステムコンポーネント用に予約するメモリー量を決定するために、以下の計算式を使用します。
- 最初の 4GiB のメモリーの 25%
- 次の 4GiB のメモリーの 20% (最大 8GiB まで)
- 次の 8 GiB のメモリーの 10% (最大 16 GiB まで)
- 次の 112 GiB のメモリーの 6% (最大 128 GiB まで)
- 128 GiB を超える分のメモリーの 2%
たとえば、16 GiB のメモリーを搭載したノードでは、OpenShift Container Platform はノードおよびシステムコンポーネント用に 2.6 GiB を予約し、ワークロード用に約 13.4 GiB を残します。
- CPU 予約
OpenShift Container Platform は、以下のロジックを使用して、ノードおよびシステムコンポーネント用に予約する CPU 量を決定します。
- OpenShift Container Platform は、1 つ目の CPU を基準としたコアの端数 (60 ミリコア = 0.06 CPU コア) を基本割り当てとして設定します。
- その後、2 つ目以降の CPU コアに対して、1 コア追加されるごとに 12 ミリコア (0.012 CPU) ずつ加算します。
- 結果は、下限値である 0.5 CPU と比較されます。計算値が 0.5 未満の場合、システムは 0.5 CPU の予約を強制的に行います。
たとえば、4 コアのノードでは、0.5 仮想 CPU がノードおよびシステムコンポーネント用に予約され、残りの 3.5 仮想 CPU がワークロードに割り当てられます。1000 ミリコアは 1CPU/仮想 CPU に相当することに注意してください。
注記KubeletConfigオブジェクトのreservedSystemCPUsパラメーターを使用して明示的に予約された CPU は、system-reservedを使用して割り当てることはできません。
「ノードのリソースの手動割り当て」で説明されているように、KubeletConfig オブジェクトの system-reserved パラメーターを設定することで、ノードおよびシステムコンポーネントの CPU とメモリーの予約を手動で管理できます。
6.12.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.12.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.12.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.12.1.4. スケジューラーがリソースの可用性を判別する方法 リンクのコピーリンクがクリップボードにコピーされました!
スケジューラーは、node.Status.Capacity ではなく node.Status.Allocatable の値を使用して、ノードが Pod スケジューリングの候補になるかどうかを判別します。
デフォルトで、ノードはそのマシン容量をクラスターで完全にスケジュール可能であるとして報告します。