第14章 スケジューリング
14.1. 概要
14.1.1. 概要
Pod のスケジューリングは、クラスター内のノードへの新規 Pod の配置を決定する内部プロセスです。
スケジューラーコードは、新規 Pod の作成時にそれらを確認し、それらをホストするのに最も適したノードを識別します。次に、マスター API を使用して Pod のバインディング (Pod とノードのバインディング) を作成します。
14.1.2. デフォルトスケジューリング
OpenShift Container Platform には、ほとんどのユーザーのニーズに対応するデフォルトスケジューラーが同梱されます。デフォルトスケジューラーは、Pod に最適なノードを判別するための固有のツールおよびカスタマイズ可能なツールの両方を使用します。
デフォルトスケジューラーが Pod の配置と利用できるカスタマイズ可能なパラメーターを判別する方法についての詳細は、「デフォルトスケジューリング」を参照してください。
14.1.3. 詳細スケジューリング
新規 Pod の配置場所に対する制御を強化する必要がある場合、OpenShift Container Platform の詳細スケジューリング機能を使用すると、Pod が特定ノード上か、または特定の Pod と共に実行されることを要求する (または実行されることが優先される) よう Pod を設定することができます。また詳細設定により、Pod をノードに配置することや他の Pod と共に実行することを防ぐこともできます。
詳細スケジューリングについての詳細は、「詳細スケジューリング」を参照してください。
14.1.4. カスタムスケジューリング
OpenShift Container Platform では、Pod 仕様を編集してユーザー独自のスケジューラーまたはサードパーティーのスケジューラーを使用することもできます。
詳細は、「カスタムスケジューラー」を参照してください。
14.2. デフォルトスケジューリング
14.2.1. 概要
OpenShift Container Platform のデフォルトの Pod スケジューラーは、クラスター内のノードにおける新規 Pod の配置場所を判別します。スケジューラーは Pod からのデータを読み取り、設定されるポリシーに基づいて適切なノードを見つけようとします。これは完全に独立した機能であり、スタンドアロン/プラグ可能ソリューションです。Pod を変更することはなく、Pod を特定ノードに関連付ける Pod のバインディングのみを作成します。
14.2.2. 汎用スケジューラー
既存の汎用スケジューラーはプラットフォームで提供されるデフォルトのスケジューラー エンジン であり、Pod をホストするノードを 3 つの手順で選択します。
- スケジューラーは 述語を使用して不適切なノードをフィルターに掛けて除外します。
- スケジューラーは ノードのフィルターされた一覧の優先順位付けを行います。
- スケジューラーは、Pod の最も優先順位の高い Pod を選択します。
14.2.3. ノードのフィルター
利用可能なノードは、指定される制約や要件に基づいてフィルターされます。フィルターは、各ノードで 述語 というフィルター関数の一覧を使用して実行されます。
14.2.3.1. フィルターされたノード一覧の優先順位付け
優先順位付けは、各ノードに一連の優先度関数を実行することによって行われます。この関数は 0 -10 までのスコアをノードに割り当て、0 は不適切であることを示し、10 は Pod のホストに適していることを示します。スケジューラー設定は、それぞれの優先度関数について単純な 重み (正の数値) を取ることができます。各優先度関数で指定されるノードのスコアは重み (ほとんどの優先度のデフォルトの重みは 1) で乗算され、すべての優先度で指定されるそれぞれのノードのスコアを追加して組み合わされます。この重み属性は、一部の優先度により重きを置くようにするなどのために管理者によって使用されます。
14.2.3.2. 最適ノードの選択
ノードの並び替えはそれらのスコアに基づいて行われ、最高のスコアを持つノードが Post をホストするように選択されます。複数のノードに同じ高スコアが付けられている場合、それらのいずれかがランダムに選択されます。
14.2.4. スケジューラーポリシー
述語と優先度の選択によって、スケジューラーのポリシーが定義されます。
スケジューラー設定ファイルは、スケジューラーが反映する述語と優先度を指定する JSON ファイルです。
スケジューラーポリシーファイルがない場合、デフォルトの設定ファイル /etc/origin/master/scheduler.json が適用されます。
スケジューラー設定ファイルで定義される述語および優先度は、デフォルトのスケジューラーポリシーを完全に上書きします。デフォルトの述語および優先度のいずれかが必要な場合、スケジューラー設定ファイルにその関数を明示的に指定する必要があります。
デフォルトのスケジューラー設定ファイル
{ "apiVersion": "v1", "kind": "Policy", "predicates": [ { "name": "NoVolumeZoneConflict" }, { "name": "MaxEBSVolumeCount" }, { "name": "MaxGCEPDVolumeCount" }, { "name": "MaxAzureDiskVolumeCount" }, { "name": "MatchInterPodAffinity" }, { "name": "NoDiskConflict" }, { "name": "GeneralPredicates" }, { "name": "PodToleratesNodeTaints" }, { "name": "CheckNodeMemoryPressure" }, { "name": "CheckNodeDiskPressure" }, { "argument": { "serviceAffinity": { "labels": [ "region" ] } }, "name": "Region" } ], "priorities": [ { "name": "SelectorSpreadPriority", "weight": 1 }, { "name": "InterPodAffinityPriority", "weight": 1 }, { "name": "LeastRequestedPriority", "weight": 1 }, { "name": "BalancedResourceAllocation", "weight": 1 }, { "name": "NodePreferAvoidPodsPriority", "weight": 10000 }, { "name": "NodeAffinityPriority", "weight": 1 }, { "name": "TaintTolerationPriority", "weight": 1 }, { "argument": { "serviceAntiAffinity": { "label": "zone" } }, "name": "Zone", "weight": 2 } ] }
14.2.4.1. スケジューラーポリシーの変更
The scheduler policy is defined in a file on the master, named /etc/origin/master/scheduler.json by default, unless overridden by the kubernetesMasterConfig.schedulerConfigFile
field in the master configuration file.
変更されたスケジューラー設定ファイルのサンプル
kind: "Policy" version: "v1" "predicates": [ { "name": "PodFitsResources" }, { "name": "NoDiskConflict" }, { "name": "MatchNodeSelector" }, { "name": "HostName" }, { "argument": { "serviceAffinity": { "labels": [ "region" ] } }, "name": "Region" } ], "priorities": [ { "name": "LeastRequestedPriority", "weight": 1 }, { "name": "BalancedResourceAllocation", "weight": 1 }, { "name": "ServiceSpreadingPriority", "weight": 1 }, { "argument": { "serviceAntiAffinity": { "label": "zone" } }, "name": "Zone", "weight": 2 } ]
スケジューラーポリシーを変更するには、以下を実行します。
- 必要なデフォルトの述語および優先度を設定するためにスケジューラー設定ファイルを編集します。カスタム設定を作成したり、サンプルのポリシー設定のいずれかを使用または変更したりすることができます。
- 必要な設定可能な述語と設定可能な優先度を追加します。
変更を有効にするために OpenShift Container Platform を再起動します。
# systemctl restart atomic-openshift-master-api atomic-openshift-master-controllers
14.2.5. 利用可能な述語
述語は、不適切なノードをフィルターに掛けるルールです。
OpenShift Container Platform には、デフォルトでいくつかの述語が提供されています。これらの述語の一部は、特定のパラメーターを指定してカスタマイズできます。複数の述語を組み合わせてノードの追加フィルターを指定できます。
14.2.5.1. 静的な述語
これらの述語はユーザーから設定パラメーターまたは入力を取りません。これらはそれぞれの正確な名前を使用してスケジューラー設定に指定されます。
14.2.5.1.1. デフォルトの述語
デフォルトのスケジューラーポリシーには以下の述語が含まれます。
NoVolumeZoneConflict は Pod が要求するボリュームがゾーンで利用可能であることを確認します。
{"name" : "NoVolumeZoneConflict"}
MaxEBSVolumeCount は、AWS インスタンスに割り当てることのできるボリュームの最大数を確認します。
{"name" : "MaxEBSVolumeCount"}
MaxGCEPDVolumeCount は、Google Compute Engine (GCE) 永続ディスク (PD) の最大数を確認します。
{"name" : "MaxGCEPDVolumeCount"}
MatchInterPodAffinity は、Pod のアフィニティー/非アフィニティールールが Pod を許可するかどうかを確認します。
{"name" : "MatchInterPodAffinity"}
NoDiskConflict は Pod が要求するボリュームが利用可能であるかどうかを確認します。
{"name" : "NoDiskConflict"}
PodToleratesNodeTaints は Pod がノードテイントを許容できるかどうかを確認します。
{"name" : "PodToleratesNodeTaints"}
CheckNodeMemoryPressure checks if a pod can be scheduled on a node with a memory pressure condition.
{"name" : "CheckNodeMemoryPressure"}
14.2.5.1.2. 他の静的な述語
OpenShift Container Platform は以下の述語もサポートしています。
CheckNodeDiskPressure checks if a pod can be scheduled on a node with a disk pressure condition.
{"name" : "CheckNodeDiskPressure"}
CheckVolumeBinding は、バインドされている PVC とバインドされていない PVC の両方の場合に Pod が要求するボリュームに基づいて適しているかどうかを評価します* バインドされている PVC については、述語は対応する PV のノードアフィニティーが指定ノードによって満たされていることを確認します。* バインドされていない PVC については、述語は PVC 要件を満たす PV を検索し、PV のノードアフィニティーが指定ノードによって満たされていることを確認します。
述語は、すべてのバインドされる PVC にノードと互換性のある PV がある場合や、すべてのバインドされていない PVC が利用可能なノードと互換性のある PV に一致する場合に true を返します。
{"name" : "CheckVolumeBinding"}
CheckVolumeBinding
述語は、デフォルト以外のスケジューラーで有効にする必要があります。
CheckNodeCondition は Pod をノードでスケジュールできるかどうかを確認し、out of disk (ディスク不足)、network unavailable (ネットワークが使用不可)、または not ready (準備できていない) 状態を報告します。
{"name" : "CheckNodeCondition"}
PodToleratesNodeNoExecuteTaints は、Pod がノードの NoExecute テイントを容認できるかどうかを確認します。
{"name" : "PodToleratesNodeNoExecuteTaints"}
CheckNodeLabelPresence は、すべての指定されたラベルがノードに存在するかどうかを確認します (その値が何であるかを問わない)。
{"name" : "CheckNodeLabelPresence"}
checkServiceAffinity は、ServiceAffinity ラベルがノードでスケジュールされる Pod について同種のものであることを確認します。
{"name" : "checkServiceAffinity"}
MaxAzureDiskVolumeCount は Azure ディスクボリュームの最大数を確認します。
{"name" : "MaxAzureDiskVolumeCount"}
14.2.5.2. 汎用的な述語
以下の汎用的な述語は、非クリティカル述語とクリティカル述語が渡されるかどうかを確認します。非クリティカル述語は、非 Critical Pod のみが渡す必要のある述語であり、クリティカル述語はすべての Pod が渡す必要のある述語です。
デフォルトのスケジューラーポリシーにはこの汎用的な述語が含まれます。
汎用的な非クリティカル述語
PodFitsResources は、リソースの可用性 (CPU、メモリー、GPU など) に基づいて適切な候補を判別します。ノードはそれらのリソース容量を宣言し、Pod は要求するリソースを指定できます。使用されるリソースではなく、要求されるリソースに基づいて適切な候補が判別されます。
{"name" : "PodFitsResources"}
汎用的なクリティカル述語
PodFitsHostPorts は、ノードに要求される Pod ポートの空きポートがある (ポートの競合がない) かどうかを判別します。
{"name" : "PodFitsHostPorts"}
HostName は、ホストパラメーターの有無と文字列のホスト名との一致に基づいて適切なノードを判別します。
{"name" : "HostName"}
MatchNodeSelector は、Pod で定義されるノードセレクター (nodeSelector)のクエリーに基づいて適したノードを判別します。
{"name" : "MatchNodeSelector"}
14.2.5.3. 設定可能な述語
これらの述語はスケジューラー設定 /etc/origin/master/scheduler.json (デフォルト) に設定し、述語の機能に影響を与えるラベルを追加することができます。
これらは設定可能であるため、ユーザー定義の名前が異なる限り、同じタイプ (ただし設定パラメーターは異なる) の複数の述語を組み合わせることができます。
これらの優先度の使用方法についての情報は、「スケジューラーポリシーの変更」を参照してください。
ServiceAffinity は、Pod で実行されるサービスに基づいて Pod をノードに配置します。同じノードまたは併置されているノードに同じサービスの複数の Pod を配置すると、効率が向上する可能性があります。
この述語は ノードセレクターの特定ラベルを持つ Pod を同じラベルを持つノードに配置しようとします。
Pod がノードセレクターでラベルを指定していない場合、最初の Pod は可用性に基づいて任意のノードに配置され、該当サービスの後続のすべての Pod はそのノードと同じラベルの値を持つノードにスケジュールされます。
"predicates":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "serviceAffinity":{ "labels":[ "<label>" 3 ] } } } ],
"name":"ZoneAffinity", "weight" : "1" "argument":{ "serviceAffinity":{ "labels":[ "rack"
たとえば、ノードセレクター rack
を持つサービスの最初の Pod がラベル region=rack
を持つノードにスケジュールされている場合、同じサービスに属するその他すべての後続の Pod は同じ region=rack
ラベルを持つノードにスケジュールされます。詳細は、「Pod 配置の制御」を参照してください。
複数レベルのラベルもサポートされています。ユーザーは同じリージョン内および (リージョン下の) 同じゾーン内のノードでスケジュールされるようサービスのすべての Pod を指定することもできます。
LabelsPresence checks whether a particular node has a certain label defined or not, regardless of its value. Matching by label can be useful, for example, where nodes have their physical location or status defined by labels.
"predicates":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "labelsPresence":{ "labels":[ "<label>" 3 presence: true/false ] } } } ],
- 1
- 述語の名前を指定します。
- 2
- Specify a weight from 1 (bad fit) to 10 (best fit).
- 3
- Specify a label for matching.
- Specify whether the labels are required.
-
presence:false
の場合、要求されるラベルのいずれかがノードラベルにある場合、Pod をスケジュールすることはできません。ラベルが存在しない場合は Pod をスケジュールできます。 -
For
presence:true
, if all of the requested labels are present in the node labels, the pod can be scheduled. If all of the lables are not present, the pod is not scheduled.
-
例:
"name":"RackPreferred", "weight" : "1" "argument":{ "labelsPresence":{ "labels":[ "rack" "labelsPresence:"{ "labels:"[ - "region" presence: true
14.2.6. 利用可能な優先度
優先度は、設定に応じて残りのノードにランクを付けるルールです。
優先度のカスタムセットは、スケジューラーを設定するために指定できます。OpenShift Container Platform ではデフォルトでいくつかの優先度があります。他の優先度は、特定のパラメーターを指定してカスタマイズできます。優先順位に影響を与えるために、複数の優先度を組み合わせ、異なる重みをそれぞれのノードに指定することができます。
14.2.6.1. 静的優先度
静的優先度は、重みを除き、ユーザーからいずれの設定パラメーターも取りません。重みは指定する必要があり、0 または負の値にすることはできません。
これらはスケジューラー設定 /etc/origin/master/scheduler.json (デフォルト) に指定されます。
14.2.6.1.1. デフォルトの優先度
デフォルトのスケジューラーポリシーには、以下の優先度が含まれています。それぞれの優先度関数は、重み 10000
を持つ NodePreferAvoidPodsPriority
以外は重み 1
を持ちます。
SelectorSpreadPriority は、Pod に一致するサービス、レプリケーションコントローラー (RC)、レプリケーションセット (RS)、およびステートフルなセットを検索し、次にそれらのセレクターに一致する既存の Pod を検索します。スケジューラーは、一致する既存 Pod が少ないノードを優先し、Pod のスケジュール時にそれらのセレクターに一致する Pod 数の最も少ないノードで Pod をスケジュールします。
{"name" : "SelectorSpreadPriority", "weight" : 1}
InterPodAffinityPriority は、ノードの対応する PodAffinityTerm が満たされている場合に weightedPodAffinityTerm
要素を使った繰り返し処理や 重み の合計への追加によって合計を計算します。合計値の最も高いノードが最も優先されます。
{"name" : "InterPodAffinityPriority", "weight" : 1}
LeastRequestedPriority は要求されたリソースの少ないノードを優先します。これは、ノードでスケジュールされる Pod によって要求されるメモリーおよび CPU のパーセンテージを計算し、利用可能な/残りの容量の値の最も高いノードを優先します。
{"name" : "LeastRequestedPriority", "weight" : 1}
BalancedResourceAllocation は、均衡が図られたリソース使用率に基づいてノードを優先します。これは、容量の一部として消費済み CPU とメモリー間の差異を計算し、2 つのメトリクスがどの程度相互に近似しているかに基づいてノードの優先度を決定します。これは常に LeastRequestedPriority
と併用する必要があります。
{"name" : "BalancedResourceAllocation", "weight" : 1}
NodePreferAvoidPodsPriority は、レプリケーションコントローラー以外のコントローラーによって所有される Pod を無視します。
{"name" : "NodePreferAvoidPodsPriority", "weight" : 10000}
NodeAffinityPriority は、ノードアフィニティーのスケジューリング設定に応じてノードの優先順位を決定します。
{"name" : "NodeAffinityPriority", "weight" : 1}
TaintTolerationPriority は、Pod についての 容認不可能な テイント数の少ないノードを優先します。容認不可能なテイントとはキー PreferNoSchedule
のあるテイントのことです。
{"name" : "TaintTolerationPriority", "weight" : 1}
14.2.6.1.2. 他の静的優先度
OpenShift Container Platform は以下の優先度もサポートしています。
EqualPriority は、優先度の設定が指定されていない場合に、すべてのノードに等しい重み 1
を指定します。この優先順位はテスト環境にのみ使用することを推奨します。
{"name" : "EqualPriority", "weight" : 1}
MostRequestedPriority は、要求されたリソースの最も多いノードを優先します。これは、ノードスケジュールされる Pod で要求されるメモリーおよび CPU のパーセンテージを計算し、容量に対して要求される部分の平均の最大値に基づいて優先度を決定します。
{"name" : "MostRequestedPriority", "weight" : 1}
ImageLocalityPriority は、Pod コンテナーのイメージをすでに要求しているノードを優先します。
{"name" : "ImageLocalityPriority", "weight" : 1}
ServiceSpreadingPriority は、同じマシンに置かれる同じサービスに属する Pod 数を最小限にすることにより Pod を分散します。
{"name" : "ServiceSpreadingPriority", "weight" : 1}
14.2.6.2. 設定可能な優先度
これらの優先度は、デフォルトでスケジューラー設定 /etc/origin/master/scheduler.json で設定し、これらの優先度に影響を与えるラベルを追加できます。
優先度関数のタイプは、それらが取る引数によって識別されます。これらは設定可能なため、ユーザー定義の名前が異なる場合に、同じタイプの (ただし設定パラメーターは異なる) 設定可能な複数の優先度を組み合わせることができます。
これらの優先度の使用方法についての情報は、「スケジューラーポリシーの変更」を参照してください。
ServiceAntiAffinity はラベルを取り、ラベルの値に基づいてノードのグループ全体に同じサービスに属する Pod を適正に分散します。これは、指定されたラベルの同じ値を持つすべてのノードに同じスコアを付与します。また Pod が最も集中していないグループ内のノードにより高いスコアを付与します。
"priorities":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "serviceAntiAffinity":{ "labels":[ "<label>" 3 ] } } } ]
例:
"name":"RackSpread", "weight" : "1" "argument":{ "serviceAffinity":{ "labels":[ "rack"
LabelPreference prefers nodes that have a particular label defined, regardless of its value.
"predicates":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "labelsPresence":{ "labels":[ "<label>" 3 presence: true/false ] } } } ],
- 1
- 優先度の名前を指定します。
- 2
- Specify a weight from 1 (bad fit) to 10 (best fit).
- 3
- Specify a label for matching.
- Specify whether the labels are required.
-
presence:false
の場合、要求されるラベルのいずれかがノードラベルにある場合、Pod をスケジュールすることはできません。ラベルが存在しない場合は Pod をスケジュールできます。 -
For
presence:true
, if all of the requested labels are present in the node labels, the pod can be scheduled. If all of the lables are not present, the pod is not scheduled.
-
例:
"name":"RackPreferred", "weight" : "1" "argument":{ "labelsPresence":{ "labels":[ "rack"
14.2.7. 使用例
OpenShift Container Platform 内でのスケジューリングの重要な使用例として、柔軟なアフィニティーと非アフィニティーポリシーのサポートを挙げることができます。
14.2.7.1. インフラストラクチャーのトポロジーレベル
管理者は、ノードのラベル (例: region=r1
、zone=z1
、rack=s1
) を指定してインフラストラクチャーの複数のトポロジーレベルを定義することができます。
これらのラベル名には特別な意味はなく、管理者はそれらのインフラストラクチャーラベルに任意の名前 (例: 都市/建物/部屋) を付けることができます。さらに、管理者はインフラストラクチャートポロジーに任意の数のレベルを定義できます。通常は、(regions
zones
racks
などの) 3 つのレベルが適切なサイズです。管理者はこれらのレベルのそれぞれにアフィニティーと非アフィニティールールを任意の組み合わせで指定することができます。
14.2.7.2. アフィニティー
管理者は、任意のトポロジーレベルまたは複数のレベルでもアフィニティーを指定できるようにスケジューラーを設定することができます。特定レベルのアフィニティーは、同じサービスに属するすべての Pod が同じレベルに属するノードにスケジュールされることを示します。これは、管理者がピア Pod が地理的に離れ過ぎないようにすることでアプリケーションの待機時間の要件に対応します。同じアフィニティーグループ内で Pod をホストするために利用できるノードがない場合、Pod はスケジュールされません。
Pod がスケジュールされる場所に対する制御を強化する必要がある場合は、「ノードアフィニティーの使用」および「Pod のアフィニティーおよび非アフィニティーの使用」を参照してください。これらの詳細スケジューリング機能により、管理者は Pod をスケジュールできるノードを指定し、他の Pod に関連してスケジューリングを強制的に実行したり、拒否したりできます。
14.2.7.3. 非アフィニティー
管理者は、任意のトポロジーレベルまたは複数のレベルでも非アフィニティーを設定できるようスケジューラーを設定することができます。特定レベルの非アフィニティー (または「分散」)は、同じサービスに属するすべての Pod が該当レベルに属するノード全体に分散されることを示します。これにより、アプリケーションが高可用性の目的で適正に分散されます。スケジューラーは、可能な限り均等になるようにすべての適用可能なノード全体にサービス Pod を配置しようとします。
Pod がスケジュールされる場所に対する制御を強化する必要がある場合は、「ノードアフィニティーの使用」および「Pod のアフィニティーおよび非アフィニティーの使用」を参照してください。これらの詳細スケジューリング機能により、管理者は Pod をスケジュールできるノードを指定し、他の Pod に関連してスケジューリングを強制的に実行したり、拒否したりできます。
14.2.8. ポリシー設定のサンプル
以下の設定は、スケジューラーポリシーファイルを使って指定される場合のデフォルトのスケジューラー設定を示しています。
kind: "Policy" version: "v1" predicates: ... - name: "RegionZoneAffinity" 1 argument: serviceAffinity: 2 labels: 3 - "region" - "zone" priorities: ... - name: "RackSpread" 4 weight: 1 argument: serviceAntiAffinity: 5 label: "rack" 6
以下の設定例のいずれの場合も、述語と優先度関数の一覧は、指定された使用例に関連するもののみを含むように切り捨てられます。実際には、完全な/分かりやすいスケジューラーポリシーには、上記のデフォルトの述語および優先度のほとんど (すべてではなくても) が含まれるはずです。
以下の例は、region (affinity)
kind: "Policy" version: "v1" predicates: ... - name: "RegionZoneAffinity" argument: serviceAffinity: labels: - "region" - "zone" priorities: ... - name: "RackSpread" weight: 1 argument: serviceAntiAffinity: label: "rack"
以下の例は、city (affinity)
kind: "Policy" version: "v1" predicates: ... - name: "CityAffinity" argument: serviceAffinity: labels: - "city" priorities: ... - name: "BuildingSpread" weight: 1 argument: serviceAntiAffinity: label: "building" - name: "RoomSpread" weight: 1 argument: serviceAntiAffinity: label: "room"
以下の例では、「region」ラベルが定義されたノードのみを使用し、「zone」ラベルが定義されたノードを優先するポリシーを定義します。
kind: "Policy" version: "v1" predicates: ... - name: "RequireRegion" argument: labelsPresence: labels: - "region" presence: true priorities: ... - name: "ZonePreferred" weight: 1 argument: labelPreference: label: "zone" presence: true
以下の例では、静的および設定可能な述語および優先度を組み合わせています。
kind: "Policy" version: "v1" predicates: ... - name: "RegionAffinity" argument: serviceAffinity: labels: - "region" - name: "RequireRegion" argument: labelsPresence: labels: - "region" presence: true - name: "BuildingNodesAvoid" argument: labelsPresence: labels: - "building" presence: false - name: "PodFitsPorts" - name: "MatchNodeSelector" priorities: ... - name: "ZoneSpread" weight: 2 argument: serviceAntiAffinity: label: "zone" - name: "ZonePreferred" weight: 1 argument: labelPreference: label: "zone" presence: true - name: "ServiceSpreadingPriority" weight: 1
14.3. カスタムスケジューリング
14.3.1. 概要
デフォルトのスケジューラーと共に複数のカスタムスケジューラーを実行し、各 Pod に使用できるスケジューラーを設定できます。
特定のスケジューラーを使用して指定された Pod をスケジュールするには、Pod 仕様にスケジューラーの名前を指定します。
14.3.2. Deploying the Scheduler
The steps below are the general process for deploying a scheduler into your cluster.
Information on how to create/deploy a scheduler is outside the scope of this document. For an example, see plugin/pkg/scheduler in the Kubernetes source directory.
Pod 設定を作成するか、または編集し、
schedulerName
パラメーターでスケジューラーの名前を指定します。名前は一意である必要があります。スケジューラーを含む Pod 仕様のサンプル
apiVersion: v1 kind: Pod metadata: name: custom-scheduler labels: name: multischeduler-example spec: schedulerName: custom-scheduler 1 containers: - name: pod-with-second-annotation-container image: docker.io/ocpqe/hello-pod
- 1
- 使用するスケジューラーの名前です。スケジューラー名が指定されていない場合、Pod はデフォルトのスケジューラーを使用して自動的にスケジュールされます。
以下のコマンドを実行して Pod を作成します。
$ oc create -f scheduler.yaml
Run the following command to check that the pod was created with the custom scheduler:
$ oc get pod custom-scheduler -o yaml
Run the following command to check the status of the pod:
$ oc get pod
The pod should not be running.
NAME READY STATUS RESTARTS AGE custom-scheduler 0/1 Pending 0 2m
- Deploy the custom scheduler.
Run the following command to check the status of the pod:
$ oc get pod
The pod should be running.
NAME READY STATUS RESTARTS AGE custom-scheduler 1/1 Running 0 4m
Run the following command to check that the scheduler was used:
$ oc describe pod custom-scheduler
以下の切り捨てられた出力に示されるように、スケジューラーの名前が一覧表示されます。
[...] Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 my-scheduler Normal Scheduled Successfully assigned custom-scheduler to <$node1> [...]
14.4. Pod 配置の制御
14.4.1. 概要
クラスター管理者は、特定のロールを持つアプリケーション開発者が Pod のスケジュール時に特定ノードをターゲットとすることを防ぐポリシーを設定できます。
The Pod Node Constraints admission controller ensures that pods are deployed onto only specified node hosts using labels] and prevents users without a specific role from using the nodeSelector
field to schedule pods.
14.4.2. ノード名の使用による Pod 配置の制約
Pod ノード制約の受付コントローラーを使用し、Pod にラベルを割り当て、これを Pod 設定の nodeName
設定に指定することで、Pod が指定されたノードホストにのみデプロイされるようにします。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeName
値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeName: <value>
Modify the master configuration file (/etc/origin/master/master-config.yaml) in two places:
Add
PodNodeConstraints
to theadmissionConfig
section:... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig ...
Then, add the same to the
kubernetesMasterConfig
section:... kubernetesMasterConfig: admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiVersion: v1 kind: PodNodeConstraintsConfig ...
変更を有効にするために OpenShift Container Platform を再起動します。
# systemctl restart atomic-openshift-master
14.4.3. ノードセレクターの使用による Pod 配置の制約
ノードセレクターを使用して、Pod が特定のラベルを持つノードにのみ配置されるようにすることができます。クラスター管理者は、Pod ノード制約の受付コントローラーを使用して、pods/binding パーミッションのないユーザーがノードセレクターを使用して Pod をスケジュールできないようにするポリシーを設定できます。
マスター設定ファイルの nodeSelectorLabelBlacklist
フィールドを使用して、一部のロールが Pod 設定の nodeSelector
フィールドで指定できるラベルを制御できます。pods/binding パーミッションロールを持つユーザー、サービスアカウントおよびグループは任意のノードセレクターを指定できます。pods/binding パーミッションがない場合は、nodeSelectorLabelBlacklist
に表示されるすべてのラベルに nodeSelector
を設定することは禁止されます。
For example, an OpenShift Container Platform cluster might consist of five data centers spread across two regions. In the U.S., "us-east", "us-central", and "us-west"; and in the Asia-Pacific region (APAC), "apac-east" and "apac-west". Each node in each geographical region is labeled accordingly. For example, region: us-east
.
ラベルの割り当ての詳細は、「ノードでのラベルの更新」を参照してください。
クラスター管理者は、アプリケーション開発者が地理的に最も近い場所にあるノードにのみ Pod をデプロイできるインフラストラクチャーを作成できます。ノードセレクターを作成し、米国のデータセンターを superregion: us
に、APAC のデータセンターを superregion: apac
に分類できます。
データセンターごとのリソースの均等なロードを維持するには、必要な region
をマスター設定の nodeSelectorLabelBlacklist
セクションに追加できます。その後は、米国の開発者が Pod を作成するたびに、Pod は superregion: us
ラベルの付いた地域のいずれかにあるノードにデプロイされます。開発者が Pod に特定の region (地域) をターゲットに設定しようとすると (例: region: us-east
)、エラーが出されます。これを Pod にノードセレクターを設定せずに試行すると、ターゲットとした region (地域) にデプロイすることができます。それは superregion: us
がプロジェクトレベルのノードセレクターとして設定されており、region: us-east
というラベルが付けられたノードには superregion: us
というラベルも付けられているためです。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeSelector
値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeSelector: <key>: <value> ...
Modify the master configuration file (/etc/origin/master/master-config.yaml) in two places:
Add
nodeSelectorLabelBlacklist
to theadmissionConfig
section with the labels that are assigned to the node hosts you want to deny pod placement:... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...
Then, add the same to the
kubernetesMasterConfig
section to restrict direct pod creation:... kubernetesMasterConfig: admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiVersion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label_1> ...
変更を有効にするために OpenShift Container Platform を再起動します。
# systemctl restart atomic-openshift-master
14.4.4. プロジェクト対する Pod 配置の制御
The Pod Node Selector admission controller allows you to force pods onto nodes associated with a specific project and prevent pods from being scheduled in those nodes.
The Pod Node Selector admission controller determines where a pod can be placed using labels on projects and node selectors specified in pods. A new pod will be placed on a node associated with a project only if the node selectors in the pod match the labels in the project.
Pod の作成後に、ノードセレクターは Pod にマージされ、Pod 仕様に元々含まれていたラベルとノードセレクターの新規ラベルが含まれるようにします。以下の例は、マージの結果について示しています。
The Pod Node Selector admission controller also allows you to create a list of labels that are permitted in a specific project. This list acts as a whitelist that lets developers know what labels are acceptable to use in a project and gives administrators greater control over labeling in a cluster.
Pod ノードセレクター の受付コントローラーをアクティブにするには、以下を実行します。
以下の方法のいずれかを使用して Pod ノードセレクター の受付コントローラーとホワイトリストを設定します。
Add the following to the master configuration file (/etc/origin/master/master-config.yaml):
admissionConfig: pluginConfig: PodNodeSelector: configuration: podNodeSelectorPluginConfig: 1 clusterDefaultNodeSelector: "k3=v3" 2 ns1: region=west,env=test,infra=fedora,os=fedora 3
- 1
- Pod ノードセレクター の受付コントローラープラグインを追加します。
- 2 3
- すべてのノードのデフォルトラベルを作成します。
- 指定されたプロジェクトで許可されるラベルのホワイトリストを作成します。ここで、プロジェクトは
ns1
で、ラベルはそれに続くkey=value
ペアになります。受付コントローラーの情報を含むファイルを作成します。
podNodeSelectorPluginConfig: clusterDefaultNodeSelector: "k3=v3" ns1: region=west,env=test,infra=fedora,os=fedora
次に、マスター設定でファイルを参照します。
admissionConfig: pluginConfig: PodNodeSelector: location: <path-to-file>
注記If a project does not have a node selectors specified, the pods associated with that project will be merged using the default node selector (
clusterDefaultNodeSelector
).
変更を有効にするために OpenShift Container Platform を再起動します。
# systemctl restart atomic-openshift-master
scheduler.alpha.kubernetes.io/node-selector
アノテーションおよびラベルを含むプロジェクトオブジェクトを作成します。{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "ns1", "annotations": { "scheduler.alpha.kubernetes.io/node-selector": "env=test,infra=fedora" 1 } }, "spec": {}, "status": {} }
- 1
- プロジェクトのラベルセレクターに一致するラベルを作成するためのアノテーションです。ここで、キー/値のラベルは
env=test
およびinfra=fedora
になります。
ノードセレクターにラベルを含む Pod 仕様を作成します。以下は例になります。
apiVersion: v1 kind: Pod metadata: labels: name: hello-pod name: hello-pod spec: containers: - image: "docker.io/ocpqe/hello-pod:latest" imagePullPolicy: IfNotPresent name: hello-pod ports: - containerPort: 8080 protocol: TCP resources: {} securityContext: capabilities: {} privileged: false terminationMessagePath: /dev/termination-log dnsPolicy: ClusterFirst restartPolicy: Always nodeSelector: 1 env: test os: fedora serviceAccount: "" status: {}
- 1
- プロジェクトラベルに一致するノードセレクターです。
プロジェクトに Pod を作成します。
oc create -f pod.yaml --namespace=ns1
ノードセレクターのラベルが Pod 設定に追加されていることを確認します。
get pod pod1 --namespace=ns1 -o json nodeSelector": { "env": "test", "infra": "fedora", "os": "fedora" }
ノードセレクターは Pod にマージされ、Pod は適切なプロジェクトでスケジュールされます。
プロジェクト仕様で指定されていないラベルを使って Pod を作成する場合、Pod はノードでスケジュールされません。
たとえば、ここでラベル env: production
はにずれのプロジェクト仕様にもありません。
nodeSelector: "env: production" "infra": "fedora", "os": "fedora"
ノードセレクターのアノテーションのないノードがある場合は、Pod はそこにスケジュールされます。
14.5. 詳細スケジューリング
14.5.1. 概要
詳細スケジューリングには、Pod が特定ノードで実行されることを要求したり、Pod が特定ノードで実行されることが優先されるように Pod を設定することが関係します。
通常、詳細スケジューリングは必要になりません。OpenShift Container Platform が Pod を合理的な方法で自動的に配置するためです。たとえば、デフォルトスケジューラーは Pod をノード間で均等に分散し、ノードの利用可能なリソースを考慮します。ただし、Pod を配置する場所についてはさらに制御を強化する必要がある場合があります。
Pod をより高速なディスクが搭載されたマシンに配置する必要ある場合 (またはそのマシンに配置するのを防ぐ場合)、または 2 つの異なるサービスの Pod が相互に通信できるように配置する必要がある場合、詳細スケジューリングを使用してそれを可能にすることができます。
適切な新規 Pod を特定のノードグループにスケジュールし、その他の新規 Pod がそれらのノードでスケジュールされるのを防ぐには、必要に応じてこれらの方法を組み合わせることができます。
14.5.2. 詳細スケジューリングの使用
クラスターで詳細スケジューリングを起動する方法はいくつかあります。
- Pod のアフィニティーおよび非アフィニティー
Pod のアフィニティーにより、Pod がその配置に使用できるアフィニティー (または非アフィニティー) を、(セキュリティー上の理由によるアプリケーションの待機時間の要件などのために) Pod のグループに対して指定できるようにします。ノード自体は配置に対する制御を行いません。
Pod のアフィニティーはノードのラベルと Pod のラベルセレクターを使用して Pod 配置のルールを作成します。ルールは mandatory (必須) または best-effort (優先) のいずれかにすることができます。
「Pod のアフィニティーおよび非アフィニティーの使用」を参照してください。
- ノードのアフィニティー
ノードのアフィニティーにより、Pod がその配置に使用できるアフィニティー (または非アフィニティー) を、(高可用性のための特殊なハードウェア、場所、要件などにより) ノード のグループに対して指定できるようにします。ノード自体は配置に対する制御を行いません。
ノードのアフィニティーはノードのラベルと Pod のラベルセレクターを使用して Pod 配置のルールを作成します。ルールは mandatory (必須) または best-effort (優先) のいずれかにすることができます。
「ノードアフィニティーの使用」を参照してください。
- ノードセレクター
ノードセレクターは詳細スケジューリングの最も単純な形態です。ノードのアフィニティーのように、ノードセレクターはノードのラベルと Pod のラベルセレクターを使用し、Pod がその配置に使用する ノード を制御できるようにします。ただし、ノードセレクターにはノードのアフィニティーが持つ required (必須) ルールまたは preferred (優先) ルールはありません。
「ノードセレクターの使用」を参照してください。
- テイントおよび容認 (Toleration)
テイント/容認により、ノード はノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。テイントはノードのラベルであり、容認は Pod のラベルです。スケジュールを可能にするには、Pod のラベルは ノードのラベル (テイント) に一致する (またはこれを許容する) 必要があります。
テイント/容認にはアフィニティーと比較して 1 つ利点があります。たとえばアフィニティーの場合は、異なるラベルを持つノードの新規グループをクラスターに追加する場合、ノードにアクセスさせたい Pod とノードを使用させたくない Pod のそれぞれに対してアフィニティーを更新する必要がありますが、テイント/容認の場合には、新規ノードに到達させる必要のある Pod のみを更新すれば、他の Pod は拒否されることになります。
「テイントおよび容認の使用」を参照してください。
14.6. 詳細スケジューリングおよびノードのアフィニティー
14.6.1. 概要
Node affinity is a set of rules used by the scheduler to determine where a pod can be placed. The rules are defined using custom labels on nodes and label selectors specified in pods. Node affinity allows a pod to specify an affinity (or anti-affinity) towards a group of nodes it can be placed on. The node does not have control over the placement.
たとえば、Pod を特定の CPU を搭載したノードまたは特定のアベイラビリティーゾーンにあるノードでのみ実行されるよう設定することができます。
ノードのアフィニティールールには、required (必須) および preferred (優先) の 2 つのタイプがあります。
required (必須) ルールは、Pod をノードにスケジュールする前に 満たされている必要があります。一方、preferred (優先) ルールは、ルールが満たされる場合にスケジューラーがルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
ランタイム時にノードのラベルに変更が生じ、その変更により Pod でのノードのアフィニティールールを満たさなくなる状態が生じるでも、Pod はノードで引き続き実行されます。
14.6.2. ノードのアフィニティーの設定
ノードのアフィニティーは、Pod 仕様で設定することができます。required (必須) ルール、preferred (優先) ルール のいずれかまたはその両方を指定することができます。両方を指定する場合、ノードは最初に required (必須) ルールを満たす必要があり、その後に preferred (優先) ルールを満たそうとします。
以下の例は、Pod をキーが e2e-az-NorthSouth
で、その値が e2e-az-North
または e2e-az-South
のいずれかであるラベルの付いたノードに Pod を配置することを求めるルールが設定された Pod 仕様です。
ノードのアフィニティーの required (必須) ルールが設定された Pod 設定ファイルのサンプル
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: 1 requiredDuringSchedulingIgnoredDuringExecution: 2 nodeSelectorTerms: - matchExpressions: - key: e2e-az-NorthSouth 3 operator: In 4 values: - e2e-az-North 5 - e2e-az-South 6 containers: - name: with-node-affinity image: docker.io/ocpqe/hello-pod
以下の例は、キーが e2e-az-EastWest
で、その値が e2e-az-East
または e2e-az-West
のラベルが付いたノードに Pod を配置すること優先する preferred (優先) ルールが設定されたノード仕様です。
ノードのアフィニティーの preferred (優先) ルールが設定された Pod 設定ファイルのサンプル
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: 1 preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 1 3 preference: matchExpressions: - key: e2e-az-EastWest 4 operator: In 5 values: - e2e-az-East 6 - e2e-az-West 7 containers: - name: with-node-affinity image: docker.io/ocpqe/hello-pod
ノードの非アフィニティー についての明示的な概念はありませんが、NotIn
または DoesNotExist
演算子を使用すると、動作が複製されます。
同じ Pod 設定でノードのアフィニティーと ノードセレクターを使用している場合、以下に注意してください。
-
nodeSelector
とnodeAffinity
の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。 -
nodeAffinity
タイプに関連付けられた複数のnodeSelectorTerms
を指定する場合、nodeSelectorTerms
のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。 -
nodeSelectorTerms
に関連付けられた複数のmatchExpressions
を指定する場合、すべてのmatchExpressions
が満たされている場合にのみ Pod をノードにスケジュールすることができます。
14.6.2.1. ノードアフィニティーの required (必須) ルールの設定
Pod がノードにスケジュールされる前に、required (必須) ルールを 満たしている必要があります。
以下の手順は、ノードとスケジューラーがノードに配置する必要のある Pod を作成する単純な設定を示しています。
ノード設定を編集するか、または
oc label node
コマンドを使用してラベルをノードに追加します。$ oc label node node1 e2e-az-name=e2e-az1
Pod 仕様では、
nodeAffinity
スタンザを使用してrequiredDuringSchedulingIgnoredDuringExecution
パラメーターを設定します。-
満たす必要のあるキーおよび値を指定します。新規 Pod を編集したノードにスケジュールする必要がある場合、ノードのラベルと同じ
key
およびvalue
パラメーターを使用します。 operator
を指定します。演算子はIn
、NotIn
、Exists
、DoesNotExist
、Lt
、またはGt
にすることができます。たとえば、演算子In
を使用してラベルがノードで必要になるようにします。spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: e2e-az-name operator: In values: - e2e-az1 - e2e-az2
-
満たす必要のあるキーおよび値を指定します。新規 Pod を編集したノードにスケジュールする必要がある場合、ノードのラベルと同じ
Pod を作成します。
$ oc create -f e2e-az2.yaml
14.6.2.2. ノードアフィニティーの preferred (優先) ルールの設定
preferred (優先) ルールは、ルールを満たす場合に、スケジューラーはルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
以下の手順は、ノードとスケジューラーがノードに配置しようとする Pod を作成する単純な設定を示しています。
ノード設定を編集するか、または
oc label node
コマンドを実行してラベルをノードに追加します。$ oc label node node1 e2e-az-name=e2e-az3
Pod 仕様では、
nodeAffinity
スタンザを使用してpreferredDuringSchedulingIgnoredDuringExecution
パラメーターを設定します。- ノードの重みを数字の 1-100 で指定します。最も高い重みを持つノードが優先されます。
満たす必要のあるキーおよび値を指定します。新規 Pod を編集したノードにスケジュールする必要がある場合、ノードのラベルと同じ
key
およびvalue
パラメーターを使用します。preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: e2e-az-name operator: In values: - e2e-az3
-
operator
を指定します。演算子はIn
、NotIn
、Exists
、DoesNotExist
、Lt
、またはGt
にすることができます。たとえば、演算子In
を使用してラベルをノードで必要になるようにします。 Pod を作成します。
$ oc create -f e2e-az3.yaml
14.6.3. 例
以下の例は、ノードのアフィニティーを示しています。
14.6.3.1. 一致するラベルを持つノードのアフィニティー
以下の例は、一致するラベルを持つノードと Pod のノードのアフィニティーを示しています。
Node1 ノードにはラベル
zone:us
があります。$ oc label node node1 zone=us
Pod pod-s1 にはノードアフィニティーの required (必須) ルールの下に
zone
とus
のキー/値のペアがあります。$ cat pod-s1.yaml apiVersion: v1 kind: Pod metadata: name: pod-s1 spec: containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "zone" operator: In values: - us
標準コマンドを使用して Pod を作成します。
$ oc create -f pod-s1.yaml pod "pod-s1" created
Pod pod-s1 を Node1 にスケジュールできます。
oc get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE pod-s1 1/1 Running 0 4m IP1 node1
14.6.3.2. 一致するラベルのないノードのアフィニティー
以下の例は、一致するラベルを持たないノードと Pod のノードのアフィニティーを示しています。
Node1 ノードにはラベル
zone:emea
があります。$ oc label node node1 zone=emea
Pod pod-s1 にはノードアフィニティーの required (必須) ルールの下に
zone
とus
のキー/値のペアがあります。$ cat pod-s1.yaml apiVersion: v1 kind: Pod metadata: name: pod-s1 spec: containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "zone" operator: In values: - us
Pod pod-s1 は Node1 にスケジュールすることができません。
oc describe pod pod-s1 <---snip---> Events: FirstSeen LastSeen Count From SubObjectPath Type Reason --------- -------- ----- ---- ------------- -------- ------ 1m 33s 8 default-scheduler Warning FailedScheduling No nodes are available that match all of the following predicates:: MatchNodeSelector (1).
14.7. 詳細スケジューリングおよび Pod のアフィニティーと非アフィニティー
14.7.1. 概要
Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods. The rules are defined using custom labels on nodes and label selectors specified in pods. Pod affinity/anti-affinity allows a pod to specify an affinity (or anti-affinity) towards a group of pods it can be placed with. The node does not have control over the placement.
たとえば、アフィニティールールを使用することで、サービス内で、または他のサービスの Pod との関連で Pod を分散したり、パックしたりすることができます。非アフィニティールールにより、特定のサービスの Pod がそののサービスの Pod のパフォーマンスに干渉すると見なされる別のサービスの Pod と同じノードでスケジュールされることを防ぐことができます。または、関連する障害を減らすために複数のノードまたはアベイラビリティーゾーン間でサービスの Pod を分散することもできます。
Pod affinity/anti-affinity allows you to constrain which nodes your pod is eligible to be scheduled on based on the labels on other pods. A label is a key/value pair.
- Pod のアフィニティーはスケジューラーに対し、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に他の Pod と同じノードで新規 Pod を見つけるように指示します。
- Pod の非アフィニティーは、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に、同じラベルを持つ Pod と同じノードで新規 Pod を見つけることを禁止します。
Pod のアフィニティーには、required (必須) および preferred (優先) の 2 つのタイプがあります。
required (必須) ルールは、Pod をノードにスケジュールする前に 満たされている必要があります。一方、preferred (優先) ルールは、ルールが満たされる場合にスケジューラーがルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
14.7.2. Pod のアフィニティーおよび非アフィニティーの設定
Pod のアフィニティー/非アフィニティーは Pod 仕様ファイルで設定します。required (必須) ルール、preferred (優先) ルールのいずれかまたはその両方を指定することができます。両方を指定する場合、ノードは最初に required (必須) ルールを満たす必要があり、その後に preferred (優先) ルールを満たそうとします。
以下の例は、Pod のアフィニティーおよび非アフィニティーに設定される Pod 仕様を示しています。
この例では、Pod のアフィニティールールは ノードにキー security
と値 S1
を持つラベルの付いた 1 つ以上の Pod がすでに実行されている場合にのみ Pod をノードにスケジュールできることを示しています。Pod の非アフィニティールールは、ノードがキー security
と値 S2
を持つラベルが付いた Pod がすでに実行されている場合は Pod をノードにスケジュールしないように設定することを示しています。
Pod のアフィニティーが設定された Pod 設定のサンプル
apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: 1 requiredDuringSchedulingIgnoredDuringExecution: 2 - labelSelector: matchExpressions: - key: security 3 operator: In 4 values: - S1 5 topologyKey: failure-domain.beta.kubernetes.io/zone containers: - name: with-pod-affinity image: docker.io/ocpqe/hello-pod
Pod の非アフィニティーが設定された Pod 設定のサンプル
apiVersion: v1 kind: Pod metadata: name: with-pod-antiaffinity spec: affinity: podAntiAffinity: 1 preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 100 3 podAffinityTerm: labelSelector: matchExpressions: - key: security 4 operator: In 5 values: - S2 6 topologyKey: kubernetes.io/hostname containers: - name: with-pod-affinity image: docker.io/ocpqe/hello-pod
- 1
- Pod の非アフィニティーを設定するためのスタンザです。
- 2
- preferred (優先) ルールを定義します。
- 3
- Specifies a weight for a preferred rule. The node that with highest weight is preferred.
- 4 6
- ルールを適用するために一致している必要のあるキーと値 (ラベル) です。
- 5
- 演算子は、既存 Pod のラベルと新規 Pod の仕様の
matchExpression
パラメーターの値のセットの間の関係を表します。これにはIn
、NotIn
、Exists
、またはDoesNotExist
のいずれかを使用できます。
ノードのラベルに、Pod のノードのアフィニティールールを満たさなくなるような結果になる変更がランタイム時に生じる場合も、Pod はノードで引き続き実行されます。
14.7.2.1. アフィニティールールの設定
以下の手順は、ラベルの付いた Pod と Pod のスケジュールを可能にするアフィニティーを使用する Pod を作成する 2 つの Pod の単純な設定を示しています。
Pod 仕様の特定のラベルの付いた Pod を作成します。
$ cat team4.yaml apiVersion: v1 kind: Pod metadata: name: security-s1 labels: security: S1 spec: containers: - name: security-s1 image: docker.io/ocpqe/hello-pod
他の Pod の作成時に、以下のように Pod 仕様を編集します。
-
podAffinity
スタンザを使用して、requiredDuringSchedulingIgnoredDuringExecution
パラメーターまたはpreferredDuringSchedulingIgnoredDuringExecution
パラメーターを設定します。 満たしている必要のあるキーおよび値を指定します。新規 Pod を他の Pod と共にスケジュールする必要がある場合、最初の Pod のラベルと同じ
key
およびvalue
パラメーターを使用します。podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: failure-domain.beta.kubernetes.io/zone
-
operator
を指定します。演算子はIn
、NotIn
、Exists
、またはDoesNotExist
にすることができます。たとえば、演算子In
を使用してラベルをノードで必要になるようにします。 -
topologyKey
を指定します。これは、システムがトポロジードメインを表すために使用する事前にデータが設定された Kubernetes ラベルです。
-
Pod を作成します。
$ oc create -f <pod-spec>.yaml
14.7.2.2. 非アフィニティールールの設定
以下の手順は、ラベルの付いた Pod と Pod のスケジュールの禁止を試行する非アフィニティーの preferred (優先) ルールを使用する Pod を作成する 2 つの Pod の単純な設定を示しています。
Pod 仕様の特定のラベルの付いた Pod を作成します。
$ cat team4.yaml apiVersion: v1 kind: Pod metadata: name: security-s2 labels: security: S2 spec: containers: - name: security-s2 image: docker.io/ocpqe/hello-pod
- 他の Pod の作成時に、Pod 仕様を編集して以下のパラメーターを設定します。
podAffinity
スタンザを使用して、requiredDuringSchedulingIgnoredDuringExecution
パラメーターまたはpreferredDuringSchedulingIgnoredDuringExecution
パラメーターを設定します。- ノードの重みを 1-100 で指定します。最も高い重みを持つノードが優先されます。
満たしている必要のあるキーおよび値を指定します。新規 Pod を他の Pod と共にスケジュールされないようにする必要がある場合、最初の Pod のラベルと同じ
key
およびvalue
パラメーターを使用します。podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: kubernetes.io/hostname
- preferred (優先) ルールの場合、重みを 1-100 で指定します。
-
operator
を指定します。演算子はIn
、NotIn
、Exists
、またはDoesNotExist
にすることができます。たとえば、演算子In
を使用してラベルをノードで必要になるようにします。
-
topologyKey
を指定します。これは、システムがトポロジードメインを表すために使用する事前にデータが設定された Kubernetes ラベルです。 Pod を作成します。
$ oc create -f <pod-spec>.yaml
14.7.3. 例
以下の例は、Pod のアフィニティーおよび非アフィニティーについて示しています。
14.7.3.1. Pod のアフィニティー
以下の例は、一致するラベルとラベルセレクターを持つ Pod についての Pod のアフィニティーを示しています。
Pod team4 にはラベル
team:4
が付けられています。$ cat team4.yaml apiVersion: v1 kind: Pod metadata: name: team4 labels: team: "4" spec: containers: - name: ocp image: docker.io/ocpqe/hello-pod
Pod team4a には、
podAffinity
の下にラベルセレクターteam:4
が付けられています。$ cat pod-team4a.yaml apiVersion: v1 kind: Pod metadata: name: team4a spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: team operator: In values: - "4" topologyKey: kubernetes.io/hostname containers: - name: pod-affinity image: docker.io/ocpqe/hello-pod
- team4a Pod は team4 Pod と同じノードにスケジュールされます。
14.7.3.2. Pod の非アフィニティー
以下の例は、一致するラベルとラベルセレクターを持つ Pod についての Pod の非アフィニティーを示しています。
Pod pod-s1 にはラベル
security:s1
が付けられています。cat pod-s1.yaml apiVersion: v1 kind: Pod metadata: name: s1 labels: security: s1 spec: containers: - name: ocp image: docker.io/ocpqe/hello-pod
Pod pod-s2 には、
podAntiAffinity
の下にラベルセレクターsecurity:s1
が付けられています。cat pod-s2.yaml apiVersion: v1 kind: Pod metadata: name: pod-s2 spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - s1 topologyKey: kubernetes.io/hostname containers: - name: pod-antiaffinity image: docker.io/ocpqe/hello-pod
Pod pod-s2 は、
security:s2
ラベルの付いた Pod を持つノードがない場合はスケジュールされません。そのラベルの付いた他の Pod がない場合、新規 Pod は保留状態のままになります。NAME READY STATUS RESTARTS AGE IP NODE pod-s2 0/1 Pending 0 32s <none>
14.7.3.3. 一致するラベルのない Pod のアフィニティー
以下の例は、一致するラベルとラベルセレクターのない Pod についての Pod のアフィニティーを示しています。
Pod pod-s1 にはラベル
security:s1
が付けられています。$ cat pod-s1.yaml apiVersion: v1 kind: Pod metadata: name: pod-s1 labels: security: s1 spec: containers: - name: ocp image: docker.io/ocpqe/hello-pod
Pod pod-s2 にはラベルセレクター
security:s2
があります。$ cat pod-s2.yaml apiVersion: v1 kind: Pod metadata: name: pod-s2 spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - s2 topologyKey: kubernetes.io/hostname containers: - name: pod-affinity image: docker.io/ocpqe/hello-pod
-
Pod pod-s2 は
pod-s1
と同じノードにスケジュールできません。
14.8. 詳細スケジューリングおよびノードセレクター
14.8.1. 概要
A node selector specifies a map of key-value pairs. The rules are defined using custom labels on nodes and selectors specified in pods.
Pod がノードで実行する要件を満たすには、Pod はノードのラベルとして示されるキーと値のペアを持っている必要があります。
同じ Pod 設定でノードのアフィニティーと ノードセレクターを使用している場合は、以下の「重要な考慮事項」を参照してください。
14.8.2. ノードセレクターの設定
Pod 設定で nodeSelector
を使用することで、Pod を特定のラベルの付いたノードのみに配置することができます。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeSelector
値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeSelector: <key>: <value> ...
Modify the master configuration file (/etc/origin/master/master-config.yaml) in two places:
Add
nodeSelectorLabelBlacklist
to theadmissionConfig
section with the labels that are assigned to the node hosts you want to deny pod placement:... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...
Then, add the same to the
kubernetesMasterConfig
section to restrict direct pod creation:... kubernetesMasterConfig: admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiVersion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label_1> ...
変更を有効にするために OpenShift Container Platform を再起動します。
# systemctl restart atomic-openshift-master
同じ Pod 設定でノードセレクターとノードのアフィニティーを使用している場合は、以下に注意してください。
-
nodeSelector
とnodeAffinity
の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。 -
nodeAffinity
タイプに関連付けられた複数のnodeSelectorTerms
を指定する場合、nodeSelectorTerms
のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。 -
nodeSelectorTerms
に関連付けられた複数のmatchExpressions
を指定する場合、すべてのmatchExpressions
が満たされている場合にのみ Pod をノードにスケジュールすることができます。
14.9. 詳細スケジューリングおよび容認
14.9.1. 概要
テイントおよび容認により、ノード はノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。
14.9.2. テイントおよび容認 (Toleration)
テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。
テイントはノード仕様 (NodeSpec
) でノードに適用され、容認は Pod 仕様 (PodSpec
) で Pod に適用されます。ノードのテイントはノードに対し、テイントを容認しないすべての Pod を拒否するよう指示します。
テイントおよび容認は、key、value、および effect.で構成されています。演算子により、これらの 3 つのパラメーターのいずれかを空のままにすることができます。
パラメーター | 説明 | ||||||
---|---|---|---|---|---|---|---|
|
| ||||||
|
| ||||||
|
effect は以下のいずれかにすることができます。
| ||||||
|
|
容認はテイントと一致します。
operator
パラメーターがEqual
に設定されている場合:-
key
パラメーターは同じになります。 -
value
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
operator
パラメーターがExists
に設定されている場合:-
key
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
14.9.2.1. 複数テイントの使用
複数のテイントを同じノードに、複数の容認を同じ Pod に配置することができます。OpenShift Container Platform は複数のテイントと容認を以下のように処理します。
- Pod に一致する容認のあるテイントを処理します。
残りの一致しないテイントは Pod について以下の effect を持ちます。
-
effect が
NoSchedule
の一致しないテイントが 1 つ以上ある場合、OpenShift Container Platform は Pod をノードにスケジュールできません。 -
effect が
NoSchedule
の一致しないテイントがなく、effect がPreferNoSchedule
の一致しない テイントが 1 つ以上ある場合、OpenShift Container Platform は Pod のノードへのスケジュールを試行しません。 effect が
NoExecute
のテイントが 1 つ以上ある場合、OpenShift Container Platform は Pod をノードからエビクトするか (ノードですでに実行中の場合)、または Pod のそのノードへのスケジュールが実行されません (ノードでまだ実行されていない場合)。- テイントを容認しない Pod はすぐにエビクトされます。
-
容認の仕様に
tolerationSeconds
を指定せずにテイントを容認する Pod は永久にバインドされたままになります。 -
指定された
tolerationSeconds
を持つテイントを容認する Pod は指定された期間バインドされます。
-
effect が
例:
ノードには以下のテイントがあります。
$ oc adm taint nodes node1 key1=value1:NoSchedule $ oc adm taint nodes node1 key1=value1:NoExecute $ oc adm taint nodes node1 key2=value2:NoSchedule
Pod には以下の容認があります。
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute"
この場合、3 つ目のテイントに一致する容認がないため、Pod はノードにスケジュールできません。Pod はこのテイントの追加時にノードですでに実行されている場合は実行が継続されます。3 つ目のテイントは 3 つのテイントの中で Pod で容認されない唯一のテイントであるためです。
14.9.3. テイントの既存ノードへの追加
テイントおよび容認コンポーネントの表で説明されているパラメーターと共に oc adm taint
コマンドを使用してテイントをノードに追加します。
$ oc adm taint nodes <node-name> <key>=<value>:<effect>
例:
$ oc adm taint nodes node1 key1=value1:NoSchedule
The example places a taint on node1
that has key key1
, value value1
, and taint effect NoSchedule
.
14.9.4. 容認の Pod への追加
容認を Pod に追加するには、Pod 仕様を tolerations
セクションを含めるように編集します。
Equal
演算子を含む Pod 設定ファイルのサンプル
tolerations: - key: "key1" 1 operator: "Equal" 2 value: "value1" 3 effect: "NoExecute" 4 tolerationSeconds: 3600 5
- 1 2 3 4
- テイントおよび容認コンポーネント の表で説明されている toleration パラメーターです。
- 5
tolerationSeconds
パラメーターは、Pod がエビクトされる前にノードにバインドされる期間を指定します。以下の「Pod エビクションを遅延させる容認期間 (秒数) の使用」を参照してください。
Exists
演算子を含む Pod 設定ファイルのサンプル
tolerations: - key: "key1" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600
これらの容認のいずれも上記の oc adm taint
コマンドで作成されるテイントに一致します。いずれかの容認のある Pod は node1
にスケジュールできます。
14.9.4.1. Pod のエビクションを遅延させる容認期間 (秒数) の使用
Pod 仕様に tolerationSeconds
パラメーターを指定して、Pod がエビクトされる前にノードにバインドされる期間を指定できます。effect NoExecute
のあるテイントがノードに追加される場合、テイントを容認しない Pod は即時にエビクトされます (テイントを容認する Pod はエビクトされません)。ただし、エビクトされる Pod に tolerationSeconds
パラメーターがある場合、Pod は期間切れになるまでエビクトされません。
例:
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600
ここで、この Pod が実行中であるものの、一致するテイントがない場合、Pod は 3,600 秒間バインドされたままとなり、その後にエビクトされます。テイントが期限前に削除される場合、Pod はエビクトされません。
14.9.4.1.1. 容認の秒数のデフォルト値の設定
This plug-in sets the default forgiveness toleration for pods, to tolerate the node.alpha.kubernetes.io/notReady:NoExecute
and node.alpha.kubernetes.io/notReady:NoExecute
taints for five minutes.
ユーザーが提供する Pod 設定にいずれかの容認がある場合、デフォルトは追加されません。
デフォルトの容認の秒数を有効にするには、以下を実行します。
マスター設定ファイル (/etc/origin/master/master-config.yaml) を変更して
DefaultTolerationSeconds
を admissionConfig セクションに追加します。admissionConfig: pluginConfig: DefaultTolerationSeconds: configuration: kind: DefaultAdmissionConfig apiVersion: v1 disable: false
変更を有効にするために、OpenShift を再起動します。
# systemctl restart atomic-openshift-master-api atomic-openshift-master-controllers
デフォルトが追加されていることを確認します。
Pod を作成します。
$ oc create -f </path/to/file>
例:
$ oc create -f hello-pod.yaml pod "hello-pod" created
Pod の容認を確認します。
$ oc describe pod <pod-name> |grep -i toleration
例:
$ oc describe pod hello-pod |grep -i toleration Tolerations: node.alpha.kubernetes.io/notReady=:Exists:NoExecute for 300s
14.9.5. Preventing Pod Eviction for Node Problems
OpenShift Container Platform は、node unreachable および node not ready 状態をテイントとして表示するよう設定できます。これにより、デフォルトの 5 分を使用するのではなく、unreachable (到達不能) または not ready (準備ができていない) 状態になるノードにバインドされたままになる期間を Pod 仕様ごとに指定することができます。
テイントベースのエビクション機能が有効にされた状態で、テイントはノードコントローラーによって自動的に追加され、Pod を Ready
ノードからエビクトするための通常のロジックは無効にされます。
-
If a node enters a not ready state, the
node.alpha.kubernetes.io/notReady:NoExecute
taint is added and pods cannot be scheduled on the node. Existing pods remain for the toleration seconds period. -
If a node enters a not reachable state, the
node.alpha.kubernetes.io/unreachable:NoExecute
taint is added and pods cannot be scheduled on the node. Existing pods remain for the toleration seconds period.
テイントベースのエビクションを有効にするには、以下を実行します。
マスター設定ファイル (/etc/origin/master/master-config.yaml) を変更して以下を
kubernetesMasterConfig
セクションに追加します。kubernetesMasterConfig: controllerArguments: feature-gates: - "TaintBasedEvictions=true"
テイントがノードに追加されていることを確認します。
oc describe node $node | grep -i taint Taints: node.alpha.kubernetes.io/notReady:NoExecute
変更を有効にするために、OpenShift を再起動します。
# systemctl restart atomic-openshift-master-api atomic-openshift-master-controllers
容認を Pod に追加します。
tolerations: - key: "node.alpha.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 6000
または、以下を実行します。
tolerations: - key: "node.alpha.kubernetes.io/notReady" operator: "Exists" effect: "NoExecute" tolerationSeconds: 6000
ノードの問題の発生時に Pod エビクションの既存のレート制限の動作を維持するために、システムはテイントをレートが制限された方法で追加します。これにより、マスターがノードからパーティション化される場合などのシナリオで発生する大規模な Pod エビクションを防ぐことができます。
14.9.6. Daemonset および容認
DaemonSet pods are created with NoExecute
tolerations for node.alpha.kubernetes.io/unreachable
and node.alpha.kubernetes.io/notReady
with no tolerationSeconds
to ensure that DaemonSet pods are never evicted due to these problems, even when the Default Toleration Seconds feature is disabled.
14.9.7. 例
テイントおよび容認は、Pod をノードから切り離し、ノードで実行されるべきでない Pod をエビクトする柔軟性のある方法として使用できます。以下は典型的なシナリオのいくつかになります。
14.9.7.1. ノードをユーザー専用にする
ノードのセットを特定のユーザーセットが排他的に使用するように指定できます。
専用ノードを指定するには、以下を実行します。
テイントをそれらのノードに追加します。
例:
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
Add a corresponding toleration to the pods by writing a custom admission controller.
容認のある Pod のみが専用ノードを使用することを許可されます。
14.9.7.2. ユーザーのノードへのバインド
特定ユーザーが専用ノードのみを使用できるようにノードを設定することができます。
ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。
テイントをそれらのノードに追加します。
例:
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
Add a corresponding toleration to the pods by writing a custom admission controller.
受付コントローラーは、Pod が
key:value
ラベル (dedicated=groupName
) が付けられたノードのみにスケジュールされるようにノードのアフィニティーを追加します。-
テイントと同様のラベル (
key:value
ラベルなど) を専用ノードに追加します。
14.9.7.3. 特殊ハードウェアを持つノード
ノードの小規模なサブセットが特殊ハードウェア(GPU など) を持つクラスターでは、テイントおよび容認を使用して、特殊ハードウェアを必要としない Pod をそれらのノードから切り離し、特殊ハードウェアを必要とする Pod をそのままにすることができます。また、特殊ハードウェアを必要とする Pod に対して特定のノードを使用することを要求することもできます。
Pod が特殊ハードウェアからブロックされるようにするには、以下を実行します。
以下のコマンドのいずれかを使用して、特殊ハードウェアを持つノードにテイントを設定します。
$ oc adm taint nodes <node-name> disktype=ssd:NoSchedule $ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
- Adding a corresponding toleration to pods that use the special hardware using an admission controller.
たとえば受付コントローラーは容認を追加することで、Pod の一部の特徴を使用し、Pod が特殊ノードを使用できるかどうかを判別できます。
Pod が特殊ハードウェアのみを使用できるようにするには、追加のメカニズムが必要です。たとえば、特殊ハードウェアを持つノードにラベルを付け、ハードウェアを必要とする Pod でノードのアフィニティーを使用できます。