2.6. ノードテイントを使用した Pod 配置の制御
テイントおよび容認 (Toleration) により、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。
2.6.1. テイントおよび容認 (Toleration) について
テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。
テイントはノード仕様 (NodeSpec
) でノードに適用され、容認は Pod 仕様 (PodSpec
) で Pod に適用されます。ノードのテイントはノードに対し、テイントを容認しないすべての Pod を拒否するよう指示します。
テイントおよび容認は、key、value、および effect.で構成されています。演算子により、これらの 3 つのパラメーターのいずれかを空のままにすることができます。
パラメーター | 説明 | ||||||
---|---|---|---|---|---|---|---|
|
| ||||||
|
| ||||||
| effect は以下のいずれかにすることができます。
| ||||||
|
|
容認はテイントと一致します。
operator
パラメーターがEqual
に設定されている場合:-
key
パラメーターは同じになります。 -
value
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
operator
パラメーターがExists
に設定されている場合:-
key
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
以下のテイントは kubernetes に組み込まれています。
-
node.kubernetes.io/not-ready
: ノードは準備状態にありません。これはノード条件Ready=False
に対応します。 -
node.kubernetes.io/unreachable
: ノードはノードコントローラーから到達不能です。これはノード条件Ready=Unknown
に対応します。 -
node.kubernetes.io/out-of-disk
: ノードには新しい Pod を追加するためのノード上の空きスペースが十分にありません。これはノード条件OutOfDisk=True
に対応します。 -
node.kubernetes.io/memory-pressure
: ノードにはメモリー不足の問題が発生しています。これはノード条件MemoryPressure=True
に対応します。 -
node.kubernetes.io/disk-pressure
: ノードにはディスク不足の問題が発生しています。これはノード条件DiskPressure=True
に対応します。 -
node.kubernetes.io/network-unavailable
: ノードのネットワークは使用できません。 -
node.kubernetes.io/unschedulable
: ノードはスケジュールが行えません。 -
node.cloudprovider.kubernetes.io/uninitialized
: ノードコントローラーが外部のクラウドプロバイダーを使って起動すると、このテイントはノード上に設定され、使用不可能とマークされます。cloud-controller-manager のコントローラーがこのノードを初期化した後に、kubelet がこのテイントを削除します。
2.6.1.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 はエビクトされません。
2.6.1.2. 複数のテイントの使用方法
複数のテイントを同じノードに、複数の容認を同じ 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 で容認されない唯一のテイントであるためです。
2.6.1.3. ノードの問題の発生時における Pod エビクションの禁止
OpenShift Container Platform は、node unreachable および node not ready 状態をテイントとして表示するよう設定できます。これにより、デフォルトの 5 分を使用するのではなく、unreachable (到達不能) または not ready (準備ができていない) 状態になるノードにバインドされたままになる期間を Pod 仕様ごとに指定することができます。
テイントベースのエビクション機能はデフォルトで有効にされています。テイントはノードコントローラーによって自動的に追加され、Pod を Ready
ノードからエビクトするための通常のロジックは無効にされます。
-
ノードが not ready (準備ができていない) 状態になると、
node.kubernetes.io/not-ready:NoExecute
テイントは追加され、Pod はノードでスケジュールできなくなります。既存 Pod は容認期間 (秒数) 中はそのまま残ります。 -
ノードが not reachable (到達不能) の状態になると、
node.kubernetes.io/unreachable:NoExecute
テイントは追加され、Pod はノードでスケジュールできません。既存 Pod は容認期間 (秒数) 中はそのまま残ります。
この機能により、tolerationSeconds
と組み合せることで、Pod は問題のいずれかまたは両方を持つノードにどの程度の期間バインドされるか指定することができます。
2.6.1.4. Pod のスケジューリングとノードの状態 (Taint Nodes By Condition) について
OpenShift Container Platform は、メモリー不足やディスク不足のような状態を報告したノードを自動的にテイントします。ノードが状態を報告すると、その状態が解消するまでテイントが追加されます。テイントに NoSchedule
の effect がある場合、ノードが一致する容認を持つまでそのノードに Pod をスケジュールすることはできません。この Taint Nodes By Condition 機能は、デフォルトで有効にされます。
スケジューラーは、Pod をスケジュールする前に、ノードでこれらのテイントの有無をチェックします。テイントがある場合、Pod は別のノードにスケジュールされます。スケジューラーは実際のノードの状態ではなくテイントをチェックするので、適切な Pod 容認を追加して、スケジューラーがこのようなノードの状態を無視するように設定します。
DeamonSet コントローラーは、以下の容認をすべてのデーモンに自動的に追加し、下位互換性を確保します。
- node.kubernetes.io/memory-pressure
- node.kubernetes.io/disk-pressure
- node.kubernetes.io/out-of-disk (Critical Pod の場合のみ)
- node.kubernetes.io/unschedulable (1.10 以降)
- node.kubernetes.io/network-unavailable (ホストネットワークのみ)
DeamonSet には任意の容認を追加することも可能です。
2.6.1.5. Pod の状態別エビクションについて (Taint-Based Eviction)
Taint-Based Eviction 機能はデフォルトで有効にされており、not-ready
や unreachable
などの特定の状態にあるノードから Pod をエビクトします。ノードがこうした状態のいずれかになると、OpenShift Container Platform はテイントをノードに自動的に追加して、Pod のエビクトおよび別のノードでの再スケジュールを開始します。
Taint Based Eviction には NoExecute
の effect があり、そのテイントを容認しない Pod はすぐにエビクトされ、容認する Pod はエビクトされません。
OpenShift Container Platform は、レートが制限された方法で Pod をエビクトし、マスターがノードからパーティション化される場合などのシナリオで発生する大規模な Pod エビクションを防ぎます。
この機能は、tolerationSeconds
と組み合せることで、ノード状態が設定されたノードに Pod がどの程度の期間バインドされるかを指定することができます。tolerationSections
の期間後もこの状態が続くと、テイントはノードに残り続け、Pod はレートが制限された方法でエビクトされます。tolerationSeconds
の期間前にこの状態が解消される場合、Pod は削除されません。
OpenShift Container Platform は、node.kubernetes.io/not-ready
および node.kubernetes.io/unreachable
の容認を、Pod の設定がいずれかの容認を指定しない限り、自動的に tolerationSeconds=300
に追加します。
spec tolerations: - key: node.kubernetes.io/not-ready operator: Exists effect: NoExecute tolerationSeconds: 300 - key: node.kubernetes.io/unreachable operator: Exists effect: NoExecute tolerationSeconds: 300
これらの容認は、ノード状態の問題のいずれかが検出された後、デフォルトの Pod 動作のバインドを 5 分間維持できるようにします。
これらの容認は必要に応じて設定できます。たとえば、アプリケーションに多数のローカル状態がある場合、ネットワークのパーティション化などに伴い、Pod をより長い時間ノードにバインドさせる必要があるかもしれません。 これにより、パーティションを回復させることができ、Pod のエビクションを回避できます。
DeamonSet Pod は、tolerationSeconds のない以下のテイントの NoExecute 容認で作成されます。
-
node.kubernetes.io/unreachable
-
node.kubernetes.io/not-ready
これにより、 DeamonSet Pod は、DefaultTolerationSeconds
受付コントローラーが無効化されていてもこれらのノードの状態が原因でエビクトされることはありません。
2.6.2. テイントおよび容認 (Toleration) の追加
テイントをノードに、容認 (Toleration) を Pod に追加することで、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。
手順
テイントおよび容認コンポーネントの表で説明されているパラメーターを使って、以下のコマンドを使用します。
$ oc adm taint nodes <node-name> <key>=<value>:<effect>
以下は例になります。
$ oc adm taint nodes node1 key1=value1:NoExecute
この例では、テイントを、キー
key1
、値value1
、およびテイント effectNoExecute
を持つnode1
にテイントを配置します。Pod 仕様を
tolerations
セクションを含めるように編集して、容認を Pod に追加します。Equal
演算子を含む Pod 設定ファイルのサンプルtolerations: - key: "key1" 1 operator: "Equal" 2 value: "value1" 3 effect: "NoExecute" 4 tolerationSeconds: 3600 5
例:
Exists
演算子を含む Pod 設定ファイルのサンプルtolerations: - key: "key1" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600
これらの容認のいずれも上記の
oc adm taint
コマンドで作成されるテイントに一致します。いずれかの容認のある Pod はnode1
にスケジュールできます。
2.6.2.1. テイントおよび容認 (Toleration) 使ってノードをユーザー専用にする
ノードのセットを特定のユーザーセットが排他的に使用するように指定できます。
手順
専用ノードを指定するには、以下を実行します。
テイントをそれらのノードに追加します。
例:
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタム受付コントローラーを作成して対応する容認を Pod に追加します。
容認のある Pod のみが専用ノードを使用することを許可されます。
2.6.2.2. テイントおよび容認 (Toleration) 使ってユーザーをノードにバインドする
特定ユーザーが専用ノードのみを使用できるようにノードを設定することができます。
手順
ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。
テイントをそれらのノードに追加します。
例:
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
カスタム受付コントローラーを作成して対応する容認を Pod に追加します。
受付コントローラーは、Pod が
key:value
ラベル (dedicated=groupName
) が付けられたノードのみにスケジュールされるようにノードのアフィニティーを追加します。-
テイントと同様のラベル (
key:value
ラベルなど) を専用ノードに追加します。
2.6.2.3. テイントおよび容認 (Toleration) を使って特殊ハードウェアを持つノードを制御する
ノードの小規模なサブセットが特殊ハードウェア(GPU など) を持つクラスターでは、テイントおよび容認 (Toleration) を使用して、特殊ハードウェアを必要としない 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 でノードのアフィニティーを使用できます。
2.6.3. テイントおよび容認 (Toleration) の削除
必要に応じてノードからテイントを、Pod から容認をそれぞれ削除できます。
手順
テイントおよび容認 (Toleration) を削除するには、以下を実行します。
ノードからテイントを削除するには、以下を実行します。
$ oc adm taint nodes <node-name> <key>-
以下は例になります。
$ oc adm taint nodes ip-10-0-132-248.ec2.internal key1- node/ip-10-0-132-248.ec2.internal untainted
Pod から容認を削除するには、容認を削除するための Pod 仕様を編集します。
tolerations: - key: "key2" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600