第23章 ノードリソースの割り当て
23.1. 概要
より信頼性の高いスケジューリングを提供し、ノードにおけるリソースのオーバーコミットを最小限にするために、各ノードは、ホスト上のすべての基礎となる ノードコンポーネント (例: kubelet、kube-proxy、Docker) および残りのシステムコンポーネント (例: sshd、NetworkManager) に使用される分をリソースの一部として保持できます。このリソースが指定されると、スケジューラーは、ノードが Pod に割り当てたリソース (例: メモリー、CPU) についての詳細な情報を取得できます。
23.2. 割り当てられるリソースについてのノードの設定
ノードコンポーネント用に予約されたリソースは 2 つのノード設定に基づきます。
設定 | 説明 |
---|---|
|
ノードコンポーネント用に予約されたリソースです。デフォルトは none です。 |
|
残りのシステムコンポーネント用に予約されたリソースです。デフォルトは none です。 |
これらは、<resource_type>=<resource_quantity>
ペアのセット (例: cpu=200m,memory=512Mi) を使用してノード設定マップの kubeletArguments
セクションに設定することができます。このセクションは、すでに存在しない場合は追加します。
node-config.yaml
ファイルを直接編集しないでください。
例23.1 ノードの割り当て可能なリソースの設定
kubeletArguments: kube-reserved: - "cpu=200m,memory=512Mi" system-reserved: - "cpu=200m,memory=512Mi"
OpenShift Container Platform は現時点では、cpu
および memory
リソースタイプをサポートします。管理者が一時ストレージのテクノロジープレビューを有効にしている場合、ephemeral-resource
リソースタイプもサポートされます。cpu
については、リソースの数量が、200m
、0.5
、または 1
のようにコア単位で指定されます。memory
および ephemeral-storage
の場合、200Ki
、50Mi
、または 5Gi
などのバイト単位で指定されます。
一時ストレージの管理機能はデフォルトで無効にされています。この機能を有効にするには、「一時ストレージの設定」を参照してください。
詳細は、「コンピュートリソース」を参照してください。
フラグが設定されていない場合、これはデフォルトで 0 になります。フラグのいずれも設定されていない場合、割り当てられるリソースは、割り当て可能なリソースの導入前であるためにノードの容量に設定されます。
23.3. 割り当てられるリソースの計算
リソースの割り当てられる量は以下の数式に基づいて計算されます。
[Allocatable] = [Node Capacity] - [kube-reserved] - [system-reserved] - [Hard-Eviction-Thresholds]
Hard-Eviction-Thresholds
を割り当て可能なリソースから差し引く点はシステムの信頼性を強化するための動作の変更点です。この値に基づいて割り当て可能なリソースをノードレベルでエンドユーザー Pod に対して適用できます。experimental-allocatable-ignore-eviction
設定は、レガシー動作を保持するために利用できますが、今後のリリースでは非推奨となります。
[Allocatable]
が負の値の場合、これは 0 に設定されます。
23.4. ノードの割り当て可能なリソースおよび容量の表示
ノードの現在の容量および割り当て可能なリソースを表示するには、以下を実行できます。
$ oc get node/<node_name> -o yaml ... status: ... allocatable: cpu: "4" memory: 8010948Ki pods: "110" capacity: cpu: "4" memory: 8010948Ki pods: "110" ...
23.5. ノードによって報告されるシステムリソース
OpenShift Container Platform 3.3 より、各ノードはコンテナーランタイムおよび kubelet によって利用されるシステムリソースについて報告します。--system-reserved
および --kube-reserved
の設定をより容易に行えるようにするには、ノード要約 API を使用して対応するノードのリソース使用状況をインストロスペクトできます。この API は <master>/api/v1/nodes/<node>/proxy/stats/summary からアクセスできます。
たとえば、cluster.node22 ノードからリソースにアクセスするには、以下を実行できます。
$ curl <certificate details> https://<master>/api/v1/nodes/cluster.node22/proxy/stats/summary { "node": { "nodeName": "cluster.node22", "systemContainers": [ { "cpu": { "usageCoreNanoSeconds": 929684480915, "usageNanoCores": 190998084 }, "memory": { "rssBytes": 176726016, "usageBytes": 1397895168, "workingSetBytes": 1050509312 }, "name": "kubelet" }, { "cpu": { "usageCoreNanoSeconds": 128521955903, "usageNanoCores": 5928600 }, "memory": { "rssBytes": 35958784, "usageBytes": 129671168, "workingSetBytes": 102416384 }, "name": "runtime" } ] } }
証明書の詳細については、「REST API Overview」を参照してください。
23.6. ノードの実施
ノードは、Pod が設定された割り当て可能な値に基づいて消費できるリソースの合計量を制限できます。この機能は、Pod がリソースのシステムサービス (例: コンテナーランタイム、ノードエージェントなど) のリソース不足の状態を防ぎ、ノードの信頼性を大幅に強化します。管理者におかれましては、ノードの信頼性を強化するために必要なノードの使用状況のターゲットに基づいてリソースを予約することを強く奨励します。
ノードは、QoS (Quality of Service) を実施する新規の cgroup 階層を使用してリソースの制約を実施します。すべての Pod は、システムデーモンと切り離された専用の cgroup 階層で起動します。
この機能を設定するために、以下の kubelet 引数を指定します。
例23.2 ノードの cgroup 設定
kubeletArguments: cgroups-per-qos: - "true" 1 cgroup-driver: - "systemd" 2 enforce-node-allocatable: - "pods" 3
- 1
- ノードによって管理される新規の cgroup 階層を有効化または無効化します。この設定の変更にはノードの完全なドレイン (解放) が必要になります。このフラグは、ノードがノードの割り当て可能分を実施できるようにするには true である必要があります。ユーザーにはこの値を変更しないようにすることを推奨します。
- 2
- cgroup 階層を管理する際にノードで使用される cgroup ドライバーです。この値はコンテナーランタイムに関連付けられたドライバーに一致する必要があります。有効な値は
systemd
およびcgroupfs
です。デフォルトはsystemd
です。 - 3
- ノードがノードのリソース制約を実施するスコープのカンマ区切りの一覧です。有効な値は
pods
、system-reserved
、およびkube-reserved
です。デフォルトはpods
です。ユーザーにはこの値を変更しないようにすることを推奨します。
オプションとして、enforce-node-allocatable フラグでトークンを指定することで、ノードが kube で予約される制限およびシステムで予約される制限を実施するようにできます。これらが指定される場合、対応する --kube-reserved-cgroup
または --system-reserved-cgroup
を指定する必要があります。今後のリリースでは、ノードおよびコンテナーランタイムは system.slice
と切り離された共通の cgroup でパッケージ化されます。パッケージ化されるまでは、ユーザーは enforce-node-allocatable フラグのデフォルト値を変更しないようにすることを推奨します。
管理者は Guaranteed Pod と同様にシステムデーモンを処理する必要があります。システムデーモンは、境界となる制御グループ内で予想外の動作をする可能性があり、この動作はクラスターデプロイメントの一部として管理される必要があります。システム予約の制限を実施することにより、ノード上の重要なシステムサービスで CPU が不足したり、OOM による強制終了が生じる可能性があります。そのため、オペレーターが正確な推定値を判別するためにノードの徹底的なプロファイリングを実行した場合や、そのグループのプロセスで OOM による強制終了が発生した場合に確実に復元できる場合にのみシステム予約の制限を実施することが推奨されます。
したがって、ユーザーはデフォルトで pods
に対してのみノードの割り当て可能分を実施し、ノード全体の信頼性を維持するためにシステムデーモンの適切な予約を確保しておくことを強くお勧めします。
23.7. エビクションしきい値
ノードがメモリー不足の状態にある場合、ノード全体に、またノードで実行されているすべての Pod に影響が及ぶ可能性があります。システムデーモンによるメモリーの使用がメモリーの予約されている量を超える場合、OOM イベントが発生し、ノード全体やノードで実行されているすべての Pod に影響が及び可能性があります。システムの OOM を防止する (またはその発生可能性を下げる) ために、ノードは Out Of Resource Handling (リソース不足の処理) を行います。
--eviction-hard
フラグで一部のメモリーを確保することで、ノードは、ノードのメモリー可用性が絶対値またはパーセンテージを下回る場合は常に Pod のエビクトを試行します。システムデーモンがノードに存在しない場合、Pod はメモリーの capacity - eviction-hard
に制限されます。このため、メモリー不足の状態になる前にエビクションのバッファーとして確保されているリソースは Pod で利用することはできません。
以下の例は、ノードの割り当て可能分のメモリーに対する影響について説明しています。
-
ノード容量:
32Gi
-
--kube reserved:
2Gi
-
--system-reserved:
1Gi
-
--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 による強制終了が生じます。
23.8. スケジューラー
スケジューラーは、node.Status.Capacity
ではなく node.Status.Allocatable
の値を使用して、ノードが Pod スケジューリングの候補になるかどうかを判別します。
デフォルトで、ノードはそのマシン容量をクラスターで完全にスケジュール可能であるとして報告します。