2.10. Pod スケジューリングの決定に Pod の優先順位を含める
クラスターで Pod の優先順位およびプリエンプションを有効にできます。Pod の優先度は、他の Pod との比較した Pod の重要度を示し、その優先度に基づいて Pod をキューに入れます。Pod のプリエンプションは、クラスターが優先順位の低い Pod のエビクトまたはプリエンプションを実行することを可能にするため、適切なノードに利用可能な領域がない場合に優先順位のより高い Pod をスケジュールできます。 Pod の優先順位は Pod のスケジューリングの順序にも影響を与え、リソース不足の場合のノード上でのエビクションの順序に影響を与えます。
優先順位およびプリエンプションを使用するには、Pod の相対的な重みを定義する優先順位クラスを作成します。次に Pod 仕様で優先順位クラスを参照し、スケジューリングの重みを適用します。
2.10.1. Pod の優先順位について
Pod の優先順位およびプリエンプション機能を使用する場合、スケジューラーは優先順位に基づいて保留中の Pod を順序付け、保留中の Pod はスケジューリングのキューで優先順位のより低い他の保留中の Pod よりも前に置かれます。その結果、より優先順位の高い Pod は、スケジューリングの要件を満たす場合に優先順位の低い Pod よりも早くスケジュールされる可能性があります。Pod をスケジュールできない場合、スケジューラーは引き続き他の優先順位の低い Pod をスケジュールします。
2.10.1.1. Pod の優先順位クラス
Pod には優先順位クラスを割り当てることができます。これは、名前から優先順位の整数値へのマッピングを定義する namespace を使用していないオブジェクトです。値が高いと優先順位が高くなります。
優先順位およびプリエンプションは、1000000000 (10 億) 以下の 32 ビットの整数値を取ることができます。プリエンプションやエビクションを実行すべきでない Critical Pod 用に 10 億以上の数値を予約する必要があります。デフォルトで、OpenShift Container Platform には 2 つの予約された優先順位クラスがあり、これらは重要なシステム Pod で保証されたスケジューリングが適用されるために使用されます。
$ oc get priorityclasses
出力例
NAME VALUE GLOBAL-DEFAULT AGE system-node-critical 2000001000 false 72m system-cluster-critical 2000000000 false 72m openshift-user-critical 1000000000 false 3d13h cluster-logging 1000000 false 29s
system-node-critical: この優先順位クラスには 2000001000 の値があり、ノードからエビクトすべきでないすべての Pod に使用されます。この優先順位クラスを持つ Pod の例として、
sdn-ovs
、sdn
などがあります。数多くの重要なコンポーネントには、デフォルトでsystem-node-critical
の優先順位クラスが含まれます。以下は例になります。- master-api
- master-controller
- master-etcd
- sdn
- sdn-ovs
- sync
system-cluster-critical: この優先順位クラスには 2000000000 (20 億) の値があり、クラスターに重要な Pod に使用されます。この優先順位クラスの Pod は特定の状況でノードからエビクトされる可能性があります。たとえば、
system-node-critical
優先順位クラスで設定される Pod が優先される可能性があります。この場合でも、この優先順位クラスではスケジューリングが保証されます。この優先順位クラスを持つ可能性のある Pod の例として、fluentd、descheduler などのアドオンコンポーネントなどがあります。数多くの重要なコンポーネントには、デフォルトでsystem-cluster-critical
優先順位クラスが含まれます。 以下はその一例です。- fluentd
- metrics-server
- descheduler
-
openshift-user-critical:
priorityClassName
フィールドを、リソース消費をバインドできず、予測可能なリソース消費動作がない重要な Pod で使用できます。openshift-monitoring
およびopenshift-user-workload-monitoring
namespace 下にある Prometheus Pod は、openshift-user-critical
priorityClassName
を使用します。モニタリングのワークロードはsystem-critical
を最初のpriorityClass
として使用しますが、これにより、モニタリング時にメモリーが過剰に使用され、ノードがエビクトできない問題が発生します。その結果、モニタリングの優先順位が下がり、スケジューラーに柔軟性が与えられ、重要なノードの動作を維持するために重いワークロード発生します。 - cluster-logging: この優先順位は、Fluentd Pod が他のアプリケーションより優先してノードにスケジュールされるようにするために Fluentd で使用されます。
2.10.1.2. Pod の優先順位名
1 つ以上の優先順位クラスを準備した後に、Pod
仕様に優先順位クラス名を指定する Pod を作成できます。優先順位の受付コントローラーは、優先順位クラス名フィールドを使用して優先順位の整数値を設定します。名前付きの優先順位クラスが見つからない場合、Pod は拒否されます。
2.10.2. Pod のプリエンプションについて
開発者が Pod を作成する場合、Pod はキューに入れられます。開発者が Pod の優先順位またはプリエンプションを設定している場合、スケジューラーはキューから Pod を選択し、Pod をノードにスケジュールしようとします。スケジューラーが Pod について指定されたすべての要件を満たす適切なノードに領域を見つけられない場合、プリエンプションロジックが保留中の Pod についてトリガーされます。
スケジューラーがノードで 1 つ以上の Pod のプリエンプションを実行する場合、優先順位の高い Pod
仕様の nominatedNodeName
フィールドは、nodename
フィールドと共にノードの名前に設定されます。スケジューラーは nominatedNodeName
フィールドを使用して Pod の予約されたリソースを追跡し、またクラスターのプリエンプションに関する情報をユーザーに提供します。
スケジューラーが優先順位の低い Pod のプリエンプションを実行した後に、スケジューラーは Pod の正常な終了期間を許可します。スケジューラーが優先順位の低い Pod の終了を待機する間に別のノードが利用可能になると、スケジューラーはそのノードに優先順位の高い Pod をスケジュールできます。その結果、Pod
仕様の nominatedNodeName
フィールドおよび nodeName
フィールドが異なる可能性があります。
さらに、スケジューラーがノード上で Pod のプリエンプションを実行し、終了を待機している場合で、保留中の Pod よりも優先順位の高い Pod をスケジュールする必要がある場合、スケジューラーは代わりに優先順位の高い Pod をスケジュールできます。その場合、スケジューラーは保留中の Pod の nominatedNodeName
をクリアし、その Pod を他のノードの対象とすることができます。
プリエンプションは、ノードから優先順位の低いすべての Pod を削除する訳ではありません。スケジューラーは、優先順位の低い Pod の一部を削除して保留中の Pod をスケジュールできます。
スケジューラーは、保留中の Pod をノードにスケジュールできる場合にのみ、Pod のプリエンプションを実行するノードを考慮します。
2.10.2.1. プリエンプションを実行しない優先順位クラス
プリエンプションポリシーが Never
に設定された Pod は優先順位の低い Pod よりも前のスケジューリングキューに置かれますが、他の Pod のプリエンプションを実行することはできません。スケジュールを待機しているプリエンプションを実行しない Pod は、十分なリソースが解放され、これがスケジュールされるまでスケジュールキュー内に留まります。他の Pod などのプリエンプションを実行しない Pod はスケジューラーのバックオフの対象になります。つまり、スケジューラーがこれらの Pod のスケジュールの試行に成功しない場合、低頻度で再試行されるため、優先順位の低い他の Pod をそれらの Pod よりも前にスケジュールできます。
プリエンプションを実行しない Pod については、他の優先順位の高い Pod が依然としてプリエンプションを実行できます。
2.10.2.2. Pod プリエンプションおよび他のスケジューラーの設定
Pod の優先順位およびプリエンプションを有効にする場合、他のスケジューラー設定を考慮します。
- Pod の優先順位および Pod の Disruption Budget (停止状態の予算)
- Pod の Disruption Budget (停止状態の予算) は一度に稼働している必要のあるレプリカの最小数またはパーセンテージを指定します。Pod の Disruption Budget (停止状態の予算) を指定する場合、OpenShift Container Platform は、Best Effort レベルで Pod のプリエンプションを実行する際にそれらを適用します。スケジューラーは、Pod の Disruption Budget (停止状態の予算) に違反しない範囲で Pod のプリエンプションを試行します。該当する Pod が見つからない場合には、Pod の Disruption Budget (停止状態の予算) の要件を無視して優先順位の低い Pod のプリエンプションが実行される可能性があります。
- Pod の優先順位およびアフィニティー
- Pod のアフィニティーは、新規 Pod が同じラベルを持つ他の Pod と同じノードにスケジュールされることを要求します。
保留中の Pod にノード上の 1 つ以上の優先順位の低い Pod との Pod 間のアフィニティーがある場合、スケジューラーはアフィニティーの要件を違反せずに優先順位の低い Pod のプリエンプションを実行することはできません。この場合、スケジューラーは保留中の Pod をスケジュールするための別のノードを探します。ただし、スケジューラーが適切なノードを見つけることは保証できず、保留中の Pod がスケジュールされない可能性があります。
この状態を防ぐには、優先順位が等しい Pod との Pod のアフィニティーの設定を慎重に行ってください。
2.10.2.3. プリエンプションが実行された Pod の正常な終了
Pod のプリエンプションの実行中、スケジューラーは Pod の正常な終了期間が期限切れになるのを待機します。その後、Pod は機能を完了し、終了します。Pod がこの期間後も終了しない場合、スケジューラーは Pod を強制終了します。 この正常な終了期間により、スケジューラーによる Pod のプリエンプションの実行時と保留中の Pod のノードへのスケジュール時に時間差が出ます。
この時間差を最小限にするには、優先順位の低い Pod の正常な終了期間を短く設定します。
2.10.3. 優先順位およびプリエンプションの設定
Pod 仕様で priorityClassName
を使用して優先順位クラスオブジェクトを作成し、Pod を優先順位に関連付けることで、Pod の優先度およびプリエンプションを適用できます。
優先クラスを既存のスケジュール済み Pod に直接追加することはできません。
手順
優先順位およびプリエンプションを使用するようにクラスターを設定するには、以下を実行します。
1 つ以上の優先順位クラスを作成します。
以下のような YAML ファイルを作成します。
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: high-priority 1 value: 1000000 2 preemptionPolicy: PreemptLowerPriority 3 globalDefault: false 4 description: "This priority class should be used for XYZ service pods only." 5
- 1
- 優先順位クラスオブジェクトの名前です。
- 2
- オブジェクトの優先順位の値です。
- 3
- オプション: この優先クラスがプリエンプティングであるか非プリエンプティングであるかを指定します。プリエンプションポリシーは、デフォルトで
PreemptLowerPriority
に設定されます。これにより、その優先順位クラスの Pod はそれよりも優先順位の低い Pod のプリエンプションを実行できます。プリエンプションポリシーがNever
に設定される場合、その優先順位クラスの Pod はプリエンプションを実行しません。 - 4
- オプション: 優先クラス名が指定されていない Pod にこの優先クラスを使用するかどうかを指定します。このフィールドはデフォルトで
false
です。globalDefault
がtrue
に設定される 1 つの優先順位クラスのみがクラスター内に存在できます。globalDefault:true
が設定された優先順位クラスがない場合、優先順位クラス名が設定されていない Pod の優先順位はゼロになります。globalDefault:true
が設定された優先順位クラスを追加すると、優先順位クラスが追加された後に作成された Pod のみがその影響を受け、これによって既存 Pod の優先順位は変更されません。 - 5
- オプション: 開発者がこの優先クラスで使用する必要がある Pod を説明します。任意の文字列を入力します。
優先クラスを作成します。
$ oc create -f <file-name>.yaml
優先クラスの名前を含む Pod 仕様を作成します。
以下のような YAML ファイルを作成します。
apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent priorityClassName: high-priority 1
- 1
- この Pod で使用する優先順位クラスを指定します。
Pod を作成します。
$ oc create -f <file-name>.yaml
優先順位の名前は Pod 設定または Pod テンプレートに直接追加できます。