5.7. テイントおよび容認 (Toleration)
テイントおよび容認について理解し、これらを使用します。
5.7.1. テイントおよび容認 (Toleration) について
テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。
テイントは Node
仕様 (NodeSpec
) でノードに適用され、容認は Pod
仕様 (PodSpec
) で Pod に適用されます。テイントをノードに適用する場合、スケジューラーは Pod がテイントを容認しない限り、Pod をそのノードに配置することができません。
ノード仕様のテイントの例
spec: taints: - effect: NoExecute key: key1 value: value1 ....
Pod
仕様での容認の例
spec: tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600 ....
テイントおよび容認は、key、value、および effect で設定されています。
パラメーター | 説明 | ||||||
---|---|---|---|---|---|---|---|
|
| ||||||
|
| ||||||
| effect は以下のいずれかにすることができます。
| ||||||
|
|
NoSchedule
テイントをコントロールプレーンノード (別名マスターノード) に追加する場合、ノードには、デフォルトで追加されるnode-role.kubernetes.io/master=:NoSchedule
テイントが必要です。以下に例を示します。
apiVersion: v1 kind: Node metadata: annotations: machine.openshift.io/machine: openshift-machine-api/ci-ln-62s7gtb-f76d1-v8jxv-master-0 machineconfiguration.openshift.io/currentConfig: rendered-master-cdc1ab7da414629332cc4c3926e6e59c ... spec: taints: - effect: NoSchedule key: node-role.kubernetes.io/master ...
容認はテイントと一致します。
operator
パラメーターがEqual
に設定されている場合:-
key
パラメーターは同じになります。 -
value
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
operator
パラメーターがExists
に設定されている場合:-
key
パラメーターは同じになります。 -
effect
パラメーターは同じになります。
-
以下のテイントは OpenShift Container Platform に組み込まれています。
-
node.kubernetes.io/not-ready
: ノードは準備状態にありません。これはノード条件Ready=False
に対応します。 -
node.kubernetes.io/unreachable
: ノードはノードコントローラーから到達不能です。これはノード条件Ready=Unknown
に対応します。 -
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 がこのテイントを削除します。 node.kubernetes.io/pid-pressure
: ノードが pid 不足の状態です。これはノード条件PIDPressure=True
に対応します。重要OpenShift Container Platform では、デフォルトの pid.available
evictionHard
は設定されません。
5.7.1.1. Pod のエビクションを遅延させる容認期間 (秒数) の使用方法
Pod
仕様または MachineSet
に tolerationSeconds
パラメーターを指定して、Pod がエビクションされる前にノードにバインドされる期間を指定できます。effect が NoExecute
のテイントがノードに追加される場合、テイントを容認する Pod に tolerationSeconds
パラメーターがある場合、Pod は期限切れになるまでエビクトされません。
出力例
spec: tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600
ここで、この Pod が実行中であるものの、一致する容認がない場合、Pod は 3,600 秒間バインドされたままとなり、その後にエビクトされます。テイントが期限前に削除される場合、Pod はエビクトされません。
5.7.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 はすぐにエビクトされます。
-
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 には以下の容認があります。
spec: tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute"
この場合、3 つ目のテイントに一致する容認がないため、Pod はノードにスケジュールできません。Pod はこのテイントの追加時にノードですでに実行されている場合は実行が継続されます。3 つ目のテイントは 3 つのテイントの中で Pod で容認されない唯一のテイントであるためです。
5.7.1.3. Pod のスケジューリングとノードの状態 (Taint Nodes By Condition) について
Taint Nodes By Condition (状態別のノードへのテイント) 機能はデフォルトで有効にされており、これはメモリー不足やディスク不足などの状態を報告するノードを自動的にテイントします。ノードが状態を報告すると、その状態が解消するまでテイントが追加されます。テイントに NoSchedule
の effect がある場合、ノードが一致する容認を持つまでそのノードに Pod をスケジュールすることはできません。
スケジューラーは、Pod をスケジュールする前に、ノードでこれらのテイントの有無をチェックします。テイントがある場合、Pod は別のノードにスケジュールされます。スケジューラーは実際のノードの状態ではなくテイントをチェックするので、適切な Pod 容認を追加して、スケジューラーがこのようなノードの状態を無視するように設定します。
デーモンセットコントローラーは、以下の容認をすべてのデーモンに自動的に追加し、下位互換性を確保します。
- node.kubernetes.io/memory-pressure
- node.kubernetes.io/disk-pressure
- node.kubernetes.io/unschedulable (1.10 以降)
- node.kubernetes.io/network-unavailable (ホストネットワークのみ)
デーモンセットには任意の容認を追加することも可能です。
コントロールプレーンは、QoS クラスを持つ Pod に node.kubernetes.io/memory-pressure
容認も追加します。これは、Kubernetes が Guaranteed
または Burstable
QoS クラスで Pod を管理するためです。新しい BestEffort
Pod は、影響を受けるノードにスケジュールされません。
5.7.1.4. Pod の状態別エビクションについて (Taint-Based Eviction)
Taint-Based Eviction 機能はデフォルトで有効にされており、これは not-ready
および unreachable
などの特定の状態にあるノードから Pod をエビクトします。ノードがこうした状態のいずれかになると、OpenShift Container Platform はテイントをノードに自動的に追加して、Pod のエビクトおよび別のノードでの再スケジュールを開始します。
Taint Based Eviction には NoExecute
の effect があり、そのテイントを容認しない Pod はすぐにエビクトされ、これを容認する Pod はエビクトされません (Pod が tolerationSeconds
パラメーターを使用しない場合に限ります)。
tolerationSeconds
パラメーターを使用すると、ノード状態が設定されたノードに Pod がどの程度の期間バインドされるかを指定することができます。tolerationSeconds
の期間後もこの状態が続くと、テイントはノードに残り続け、一致する容認を持つ Pod はエビクトされます。tolerationSeconds
の期間前にこの状態が解消される場合、一致する容認を持つ Pod は削除されません。
値なしで tolerationSeconds
パラメーターを使用する場合、Pod は not ready(準備未完了) および unreachable(到達不能) のノードの状態が原因となりエビクトされることはありません。
OpenShift Container Platform は、レートが制限された方法で Pod をエビクトし、マスターがノードからパーティション化される場合などのシナリオで発生する大規模な Pod エビクションを防ぎます。
デフォルトでは、特定のゾーン内のノードの 55% 以上が 異常である場合、ノードライフサイクルコントローラーはそのゾーンの状態を PartialDisruption
に変更し、Pod の削除率が低下します。この状態の小さなクラスター (デフォルトでは 50 ノード以下) の場合、このゾーンのノードは汚染されず、排除が停止されます。
詳細については、Kubernetes ドキュメントの Rate limits on eviction を参照してください。
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 1
- key: node.kubernetes.io/unreachable
operator: Exists
effect: NoExecute
tolerationSeconds: 300
- 1
- これらの容認は、ノード状態の問題のいずれかが検出された後、デフォルトの Pod 動作のバインドを 5 分間維持できるようにします。
これらの容認は必要に応じて設定できます。たとえば、アプリケーションに多数のローカル状態がある場合、ネットワークのパーティション化などに伴い、Pod をより長い時間ノードにバインドさせる必要があるかもしれません。 これにより、パーティションを回復させることができ、Pod のエビクションを回避できます。
デーモンセットによって起動する Pod は、tolerationSeconds
が指定されない以下のテイントの NoExecute
容認を使用して作成されます。
-
node.kubernetes.io/unreachable
-
node.kubernetes.io/not-ready
その結果、デーモンセット Pod は、これらのノードの状態が原因でエビクトされることはありません。
5.7.1.5. すべてのテイントの許容
ノードは、operator: "Exists"
容認を key
および value
パラメーターなしで追加することですべてのテイントを容認するように Pod を設定できます。この容認のある Pod はテイントを持つノードから削除されません。
すべてのテイントを容認するための Pod
仕様
spec: tolerations: - operator: "Exists"
5.7.2. テイントおよび容認 (Toleration) の追加
容認を Pod に、テイントをノードに追加することで、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。既存の Pod およびノードの場合、最初に容認を Pod に追加してからテイントをノードに追加して、容認を追加する前に Pod がノードから削除されないようにする必要があります。
手順
Pod
仕様をtolerations
スタンザを含めるように編集して、容認を Pod に追加します。Equal 演算子を含む Pod 設定ファイルのサンプル
spec: tolerations: - key: "key1" 1 value: "value1" operator: "Equal" effect: "NoExecute" tolerationSeconds: 3600 2
以下に例を示します。
Exists 演算子を含む Pod 設定ファイルのサンプル
spec: tolerations: - key: "key1" operator: "Exists" 1 effect: "NoExecute" tolerationSeconds: 3600
- 1
Exists
Operator はvalue
を取りません。
この例では、テイントを、キー
key1
、値value1
、およびテイント effectNoExecute
を持つnode1
にテイントを配置します。テイントおよび容認コンポーネント の表で説明されているパラメーターと共に以下のコマンドを使用してテイントをノードに追加します。
$ oc adm taint nodes <node_name> <key>=<value>:<effect>
以下に例を示します。
$ oc adm taint nodes node1 key1=value1:NoExecute
このコマンドは、キー
key1
、値value1
、および effectNoExecute
を持つテイントをnode1
に配置します。注記NoSchedule
テイントをコントロールプレーンノード (別名マスターノード) に追加する場合、ノードには、デフォルトで追加されるnode-role.kubernetes.io/master=:NoSchedule
テイントが必要です。以下に例を示します。
apiVersion: v1 kind: Node metadata: annotations: machine.openshift.io/machine: openshift-machine-api/ci-ln-62s7gtb-f76d1-v8jxv-master-0 machineconfiguration.openshift.io/currentConfig: rendered-master-cdc1ab7da414629332cc4c3926e6e59c ... spec: taints: - effect: NoSchedule key: node-role.kubernetes.io/master ...
Pod の容認はノードのテイントに一致します。いずれかの容認のある Pod は
node1
にスケジュールできます。
5.7.3. マシンセットを使用したテイントおよび容認の追加
マシンセットを使用してテイントをノードに追加できます。MachineSet
オブジェクトに関連付けられるすべてのノードがテイントで更新されます。容認は、ノードに直接追加されたテイントと同様に、マシンセットによって追加されるテイントに応答します。
手順
Pod
仕様をtolerations
スタンザを含めるように編集して、容認を Pod に追加します。Equal
演算子を含む Pod 設定ファイルのサンプルspec: tolerations: - key: "key1" 1 value: "value1" operator: "Equal" effect: "NoExecute" tolerationSeconds: 3600 2
以下に例を示します。
Exists
演算子を含む Pod 設定ファイルのサンプルspec: tolerations: - key: "key1" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600
テイントを
MachineSet
オブジェクトに追加します。テイントを付けるノードの
MachineSet
YAML を編集するか、または新規MachineSet
オブジェクトを作成できます。$ oc edit machineset <machineset>
テイントを
spec.template.spec
セクションに追加します。マシンセット仕様のテイントの例
spec: .... template: .... spec: taints: - effect: NoExecute key: key1 value: value1 ....
この例では、キー
key1
、値value1
、およびテイント effectNoExecute
を持つテイントをノードに配置します。マシンセットを 0 にスケールダウンします。
$ oc scale --replicas=0 machineset <machineset> -n openshift-machine-api
ヒントまたは、以下の YAML を適用してマシンセットをスケーリングすることもできます。
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: name: <machineset> namespace: openshift-machine-api spec: replicas: 0
マシンが削除されるまで待機します。
マシンセットを随時スケールアップします。
$ oc scale --replicas=2 machineset <machineset> -n openshift-machine-api
または、以下を実行します。
$ oc edit machineset <machineset> -n openshift-machine-api
マシンが起動するまで待ちます。テイントは
MachineSet
オブジェクトに関連付けられたノードに追加されます。
5.7.4. テイントおよび容認 (Toleration) 使ってユーザーをノードにバインドする
ノードのセットを特定のユーザーセットによる排他的な使用のために割り当てる必要がある場合、容認をそれらの Pod に追加します。次に、対応するテイントをそれらのノードに追加します。容認が設定された Pod は、テイントが付けられたノードまたはクラスター内の他のノードを使用できます。
Pod がテイントが付けられたノードのみにスケジュールされるようにするには、ラベルを同じノードセットに追加し、ノードのアフィニティーを Pod に追加し、Pod がそのラベルの付いたノードのみにスケジュールできるようにします。
手順
ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。
対応するテイントをそれらのノードに追加します。
以下に例を示します。
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
ヒントまたは、以下の YAML を適用してテイントを追加できます。
kind: Node apiVersion: v1 metadata: name: <node_name> labels: ... spec: taints: - key: dedicated value: groupName effect: NoSchedule
- カスタム受付コントローラーを作成して容認を Pod に追加します。
5.7.5. テイントおよび容認 (Toleration) を使って特殊ハードウェアを持つノードを制御する
ノードの小規模なサブセットが特殊ハードウェアを持つクラスターでは、テイントおよび容認 (Toleration) を使用して、特殊ハードウェアを必要としない Pod をそれらのノードから切り離し、特殊ハードウェアを必要とする Pod をそのままにすることができます。また、特殊ハードウェアを必要とする Pod に対して特定のノードを使用することを要求することもできます。
これは、特殊ハードウェアを必要とする Pod に容認を追加し、特殊ハードウェアを持つノードにテイントを付けることで実行できます。
手順
特殊ハードウェアを持つノードが特定の Pod 用に予約されるようにするには、以下を実行します。
容認を特別なハードウェアを必要とする Pod に追加します。
以下に例を示します。
spec: tolerations: - key: "disktype" value: "ssd" operator: "Equal" effect: "NoSchedule" tolerationSeconds: 3600
以下のコマンドのいずれかを使用して、特殊ハードウェアを持つノードにテイントを設定します。
$ oc adm taint nodes <node-name> disktype=ssd:NoSchedule
または、以下を実行します。
$ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
ヒントまたは、以下の YAML を適用してテイントを追加できます。
kind: Node apiVersion: v1 metadata: name: <node_name> labels: ... spec: taints: - key: disktype value: ssd effect: PreferNoSchedule
5.7.6. テイントおよび容認 (Toleration) の削除
必要に応じてノードからテイントを、Pod から容認をそれぞれ削除できます。最初に容認を Pod に追加してからテイントをノードに追加して、容認を追加する前に 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
仕様を編集します。spec: tolerations: - key: "key2" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600