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