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

より信頼性の高いスケジューリングを実現し、ノードにおけるリソースのオーバーコミットを最小限にするために、各ノードは、ホスト上のすべての基礎となる ノードコンポーネント (kubelet、kube-proxy など) および残りのシステムコンポーネント (sshdNetworkManager など) に使用されるリソースの一部を予約できます。指定されると、スケジューラーは、ノードが Pod に割り当てたリソース (例: メモリー、CPU) についての詳細な情報を取得できます。

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

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

設定説明

kube-reserved

ノードコンポーネント用に予約されたリソースです。デフォルトは none です。

system-reserved

残りのシステムコンポーネント用に予約されたリソースです。デフォルトは none です。

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

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

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

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

割り当て可能なリソースをノードレベルでエンドユーザー Pod に対して適用できるようになったことから、Hard-Eviction-Thresholds を割り当て可能なリソースから差し引く点は、システムの信頼性を強化するための動作の変更点になります。experimental-allocatable-ignore-eviction 設定は、レガシー動作を保持するために利用できますが、今後のリリースでは非推奨となります。

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

各ノードはコンテナーランタイムおよび kubelet によって利用されるシステムリソースについて報告します。--system-reserved および --kube-reserved の設定をより容易に行えるようにするには、ノード要約 API を使用して対応するノードのリソース使用状況をイントロスペクトできます。この API は /api/v1/nodes/<node>/proxy/stats/summary からアクセスできます。

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

ノードは、Pod が設定された割り当て可能な値に基づいて消費できるリソースの合計量を制限できます。この機能は、Pod がリソースのシステムサービス (例: コンテナーランタイム、ノードエージェントなど) のリソース不足の状態を防ぎ、ノードの信頼性を大幅に強化します。管理者に対しては、ノードの信頼性を強化するために必要なノードの使用状況のターゲットに基づいてリソースを予約することが強く奨励されます。

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

オプションとして、enforce-node-allocatable フラグでトークンを指定することで、ノードが kube で予約される制限およびシステムで予約される制限を実施するようにできます。これらが指定される場合、対応する --kube-reserved-cgroup または --system-reserved-cgroup を指定する必要があります。今後のリリースでは、ノードおよびコンテナーランタイムは system.slice と切り離された共通の cgroup でパッケージ化されます。パッケージ化されるまでは、ユーザーは enforce-node-allocatable フラグのデフォルト値を変更しないようにすることを推奨します。

管理者は Guaranteed Pod と同様にシステムデーモンを処理する必要があります。システムデーモンは、境界となる制御グループ内で予想外の動作をする可能性があり、この動作はクラスターデプロイメントの一部として管理される必要があります。システム予約の制限を実施することにより、ノード上の重要なシステムサービスで CPU が不足したり、OOM による強制終了が生じる可能性があります。そのため、オペレーターが正確な推定値を判別するためにノードの徹底的なプロファイリングを実行した場合や、そのグループのプロセスで OOM による強制終了が発生した場合に確実に復元できる場合にのみシステム予約の制限を実施することが推奨されます。

したがって、ユーザーはデフォルトで pods に対してのみノードの割り当て可能分を実施し、ノード全体の信頼性を維持するためにシステムデーモンの適切な予約を確保しておくことを強くお勧めします。

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

ノードがメモリー不足の状態にある場合、ノード全体、およびノードで実行されているすべての 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 による強制終了が生じます。

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

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

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

4.8.2. ノードに割り当てられるリソースの設定

OpenShift Container Platform は、割り当てに使用する CPU および メモリーリソースタイプをサポートします。管理者が一時ストレージのテクノロジープレビューを有効にしている場合、ephemeral-resource リソースタイプもサポートされます。cpu タイプについては、リソースの数量が、200m0.5、または 1 のようにコア単位で指定されます。memory および ephemeral-storage の場合、200Ki50Mi、または 5Gi などのバイト単位で指定されます。

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

前提条件

  1. --system-reserved および --kube-reserved の設定を決定しやすくするには、ノード要約 API を使用して対応するノードのリソース使用状況をイントロスペクトできます。この API は /api/v1/nodes/<node>/proxy/stats/summary からアクセスできます。ノードについて以下のコマンドを入力します。

    $ oc get --raw /api/v1/nodes/<node>/proxy/stats/summary

    たとえば、cluster.node22 ノードからリソースにアクセスするには、以下の手順を入力できます。

    $ oc get --raw /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"
                }
            ]
        }
    }
  2. 設定したいノードタイプの静的な Machine Config Pool CRD に関連付けられたラベルを取得します。以下のいずれかの手順を実行します。

    1. マシンの Config Pool を表示します。

      $ oc describe machineconfigpool <name>

      以下は例になります。

      $ oc describe machineconfigpool worker
      
      apiVersion: machineconfiguration.openshift.io/v1
      kind: MachineConfigPool
      metadata:
        creationTimestamp: 2019-02-08T14:52:39Z
        generation: 1
        labels:
          custom-kubelet: small-pods 1
      1
      ラベルが追加されると、labels の下に表示されます。
    2. ラベルが存在しない場合は、キー/値のペアを追加します。

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

手順

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

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

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-allocatable 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: small-pods 2
      kubeletConfig:
        systemReserved:
          cpu: 500m
          memory: 512Mi
        kubeReserved:
          cpu: 500m
          memory: 512Mi