第16章 スケジューリング
16.1. 概要
16.1.1. 概要
Pod のスケジューリングは、クラスター内のノードへの新規 Pod の配置を決定する内部プロセスです。
スケジューラーコードは、新規 Pod の作成時にそれらを確認し、それらをホストするのに最も適したノードを識別します。次に、マスター API を使用して Pod のバインディング (Pod とノードのバインディング) を作成します。
16.1.2. デフォルトスケジューリング
OpenShift Container Platform には、ほとんどのユーザーのニーズに対応するデフォルトスケジューラーが同梱されます。デフォルトスケジューラーは、Pod に最適なノードを判別するための固有のツールおよびカスタマイズ可能なツールの両方を使用します。
デフォルトスケジューラーが Pod の配置と利用できるカスタマイズ可能なパラメーターを判別する方法についての詳細は、「デフォルトスケジューリング」を参照してください。
16.1.3. 詳細スケジューリング
新規 Pod の配置場所に対する制御を強化する必要がある場合、OpenShift Container Platform の詳細スケジューリング機能を使用すると、Pod が特定ノード上か、または特定の Pod と共に実行されることを要求する (または実行されることが優先される) よう Pod を設定することができます。また詳細設定により、Pod をノードに配置することや他の Pod と共に実行することを防ぐこともできます。
詳細スケジューリングについての詳細は、「詳細スケジューリング」を参照してください。
16.1.4. カスタムスケジューリング
OpenShift Container Platform では、Pod 仕様を編集してユーザー独自のスケジューラーまたはサードパーティーのスケジューラーを使用することもできます。
詳細は、「カスタムスケジューラー」を参照してください。
16.2. デフォルトスケジューリング
16.2.1. 概要
OpenShift Container Platform のデフォルトの Pod スケジューラーは、クラスター内のノードにおける新規 Pod の配置場所を判別します。スケジューラーは Pod からのデータを読み取り、設定されるポリシーに基づいて適切なノードを見つけようとします。これは完全に独立した機能であり、スタンドアロン/プラグ可能ソリューションです。Pod を変更することはなく、Pod を特定ノードに関連付ける Pod のバインディングのみを作成します。
16.2.2. 汎用スケジューラー
既存の汎用スケジューラーはプラットフォームで提供されるデフォルトのスケジューラー エンジン であり、Pod をホストするノードを 3 つの手順で選択します。
- スケジューラーは 述語を使用して不適切なノードをフィルターに掛けて除外します。
- スケジューラーは ノードのフィルターされた一覧の優先順位付けを行います。
- スケジューラーは、Pod の最も優先順位の高い Pod を選択します。
16.2.3. ノードのフィルター
利用可能なノードは、指定される制約や要件に基づいてフィルターされます。フィルターは、各ノードで 述語 というフィルター関数の一覧を使用して実行されます。
16.2.3.1. フィルターされたノード一覧の優先順位付け
優先順位付けは、各ノードに一連の優先度関数を実行することによって行われます。この関数は 0 -10 までのスコアをノードに割り当て、0 は不適切であることを示し、10 は Pod のホストに適していることを示します。スケジューラー設定は、それぞれの優先度関数について単純な 重み (正の数値) を取ることができます。各優先度関数で指定されるノードのスコアは重み (ほとんどの優先度のデフォルトの重みは 1) で乗算され、すべての優先度で指定されるそれぞれのノードのスコアを追加して組み合わされます。この重み属性は、一部の優先度により重きを置くようにするなどのために管理者によって使用されます。
16.2.3.2. 最適ノードの選択
ノードの並び替えはそれらのスコアに基づいて行われ、最高のスコアを持つノードが Post をホストするように選択されます。複数のノードに同じ高スコアが付けられている場合、それらのいずれかがランダムに選択されます。
16.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 } ] }
16.2.4.1. スケジューラーポリシーの変更
デフォルトで、スケジューラーポリシーはマスター設定ファイルの kubernetesMasterConfig.schedulerConfigFile
フィールドで上書きされない限り、/etc/origin/master/scheduler.json というマスターのファイルに定義されます。
変更されたスケジューラー設定ファイルのサンプル
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 を再起動します。
# master-restart api # master-restart controllers
16.2.5. 利用可能な述語
述語は、不適切なノードをフィルターに掛けるルールです。
OpenShift Container Platform には、デフォルトでいくつかの述語が提供されています。これらの述語の一部は、特定のパラメーターを指定してカスタマイズできます。複数の述語を組み合わせてノードの追加フィルターを指定できます。
16.2.5.1. 静的な述語
これらの述語はユーザーから設定パラメーターまたは入力を取りません。これらはそれぞれの正確な名前を使用してスケジューラー設定に指定されます。
16.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 は、Pod がメモリー不足 (memory pressure) 状況にあるノードでスケジュールできるかどうかを確認します。
{"name" : "CheckNodeMemoryPressure"}
16.2.5.1.2. 他の静的な述語
OpenShift Container Platform は以下の述語もサポートしています。
CheckNodeDiskPressure は、Pod がディスク不足 (disk pressure) の状況にあるノードでスケジュールできるかどうかを確認します。
{"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"}
16.2.5.2. 汎用的な述語
以下の汎用的な述語は、非クリティカル述語とクリティカル述語が渡されるかどうかを確認します。非クリティカル述語は、Critical Pod 以外の Pod のみが渡す必要のある述語であり、クリティカル述語はすべての Pod が渡す必要のある述語です。
デフォルトのスケジューラーポリシーにはこの汎用的な述語が含まれます。
汎用的な非クリティカル述語
PodFitsResources は、リソースの可用性 (CPU、メモリー、GPU など) に基づいて適切な候補を判別します。ノードはそれらのリソース容量を宣言し、Pod は要求するリソースを指定できます。使用されるリソースではなく、要求されるリソースに基づいて適切な候補が判別されます。
{"name" : "PodFitsResources"}
汎用的なクリティカル述語
PodFitsHostPorts は、ノードに要求される Pod ポートの空きポートがある (ポートの競合がない) かどうかを判別します。
{"name" : "PodFitsHostPorts"}
HostName は、ホストパラメーターの有無と文字列のホスト名との一致に基づいて適切なノードを判別します。
{"name" : "HostName"}
MatchNodeSelector は、Pod で定義されるノードセレクター (nodeSelector)のクエリーに基づいて適したノードを判別します。
{"name" : "MatchNodeSelector"}
16.2.5.3. 設定可能な述語
これらの述語はスケジューラー設定 /etc/origin/master/scheduler.json (デフォルト) に設定し、述語の機能に影響を与えるラベルを追加することができます。
これらは設定可能であるため、ユーザー定義の名前が異なる限り、同じタイプ (ただし設定パラメーターは異なる) の複数の述語を組み合わせることができます。
これらの優先度の使用方法についての情報は、「スケジューラーポリシーの変更」を参照してください。
ServiceAffinity は、Pod で実行されるサービスに基づいて Pod をノードに配置します。同じノードまたは併置されているノードに同じサービスの複数の Pod を配置すると、効率が向上する可能性があります。
この述語は ノードセレクターの特定ラベルを持つ Pod を同じラベルを持つノードに配置しようとします。
Pod がノードセレクターでラベルを指定していない場合、最初の Pod は可用性に基づいて任意のノードに配置され、該当サービスの後続のすべての Pod はそのノードと同じラベルの値を持つノードにスケジュールされます。
"predicates":[ { "name":"<name>", 1 "argument":{ "serviceAffinity":{ "labels":[ "<label>" 2 ] } } } ],
以下に例を示します。
"name":"ZoneAffinity", "argument":{ "serviceAffinity":{ "labels":[ "rack"
たとえば、ノードセレクター rack
を持つサービスの最初の Pod がラベル region=rack
を持つノードにスケジュールされている場合、同じサービスに属するその他すべての後続の Pod は同じ region=rack
ラベルを持つノードにスケジュールされます。詳細は、「Pod 配置の制御」を参照してください。
複数レベルのラベルもサポートされています。ユーザーは同じリージョン内および (リージョン下の) 同じゾーン内のノードでスケジュールされるようサービスのすべての Pod を指定することもできます。
labelsPresence
パラメーターは特定のノードに特定のラベルがあるかどうかをチェックします。ラベルは、LabelPreference
の優先順位が使用するノード グループ を作成します。ラベルでのマッチングは、ノードにラベルで定義されている物理的な場所またはステータスがある場合などに役立ちます。
"predicates":[ { "name":"<name>", 1 "argument":{ "labelsPresence":{ "labels":[ "<label>" 2 ], "presence": true 3 } } } ],
以下に例を示します。
"name":"RackPreferred", "argument":{ "labelsPresence":{ "labels":[ "rack" "labelsPresence:"{ "labels:"[ "region" ], "presence": true } } } ],
16.2.6. 利用可能な優先度
優先度は、設定に応じて残りのノードにランクを付けるルールです。
優先度のカスタムセットは、スケジューラーを設定するために指定できます。OpenShift Container Platform ではデフォルトでいくつかの優先度があります。他の優先度は、特定のパラメーターを指定してカスタマイズできます。優先順位に影響を与えるために、複数の優先度を組み合わせ、異なる重みをそれぞれのノードに指定することができます。
16.2.6.1. 静的優先度
静的優先度は、重みを除き、ユーザーからいずれの設定パラメーターも取りません。重みは指定する必要があり、0 または負の値にすることはできません。
これらはスケジューラー設定 /etc/origin/master/scheduler.json (デフォルト) に指定されます。
16.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}
16.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}
16.2.6.2. 設定可能な優先度
これらの優先度は、デフォルトでスケジューラー設定 /etc/origin/master/scheduler.json で設定し、これらの優先度に影響を与えるラベルを追加できます。
優先度関数のタイプは、それらが取る引数によって識別されます。これらは設定可能なため、ユーザー定義の名前が異なる場合に、同じタイプの (ただし設定パラメーターは異なる) 設定可能な複数の優先度を組み合わせることができます。
これらの優先度の使用方法についての情報は、「スケジューラーポリシーの変更」を参照してください。
ServiceAntiAffinity はラベルを取り、ラベルの値に基づいてノードのグループ全体に同じサービスに属する Pod を適正に分散します。これは、指定されたラベルの同じ値を持つすべてのノードに同じスコアを付与します。また Pod が最も集中していないグループ内のノードにより高いスコアを付与します。
"priorities":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "serviceAntiAffinity":{ "label":[ "<label>" 3 ] } } } ]
以下に例を示します。
"name":"RackSpread", 1 "weight" : "1" 2 "argument":{ "serviceAffinity":{ "label":[ 3 "rack"
カスタムラベルに基づいて ServiceAntiAffinity
を使用しても Pod を予想通りに展開できない場合があります。この Red Hat ソリューションを参照してください。
*labelPreference
パラメーターは指定されたラベルに基づいて優先順位を指定します。ラベルがノードにある場合、そのノードに優先度が指定されます。ラベルが指定されていない場合は、優先度はラベルを持たないノードに指定されます。
"priorities":[ { "name":"<name>", 1 "weight" : "1" 2 "argument":{ "labelPreference":{ "label":[ "<label>" 3 ] } } } ],
16.2.7. 使用例
OpenShift Container Platform 内でのスケジューリングの重要な使用例として、柔軟なアフィニティーと非アフィニティーポリシーのサポートを挙げることができます。
16.2.7.1. インフラストラクチャーのトポロジーレベル
管理者は、ノードのラベル (例: region=r1
、zone=z1
、rack=s1
) を指定してインフラストラクチャーの複数のトポロジーレベルを定義することができます。
これらのラベル名には特別な意味はなく、管理者はそれらのインフラストラクチャーラベルに任意の名前 (例: 都市/建物/部屋) を付けることができます。さらに、管理者はインフラストラクチャートポロジーに任意の数のレベルを定義できます。通常は、(regions
zones
racks
などの) 3 つのレベルが適切なサイズです。管理者はこれらのレベルのそれぞれにアフィニティーと非アフィニティールールを任意の組み合わせで指定することができます。
16.2.7.2. アフィニティー
管理者は、任意のトポロジーレベルまたは複数のレベルでもアフィニティーを指定できるようにスケジューラーを設定することができます。特定レベルのアフィニティーは、同じサービスに属するすべての Pod が同じレベルに属するノードにスケジュールされることを示します。これは、管理者がピア Pod が地理的に離れ過ぎないようにすることでアプリケーションの待機時間の要件に対応します。同じアフィニティーグループ内で Pod をホストするために利用できるノードがない場合、Pod はスケジュールされません。
Pod がスケジュールされる場所に対する制御を強化する必要がある場合は、「ノードアフィニティーの使用」および「Pod のアフィニティーおよび非アフィニティーの使用」を参照してください。これらの詳細スケジューリング機能により、管理者は Pod をスケジュールできるノードを指定し、他の Pod に関連してスケジューリングを強制的に実行したり、拒否したりできます。
16.2.7.3. 非アフィニティー
管理者は、任意のトポロジーレベルまたは複数のレベルでも非アフィニティーを設定できるようスケジューラーを設定することができます。特定レベルの非アフィニティー (または「分散」)は、同じサービスに属するすべての Pod が該当レベルに属するノード全体に分散されることを示します。これにより、アプリケーションが高可用性の目的で適正に分散されます。スケジューラーは、可能な限り均等になるようにすべての適用可能なノード全体にサービス Pod を配置しようとします。
Pod がスケジュールされる場所に対する制御を強化する必要がある場合は、「ノードアフィニティーの使用」および「Pod のアフィニティーおよび非アフィニティーの使用」を参照してください。これらの詳細スケジューリング機能により、管理者は Pod をスケジュールできるノードを指定し、他の Pod に関連してスケジューリングを強制的に実行したり、拒否したりできます。
16.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
16.3. 再スケジュール (Descheduling)
16.3.1. 概要
再スケジュール (Descheduling) には、Pod がより適切なノードに再スケジュールされるように特定のポリシーに基づいて Pod をエビクトすることが関係しています。
クラスターには、すでに実行されている Pod をスケジュール解除し、再スケジュールできることによる利点があり、スケジュール解除および再スケジュールは各種の理由によって実行されます。
- ノードの使用率が低くなっているか、または高くなっている。
- テイントまたはラベルなどの、Pod およびノードアフィニティーの各種要件が変更され、当初のスケジューリングの意思決定が特定のノードに適さなくなっている。
- ノードの障害により、Pod を移動する必要がある。
- 新規ノードがクラスターに追加されている。
Descheduler はエビクトされた Pod の置き換えをスケジュールしません。スケジューラー は、エビクトされた Pod に対してこのタスクを自動的に実行します。
Heapster および DNS など、クラスターの完全な機能に欠かせないコアコンポーネントであるものの、マスターではなく通常のクラスターノードで実行されるコアコンポーネントが多数あることに留意する必要があります。クラスターはコンポーネントがエビクトされると正常な機能を停止する可能性があります。Descheduler がこれらの Pod を削除することを防ぐには、scheduler.alpha.kubernetes.io/critical-pod
アノテーションを Pod 仕様に追加して、Pod を Critical Pod として設定します。
Descheduler ジョブは Critical Pod としてみなされ、これは Descheduler Pod が Descheduler のエビクトの対象になることを防ぎます。
Descheduler ジョブおよび Descheduler Pod は、デフォルトで作成される kube-system
プロジェクトに作成されます。
Descheduler はテクノロジープレビュー機能です。テクノロジープレビュー機能は Red Hat の実稼働環境でのサービスレベルアグリーメント (SLA) ではサポートされていないため、Red Hat では実稼働環境での使用を推奨していません。これらの機能は、近々発表予定の製品機能をリリースに先駆けてご提供することにより、お客様は機能性をテストし、開発プロセス中にフィードバックをお寄せいただくことができます。
Red Hat のテクノロジープレビュー機能のサポートについての詳細は、https://access.redhat.com/support/offerings/techpreview/ を参照してください。
Descheduler は以下のタイプの Pod をエビクトしません。
-
Critical Pod (
scheduler.alpha.kubernetes.io/critical-pod
アノテーションを持つ)。 - レプリカセット、レプリケーションコントローラー、デプロイメント、またはジョブに関連付けられていない Pod (静的およびミラー Pod またはスタンドアロンモードの Pod) (これらの Pod 再作成されないため)。
- DaemonSet に関連付けられた Pod。
- ローカルストレージを持つ Pod。
- Pod の Disruption Budget (PDB) が適用される Pod は、スケジュール解除が PDB に違反する場合にエビクトされません。Pod は、エビクションポリシーを使用してエビクトできます。
Best Effort Pod は、Burstable および Guaranteed Pod の前にエビクトされます。
以下のセクションでは、Descheduler を設定し、実行するプロセスについて説明します。
- ロールを作成します。
- ポリシーファイルにスケジュール解除動作を定義します。
- ポリシーファイルを参照するための参照マップを作成します。
- Descheduler ジョブ設定を作成します。
- Descheduler ジョブを実行します。
16.3.2. クラスターロールの作成
Descheduler が Pod で機能するために必要なパーミッションを設定するには、以下を実行します。
以下のルールでクラスターロールを作成します。
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: descheduler-cluster-role rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "watch", "list"] 1 - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list", "delete"] 2 - apiGroups: [""] resources: ["pods/eviction"] 3 verbs: ["create"]
ジョブを実行するために使用されるサービスアカウントを作成します。
# oc create sa <file-name>.yaml -n kube-system
以下に例を示します。
# oc create sa descheduler-sa.yaml -n kube-system
クラスターロールをサービスアカウントにバインドします。
# oc create clusterrolebinding descheduler-cluster-role-binding \ --clusterrole=<cluster-role-name> \ --serviceaccount=kube-system:<service-account-name>
以下に例を示します。
# oc create clusterrolebinding descheduler-cluster-role-binding \ --clusterrole=descheduler-cluster-role \ --serviceaccount=kube-system:descheduler-sa
16.3.3. Descheduler ポリシーの作成
Descheduler は、YAML ポリシーファイルの strategies で定義されるルールに違反するノードから Pod を削除するように設定できます。ジョブ仕様にポリシーファイルへのパスを組み込み、特定のスケジュール解除ストラテジーを適用します。
Descheduler ポリシーファイルのサンプル
apiVersion: "descheduler/v1alpha1" kind: "DeschedulerPolicy" strategies: "RemoveDuplicates": enabled: false "LowNodeUtilization": enabled: true params: nodeResourceUtilizationThresholds: thresholds: "cpu" : 20 "memory": 20 "pods": 20 targetThresholds: "cpu" : 50 "memory": 50 "pods": 50 numberOfNodes: 3 "RemovePodsViolatingInterPodAntiAffinity": enabled: true
Descheduler で使用できるデフォルトストラテジーとして、 3 つのストラテジーがあります。
-
重複 Pod の削除 (
RemoveDuplicates
) -
Pod の使用率の低いノードへの移動 (
LowNodeUtilization
) -
非アフィニティールールに違反する Pod の削除 (
RemovePodsViolatingInterPodAntiAffinity
)
ストラテジーに関連付けられたパラメーターを必要に応じて設定し、無効にすることができます。
16.3.3.1. 重複 Pod の削除
RemoveDuplicates
ストラテジーでは、1 つの Pod のみが同じノードで実行されている レプリカセット、レプリケーションコントローラー、デプロイメント設定、または ジョブに関連付けられます。これらのオブジェクトに関連付けられている他の Pod がある場合、重複 Pod はエビクトされます。重複 Pod をエビクトすると、Pod をクラスター内により効果的に分散できます。
たとえば、ノードが失敗し、ノード上の Pod が別のノードに移行した場合に、複数の Pod が同じノードで実行されているレプリカセットまたはレプリケーションコントローラーに関連付けられると、重複 Pod が発生する可能性があります。失敗したノードが再び準備可能になると、それらの重複 Pod をエビクトするためにこのストラテジーが使用される可能性があります。
このストラテジーに関連付けられるパラメーターはありません。
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemoveDuplicates":
enabled: false 1
- 1
- このポリシーを使用するには、この値を
enabled: true
に設定します。このポリシーを無効にするには、false
に設定します。
16.3.3.2. ノードの低使用率ポリシー (Low Node Utilization Policy) の作成
LowNodeUtilization
ストラテジーは、使用率の低いノードを検出し、他のノードから Pod をエビクトして、エビクトされた Pod がそれらの使用率の低いノードにスケジュールされるようにします。
ノードの使用率は、CPU、メモリーまたは Pod 数の設定可能なしきい値 thresholds
(パーセンテージベース) で決定されます。ノードの使用率がこれらのしきい値のすべてを下回る場合、ノードの使用率は低いとみなされ、Descheduler は Pod を他のノードからエビクトする可能性があります。Pod の要求リソース要件は、ノードのリソース使用率を計算する際に考慮されます。
高いしきい値の targetThresholds
は、使用率が適性なノードを判別するために使用されます。thresholds と targetThresholds 間にあるノードの使用率は適性であるとみなされ、エビクションの対象にはなりません。しきい値 targetThresholds
は、CPU、メモリーおよび Pod 数について設定できます (パーセンテージベース)。
これらのしきい値はクラスター要件に合わせて調整できます。
numberOfNodes
パラメーターは、使用率の低いノードの数が設定された値を上回る場合にのみストラテジーをアクティブにするために設定できます。いくつかのノードの使用率が低くなることが許容される場合にこのパラメーターを設定します。デフォルトで、numberOfNodes
はゼロに設定されます。
apiVersion: "descheduler/v1alpha1" kind: "DeschedulerPolicy" strategies: "LowNodeUtilization": enabled: true params: nodeResourceUtilizationThresholds: thresholds: 1 "cpu" : 20 "memory": 20 "pods": 20 targetThresholds: 2 "cpu" : 50 "memory": 50 "pods": 50 numberOfNodes: 3 3
16.3.3.3. Pod 間の非アフィニティー (Inter-Pod Anti-Affinity) に違反する Pod の削除
RemovePodsViolatingInterPodAntiAffinity
ストラテジーは、Pod 間の非アフィニティー (inter-pod anti-affinity) に違反する Pod がノードから削除されるようにします。
たとえば、 Node1 には podA、podB、および podC があるとします。podB および podC には、podA と同じノードでそれらが実行されることを禁止する非アフィニティールールがあります。podA はノードからエビクトされ、podB および podC がそのノードで実行されるようになります。この状況は、podB および podC がノード上で実行されている際に非アフィニティールールが適用される場合に生じます。
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
"RemovePodsViolatingInterPodAntiAffinity": 1
enabled: true
- 1
- このポリシーを使用するには、この値を
enabled: true
に設定します。このポリシーを無効にするには、false
に設定します。
16.3.4. 設定マップでの Descheduler ポリシーの設定
kube-system
プロジェクトで Descheduler ポリシーファイルの設定マップを作成し、これが Descheduler ジョブで参照されるようにします。
# oc create configmap descheduler-policy-configmap \
-n kube-system --from-file=<path-to-policy-dir/policy.yaml> 1
- 1
- 作成したポリシーファイルのパスです。
16.3.5. ジョブ仕様の作成
Descheduler のジョブ設定を作成します。
apiVersion: batch/v1 kind: Job metadata: name: descheduler-job namespace: kube-system spec: parallelism: 1 completions: 1 template: metadata: name: descheduler-pod 1 annotations: scheduler.alpha.kubernetes.io/critical-pod: "true" 2 spec: containers: - name: descheduler image: descheduler volumeMounts: 3 - mountPath: /policy-dir name: policy-volume command: - "/bin/sh" - "-ec" - | /bin/descheduler --policy-config-file /policy-dir/policy.yaml 4 restartPolicy: "Never" serviceAccountName: descheduler-sa 5 volumes: - name: policy-volume configMap: name: descheduler-policy-configmap
ポリシーファイルは、設定マップからボリュームとしてマウントされます。
16.3.6. Descheduler の実行
Descheduler を Pod のジョブとして実行するには、以下を実行します。
# oc create -f <file-name>.yaml
以下に例を示します。
# oc create -f descheduler-job.yaml
16.4. カスタムスケジューリング
16.4.1. 概要
デフォルトのスケジューラーと共に複数のカスタムスケジューラーを実行し、各 Pod に使用できるスケジューラーを設定できます。
特定のスケジューラーを使用して指定された Pod をスケジュールするには、Pod 仕様にスケジューラーの名前を指定します。
16.4.2. スケジューラーのデプロイ
以下の手順は、スケジューラーをクラスターにデプロイするための一般的なプロセスです。
スケジューラーの作成/デプロイ方法については、本書では扱いません。これらについては、Kubernetes ソースディレクトリーの plugin/pkg/scheduler などを参照してください。
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
以下のコマンドを実行し、Pod がカスタムスケジューラーで作成されていることを確認します。
$ oc get pod custom-scheduler -o yaml
以下のコマンドを実行して Pod のステータスを確認します。
$ oc get pod
Pod は実行されていないはずです。
NAME READY STATUS RESTARTS AGE custom-scheduler 0/1 Pending 0 2m
- カスタムスケジューラーをデプロイします。
以下のコマンドを実行して Pod のステータスを確認します。
$ oc get pod
Pod は実行されているはずです。
NAME READY STATUS RESTARTS AGE custom-scheduler 1/1 Running 0 4m
以下のコマンドを実行し、スケジューラーが使用されていることを確認します。
$ 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> [...]
16.5. Pod 配置の制御
16.5.1. 概要
クラスター管理者は、特定のロールを持つアプリケーション開発者が Pod のスケジュール時に特定ノードをターゲットとすることを防ぐポリシーを設定できます。
Pod ノード制約の受付コントローラーは、Pod がラベルを使用して指定されたノードホストのみにデプロイされるようにし、特定のロールを持たないユーザーが nodeSelector
フィールドを使用して Pod をスケジュールできないようにします。
16.5.2. ノード名の使用による Pod 配置の制約
Pod ノード制約の受付コントローラーを使用し、Pod にラベルを割り当て、これを Pod 設定の nodeName
設定に指定することで、Pod が指定されたノードホストにのみデプロイされるようにします。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeName
値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeName: <value>
マスター設定ファイル (/etc/origin/master/master-config.yaml) を変更して
PodNodeConstraints
をadmissionConfig
セクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig ...
変更を有効にするために OpenShift Container Platform を再起動します。
# master-restart controllers
16.5.3. ノードセレクターの使用による Pod 配置の制約
ノードセレクターを使用して、Pod が特定のラベルを持つノードにのみ配置されるようにすることができます。クラスター管理者は、Pod ノード制約の受付コントローラーを使用して、pods/binding パーミッションのないユーザーがノードセレクターを使用して Pod をスケジュールできないようにするポリシーを設定できます。
マスター設定ファイルの nodeSelectorLabelBlacklist
フィールドを使用して、一部のロールが Pod 設定の nodeSelector
フィールドで指定できるラベルを制御できます。pods/binding パーミッションロールを持つユーザー、サービスアカウントおよびグループは任意のノードセレクターを指定できます。pods/binding パーミッションがない場合は、nodeSelectorLabelBlacklist
に表示されるすべてのラベルに nodeSelector
を設定することは禁止されます。
たとえば、OpenShift Container Platform クラスターは、2 つの地域にまたがる 5 つのデータセンターで構成される場合があります。米国の us-east、us-central、および us-west、およびアジア太平洋 (APAC) の apac-east および apac-west です。それぞれの地理的地域の各ノードには、region: us-east
などのラベルが付けられます。たとえば、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> ...
マスター設定ファイル /etc/origin/master/master-config.yaml を変更し、
nodeSelectorLabelBlacklist
を、Pod の配置を拒否する必要のあるノードホストに割り当てられるラベルと共にadmissionConfig
セクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...
変更を有効にするために OpenShift Container Platform を再起動します。
# master-restart controllers
16.5.4. プロジェクト対する Pod 配置の制御
Pod ノードセレクターの受付コントローラーを使用して、Pod を特定のプロジェクトに関連付けられたノードに対して強制的に適用したり、Pod がそれらのノードでスケジュールされないようにしたりできます。
Pod ノードセレクターの受付コントローラーは、プロジェクトのラベルと Pod で指定されるノードセレクターを使用して Pod を配置する場所を決定します。新規 Pod は、Pod のノードセレクターがプロジェクトのラベルに一致する場合にのみプロジェクトに関連付けられたノードに配置されます。
Pod の作成後に、ノードセレクターは Pod にマージされ、Pod 仕様に元々含まれていたラベルとノードセレクターの新規ラベルが含まれるようにします。以下の例は、マージの結果について示しています。
Pod ノードセレクターの受付コントローラーにより、特定のプロジェクトで許可されるラベルの一覧を作成することもできます。この一覧は開発者がプロジェクトで使用できるラベルを認識するための ホワイトリスト として機能し、管理者がクラスターでのラベル設定の制御を強化するのに役立ちます。
Pod ノードセレクター の受付コントローラーをアクティブにするには、以下を実行します。
以下の方法のいずれかを使用して Pod ノードセレクター の受付コントローラーとホワイトリストを設定します。
以下をマスター設定ファイル (/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
受付コントローラーの情報を含むファイルを作成します。
podNodeSelectorPluginConfig: clusterDefaultNodeSelector: "k3=v3" ns1: region=west,env=test,infra=fedora,os=fedora
次に、マスター設定でファイルを参照します。
admissionConfig: pluginConfig: PodNodeSelector: location: <path-to-file>
注記プロジェクトにノードセレクターが指定されていない場合、そのプロジェクトに関連付けられた Pod はデフォルトのノードセレクター (
clusterDefaultNodeSelector
) を使用してマージされます。
変更を有効にするために OpenShift Container Platform を再起動します。
# master-restart controllers
scheduler.alpha.kubernetes.io/node-selector
アノテーションおよびラベルを含むプロジェクトオブジェクトを作成します。apiVersion: v1 kind: Namespace metadata name: ns1 annotations: scheduler.alpha.kubernetes.io/node-selector: env=test,infra=fedora 1 spec: {}, status: {}
- 1
- プロジェクトのラベルセレクターに一致するラベルを作成するためのアノテーションです。ここで、キー/値のラベルは
env=test
およびinfra=fedora
になります。
注記Pod Node Selector 受付コントローラーを使用している場合、プロジェクトノードセレクターを設定するるために
oc adm new-project <project-name>
を設定することはできません。oc adm new-project myproject --node-selector='type=user-node,region=<region>
コマンドを使用してプロジェクトノードセレクターを設定する場合、OpenShift Container Platform はopenshift.io/node-selector
アノテーションを設定します。これは NodeEnv 受付プラグインで処理されます。ノードセレクターにラベルを含む 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 はそこにスケジュールされます。
16.6. 詳細スケジューリング
16.6.1. 概要
詳細スケジューリングには、Pod が特定ノードで実行されることを要求したり、Pod が特定ノードで実行されることが優先されるように Pod を設定することが関係します。
通常、詳細スケジューリングは必要になりません。OpenShift Container Platform が Pod を合理的な方法で自動的に配置するためです。たとえば、デフォルトスケジューラーは Pod をノード間で均等に分散し、ノードの利用可能なリソースを考慮します。ただし、Pod を配置する場所についてはさらに制御を強化する必要がある場合があります。
Pod をより高速なディスクが搭載されたマシンに配置する必要ある場合 (またはそのマシンに配置するのを防ぐ場合)、または 2 つの異なるサービスの Pod が相互に通信できるように配置する必要がある場合、詳細スケジューリングを使用してそれを可能にすることができます。
適切な新規 Pod を特定のノードグループにスケジュールし、その他の新規 Pod がそれらのノードでスケジュールされるのを防ぐには、必要に応じてこれらの方法を組み合わせることができます。
16.6.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 は拒否されることになります。
「テイントおよび容認の使用」を参照してください。
16.7. 詳細スケジューリングおよびノードのアフィニティー
16.7.1. 概要
ノードのアフィニティー は、Pod の配置場所を判別するためにスケジューラーによって使用されるルールのセットです。ルールはカスタムのノードのラベルと Pod で指定されるラベルセレクターを使って定義されます。ノードのアフィニティーにより、Pod ノード のグループに対してはアフィニティー (または非アフィニティー) を指定できます。ノード自体は配置に対して制御を行いません。
たとえば、Pod を特定の CPU を搭載したノードまたは特定のアベイラビリティーゾーンにあるノードでのみ実行されるよう設定することができます。
ノードのアフィニティールールには、required (必須) および preferred (優先) の 2 つのタイプがあります。
required (必須) ルールは、Pod をノードにスケジュールする前に 満たされている必要があります。一方、preferred (優先) ルールは、ルールが満たされる場合にスケジューラーがルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
ランタイム時にノードのラベルに変更が生じ、その変更により Pod でのノードのアフィニティールールを満たさなくなる状態が生じるでも、Pod はノードで引き続き実行されます。
16.7.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 をノードにスケジュールすることができます。
16.7.2.1. ノードアフィニティーの required (必須) ルールの設定
Pod がノードにスケジュールされる前に、required (必須) ルールを 満たしている必要があります。
以下の手順は、ノードとスケジューラーがノードに配置する必要のある Pod を作成する単純な設定を示しています。
ノード設定を編集するか、または
oc label node
コマンドを使用してラベルをノードに追加します。$ oc label node node1 e2e-az-name=e2e-az1
注記クラスターのノードを変更するには、ノード設定マップを必要に応じて更新します。
node-config.yaml
ファイルは手動で変更しないようにしてください。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
16.7.2.2. ノードアフィニティーの preferred (優先) ルールの設定
preferred (優先) ルールは、ルールを満たす場合に、スケジューラーはルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
以下の手順は、ノードとスケジューラーがノードに配置しようとする Pod を作成する単純な設定を示しています。
ノード設定を編集するか、または
oc label node
コマンドを実行してラベルをノードに追加します。$ oc label node node1 e2e-az-name=e2e-az3
注記クラスターのノードを変更するには、ノード設定マップを必要に応じて更新します。
node-config.yaml
ファイルは手動で変更しないようにしてください。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
16.7.3. 各種の例
以下の例は、ノードのアフィニティーを示しています。
16.7.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
16.7.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).
16.8. 詳細スケジューリングおよび Pod のアフィニティーと非アフィニティー
16.8.1. 概要
Pod のアフィニティー および Pod の非アフィニティー により、他の Pod との関連で Pod を配置する方法についてのルールを指定できます。ルールは、カスタムのノードのラベルおよび Pod で指定されるラベセレクターを使用して定義されます。Pod のアフィニティー/非アフィニティーにより、Pod はアフィニティー (または非アフィニティー) を、その配置に使用できる Pod のグループに対して指定できます。ノード自体は配置に対する制御を行いません。
たとえば、アフィニティールールを使用することで、サービス内で、または他のサービスの Pod との関連で Pod を分散したり、パックしたりすることができます。非アフィニティールールにより、特定のサービスの Pod がそののサービスの Pod のパフォーマンスに干渉すると見なされる別のサービスの Pod と同じノードでスケジュールされることを防ぐことができます。または、関連する障害を減らすために複数のノードまたはアベイラビリティーゾーン間でサービスの Pod を分散することもできます。
Pod のアフィニティー/非アフィニティーにより、他の Pod のラベルに基づいて Pod のスケジュール対象とするノードを制限することができます。ラベルはキー/値のペアです。
- Pod のアフィニティーはスケジューラーに対し、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に他の Pod と同じノードで新規 Pod を見つけるように指示します。
- Pod の非アフィニティーは、新規 Pod のラベルセレクターが現在の Pod のラベルに一致する場合に、同じラベルを持つ Pod と同じノードで新規 Pod を見つけることを禁止します。
Pod のアフィニティーには、required (必須) および preferred (優先) の 2 つのタイプがあります。
required (必須) ルールは、Pod をノードにスケジュールする前に 満たされている必要があります。一方、preferred (優先) ルールは、ルールが満たされる場合にスケジューラーがルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
16.8.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 topologyKey: kubernetes.io/hostname containers: - name: with-pod-affinity image: docker.io/ocpqe/hello-pod
ノードのラベルに、Pod のノードのアフィニティールールを満たさなくなるような結果になる変更がランタイム時に生じる場合も、Pod はノードで引き続き実行されます。
16.8.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
16.8.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
16.8.3. 各種の例
以下の例は、Pod のアフィニティーおよび非アフィニティーについて示しています。
16.8.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 と同じノードにスケジュールされます。
16.8.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>
16.8.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
と同じノードにスケジュールできません。
16.9. 詳細スケジューリングおよびノードセレクター
16.9.1. 概要
ノードセレクター はキーと値のペアのマップを指定します。ルールは、カスタムのノードのラベルおよび Pod で指定されるセレクターを使用して定義されます。
Pod がノードで実行する要件を満たすには、Pod はノードのラベルとして示されるキーと値のペアを持っている必要があります。
同じ Pod 設定でノードのアフィニティーと ノードセレクターを使用している場合は、以下の「重要な考慮事項」を参照してください。
16.9.2. ノードセレクターの設定
Pod 設定で nodeSelector
を使用することで、Pod を特定のラベルの付いたノードのみに配置することができます。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeSelector
値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeSelector: <key>: <value> ...
マスター設定ファイル /etc/origin/master/master-config.yaml を変更し、
nodeSelectorLabelBlacklist
を、Pod の配置を拒否する必要のあるノードホストに割り当てられるラベルと共にadmissionConfig
セクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...
変更を有効にするために OpenShift Container Platform を再起動します。
# master-restart controllers
同じ Pod 設定でノードセレクターとノードのアフィニティーを使用している場合は、以下に注意してください。
-
nodeSelector
とnodeAffinity
の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。 -
nodeAffinity
タイプに関連付けられた複数のnodeSelectorTerms
を指定する場合、nodeSelectorTerms
のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。 -
nodeSelectorTerms
に関連付けられた複数のmatchExpressions
を指定する場合、すべてのmatchExpressions
が満たされている場合にのみ Pod をノードにスケジュールすることができます。
16.10. 詳細スケジューリングおよびテイントと容認
16.10.1. 概要
テイントおよび容認により、ノード はノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。
16.10.2. テイントおよび容認 (Toleration)
テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。
テイントはノード仕様 (NodeSpec
) でノードに適用され、容認は Pod 仕様 (PodSpec
) で Pod に適用されます。ノードのテイントはノードに対し、テイントを容認しないすべての Pod を拒否するよう指示します。
テイントおよび容認は、key、value、および effect.で構成されています。演算子により、これらの 3 つのパラメーターのいずれかを空のままにすることができます。
パラメーター | 説明 | ||||||
---|---|---|---|---|---|---|---|
|
| ||||||
|
| ||||||
|
effect は以下のいずれかにすることができます。
| ||||||
|
|
容認はテイントと一致します。
operator
パラメーターがEqual
に設定されている場合:-
key
パラメーターは同じになります。 -
value
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
operator
パラメーターがExists
に設定されている場合:-
key
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
16.10.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 で容認されない唯一のテイントであるためです。
16.10.3. テイントの既存ノードへの追加
テイントおよび容認コンポーネントの表で説明されているパラメーターと共に oc adm taint
コマンドを使用してテイントをノードに追加します。
$ oc adm taint nodes <node-name> <key>=<value>:<effect>
以下に例を示します。
$ oc adm taint nodes node1 key1=value1:NoSchedule
この例では、テイントを、キー key1
、値 value1
、およびテイントの effect NoSchedule
を持つ node1
にテイントを配置します。
16.10.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
にスケジュールできます。
16.10.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 はエビクトされません。
16.10.4.1.1. 容認の秒数のデフォルト値の設定
このプラグインは、node.alpha.kubernetes.io/notReady:NoExecute
および node.alpha.kubernetes.io/notReady:NoExecute
テイントを 5 分間容認するための Pod のデフォルトの容認を設定します。
ユーザーが提供する Pod 設定にいずれかの容認がある場合、デフォルトは追加されません。
デフォルトの容認の秒数を有効にするには、以下を実行します。
マスター設定ファイル (/etc/origin/master/master-config.yaml) を変更して
DefaultTolerationSeconds
を admissionConfig セクションに追加します。admissionConfig: pluginConfig: DefaultTolerationSeconds: configuration: kind: DefaultAdmissionConfig apiVersion: v1 disable: false
変更を有効にするために、OpenShift を再起動します。
# master-restart api # master-restart 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
16.10.5. ノードの問題の発生時における Pod エビクションの禁止
OpenShift Container Platform は、node unreachable および node not ready 状態をテイントとして表示するよう設定できます。これにより、デフォルトの 5 分を使用するのではなく、unreachable (到達不能) または not ready (準備ができていない) 状態になるノードにバインドされたままになる期間を Pod 仕様ごとに指定することができます。
テイントベースのエビクション機能が有効にされた状態で、テイントはノードコントローラーによって自動的に追加され、Pod を Ready
ノードからエビクトするための通常のロジックは無効にされます。
-
ノードが not ready (準備ができていない) 状態になると、
node.alpha.kubernetes.io/notReady:NoExecute
テイントは追加され、Pod はノードでスケジュールできなくなります。既存 Pod は容認期間 (秒数) 中はそのまま残ります。 -
ノードが not reachable (到達不能) の状態になると、
node.alpha.kubernetes.io/unreachable:NoExecute
テイントは追加され、Pod はノードでスケジュールできません。既存の Pod は容認期間 (秒数) 中はそのまま残ります。
テイントベースのエビクションを有効にするには、以下を実行します。
マスター設定ファイル (/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 を再起動します。
# master-restart api # master-restart 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 エビクションを防ぐことができます。
16.10.6. Daemonset および容認
Daemonset Pod は、Default Toleration Seconds (デフォルトの容認期間の秒数) が無効にされている場合でも、tolerationSeconds
のない node.alpha.kubernetes.io/unreachable
および node.alpha.kubernetes.io/notReady
の NoExecute
容認の設定と共に作成され、DaemonSet Pod がエビクトされないようにします。
16.10.7. 各種の例
テイントおよび容認は、Pod をノードから切り離し、ノードで実行されるべきでない Pod をエビクトする柔軟性のある方法として使用できます。以下は典型的なシナリオのいくつかになります。
16.10.7.1. ノードをユーザー専用にする
ノードのセットを特定のユーザーセットが排他的に使用するように指定できます。
専用ノードを指定するには、以下を実行します。
テイントをそれらのノードに追加します。
以下に例を示します。
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタムの受付コントローラーを作成して、対応する容認を Pod に追加します。
容認のある Pod のみが専用ノードを使用することを許可されます。
16.10.7.2. ユーザーのノードへのバインド
特定ユーザーが専用ノードのみを使用できるようにノードを設定することができます。
ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。
テイントをそれらのノードに追加します。
以下に例を示します。
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタムの受付コントローラーを作成して、対応する容認を Pod に追加します。
受付コントローラーは、Pod が
key:value
ラベル (dedicated=groupName
) が付けられたノードのみにスケジュールされるようにノードのアフィニティーを追加します。-
テイントと同様のラベル (
key:value
ラベルなど) を専用ノードに追加します。
16.10.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
- 受付コントローラーを使用して特殊ハードウェアを使用する Pod に対応する容認を追加します。
たとえば受付コントローラーは容認を追加することで、Pod の一部の特徴を使用し、Pod が特殊ノードを使用できるかどうかを判別できます。
Pod が特殊ハードウェアのみを使用できるようにするには、追加のメカニズムが必要です。たとえば、特殊ハードウェアを持つノードにラベルを付け、ハードウェアを必要とする Pod でノードのアフィニティーを使用できます。