第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. スケジューラーポリシーの変更
デフォルトで、スケジューラーポリシーはマスター設定ファイルの 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 を再起動します。
# 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 は、Pod がメモリー不足 (memory pressure) 状況にあるノードでスケジュールできるかどうかを確認します。
{"name" : "CheckNodeMemoryPressure"}14.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"}14.2.5.2. 汎用的な述語
以下の汎用的な述語は、非クリティカル述語とクリティカル述語が渡されるかどうかを確認します。非クリティカル述語は、非クリティカル 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 は、値の種類を問わず、特定のノードに特定のラベルが定義されているかどうかを確認します。ラベルによるマッチングは、ノードに物理的な場所やステータスがラベルで定義されている場合などに役立ちます。
"predicates":[
{
"name":"<name>", 1
"weight" : "1" 2
"argument":{
"labelsPresence":{
"labels":[
"<label>" 3
presence: true/false
]
}
}
}
],以下に例を示します。
"name":"RackPreferred",
"weight" : "1"
"argument":{
"labelsPresence":{
"labels":[
"rack"
"labelsPresence:"{
"labels:"[
- "region"
presence: true14.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 は、その値が何であるかを問わず、特定のラベルが定義されているノードを優先します。
"predicates":[
{
"name":"<name>", 1
"weight" : "1" 2
"argument":{
"labelsPresence":{
"labels":[
"<label>" 3
presence: true/false
]
}
}
}
],以下に例を示します。
"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) → zone (affinity) → rack (anti-affinity) の 3 つのトポロジーレベルを定義します。
kind: "Policy"
version: "v1"
predicates:
...
- name: "RegionZoneAffinity"
argument:
serviceAffinity:
labels:
- "region"
- "zone"
priorities:
...
- name: "RackSpread"
weight: 1
argument:
serviceAntiAffinity:
label: "rack"以下の例は、city (affinity) → building (anti-affinity) → room (anti-affinity) の 3 つのトポロジーレベルを定義します。
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: 114.3. カスタムスケジューリング
14.3.1. 概要
デフォルトのスケジューラーと共に複数のカスタムスケジューラーを実行し、各 Pod に使用できるスケジューラーを設定できます。
特定のスケジューラーを使用して指定された Pod をスケジュールするには、Pod 仕様にスケジューラーの名前を指定します。
14.3.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> [...]
14.4. Pod 配置の制御
14.4.1. 概要
クラスター管理者は、特定のロールを持つアプリケーション開発者が Pod のスケジュール時に特定ノードをターゲットとすることを防ぐポリシーを設定できます。
Pod ノード制約の受付コントローラーは、Pod がラベルを使用して指定されたノードホストのみにデプロイされるようにし、特定のロールを持たないユーザーが nodeSelector フィールドを使用して Pod をスケジュールできないようにします。
14.4.2. ノード名の使用による Pod 配置の制約
Pod ノード制約の受付コントローラーを使用し、Pod にラベルを割り当て、これを Pod 設定の nodeName 設定に指定することで、Pod が指定されたノードホストにのみデプロイされるようにします。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeName値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeName: <value>
マスター設定ファイル (/etc/origin/master/master-config.yaml) を 2 箇所で変更します。
PodNodeConstraintsをadmissionConfigセクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig ...次に、同じ設定を
kubernetesMasterConfigセクションに追加します。... 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 を設定することは禁止されます。
たとえば、OpenShift Container Platform クラスターは、2 つの地域にまたがる 5 つのデータセンターで構成される場合があります。米国の "us-east"、"us-central"、および "us-west"、およびアジア太平洋地域 (APAC) の "apac-east" および "apac-west" です。それぞれの地理的地域の各ノードには、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) を 2 箇所で変更します。
nodeSelectorLabelBlacklistを、Pod の配置を拒否する必要のあるノードホストに割り当てられるラベルと共にadmissionConfigセクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...次に、同じ設定を
kubernetesMasterConfigセクションに追加し、Pod の直接の作成を制限します。... 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 配置の制御
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- 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>注記プロジェクトにノードセレクターが指定されていない場合、そのプロジェクトに関連付けられた Pod はデフォルトのノードセレクター (
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. 概要
ノードのアフィニティー は、Pod の配置場所を判別するためにスケジューラーによって使用されるルールのセットです。ルールはカスタムのノードのラベルと Pod で指定されるラベルセレクターを使って定義されます。ノードのアフィニティーにより、Pod ノード のグループに対してはアフィニティー (または非アフィニティー) を指定できます。ノード自体は配置に対して制御を行いません。
たとえば、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: - usPod 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 のアフィニティー および 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 (優先) ルールは、ルールが満たされる場合にスケジューラーがルールの実施を試行しますが、その実施が必ずしも保証される訳ではありません。
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
ノードのラベルに、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-podPod 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-podPod 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-podPod 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-podPod 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. 概要
ノードセレクター はキーと値のペアのマップを指定します。ルールは、カスタムのノードのラベルおよび Pod で指定されるセレクターを使用して定義されます。
Pod がノードで実行する要件を満たすには、Pod はノードのラベルとして示されるキーと値のペアを持っている必要があります。
同じ Pod 設定でノードのアフィニティーと ノードセレクターを使用している場合は、以下の「重要な考慮事項」を参照してください。
14.8.2. ノードセレクターの設定
Pod 設定で nodeSelector を使用することで、Pod を特定のラベルの付いたノードのみに配置することができます。
必要なラベル (詳細は、「ノードでのラベルの更新」を参照) およびノードセレクターが環境にセットアップされていることを確認します。
たとえば、Pod 設定が必要なラベルを示す
nodeSelector値を持つことを確認します。apiVersion: v1 kind: Pod spec: nodeSelector: <key>: <value> ...マスター設定ファイル (/etc/origin/master/master-config.yaml) を 2 箇所で変更します。
nodeSelectorLabelBlacklistを、Pod の配置を拒否する必要のあるノードホストに割り当てられるラベルと共にadmissionConfigセクションに追加します。... admissionConfig: pluginConfig: PodNodeConstraints: configuration: apiversion: v1 kind: PodNodeConstraintsConfig nodeSelectorLabelBlacklist: - kubernetes.io/hostname - <label> ...次に、同じ設定を
kubernetesMasterConfigセクションに追加し、Pod の直接の作成を制限します。... 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 つのパラメーターのいずれかを空のままにすることができます。
表14.1 テイントおよび容認コンポーネント
| パラメーター | 説明 | ||||||
|---|---|---|---|---|---|---|---|
|
|
| ||||||
|
|
| ||||||
|
|
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
この例では、テイントを、キー key1、値 value1、およびテイント effect NoSchedule を持つ node1 にテイントを配置します。
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. 容認の秒数のデフォルト値の設定
このプラグインは、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 を再起動します。
# 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. ノードの問題の発生時における 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 を再起動します。
# 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 Pod は、Default Toleration Seconds (デフォルトの容認期間の秒数) が無効にされている場合でも、tolerationSeconds のない node.alpha.kubernetes.io/unreachable および node.alpha.kubernetes.io/notReady の NoExecute 容認の設定と共に作成されます。
14.9.7. 各種の例
テイントおよび容認は、Pod をノードから切り離し、ノードで実行されるべきでない Pod をエビクトする柔軟性のある方法として使用できます。以下は典型的なシナリオのいくつかになります。
14.9.7.1. ノードをユーザー専用にする
ノードのセットを特定のユーザーセットが排他的に使用するように指定できます。
専用ノードを指定するには、以下を実行します。
テイントをそれらのノードに追加します。
以下に例を示します。
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタムの受付コントローラーを作成して、対応する容認を Pod に追加します。
容認のある Pod のみが専用ノードを使用することを許可されます。
14.9.7.2. ユーザーのノードへのバインド
特定ユーザーが専用ノードのみを使用できるようにノードを設定することができます。
ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。
テイントをそれらのノードに追加します。
以下に例を示します。
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタムの受付コントローラーを作成して、対応する容認を Pod に追加します。
受付コントローラーは、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
- 受付コントローラーを使用して特殊ハードウェアを使用する Pod に対応する容認を追加します。
たとえば受付コントローラーは容認を追加することで、Pod の一部の特徴を使用し、Pod が特殊ノードを使用できるかどうかを判別できます。
Pod が特殊ハードウェアのみを使用できるようにするには、追加のメカニズムが必要です。たとえば、特殊ハードウェアを持つノードにラベルを付け、ハードウェアを必要とする Pod でノードのアフィニティーを使用できます。

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.