2.6. ノードテイントを使用した Pod 配置の制御

テイントおよび容認 (Toleration) により、ノードはノード上でスケジュールする必要のある (またはスケジュールすべきでない) Pod を制御できます。

2.6.1. テイントおよび容認 (Toleration) について

テイント により、ノードは Pod に一致する 容認 がない場合に Pod のスケジュールを拒否することができます。

テイントはノード仕様 (NodeSpec) でノードに適用され、容認は Pod 仕様 (PodSpec) で Pod に適用されます。ノードのテイントはノードに対し、テイントを容認しないすべての Pod を拒否するよう指示します。

テイントおよび容認は、key、value、および effect.で構成されています。演算子により、これらの 3 つのパラメーターのいずれかを空のままにすることができます。

表2.1 テイントおよび容認コンポーネント

パラメーター説明

key

key には、253 文字までの文字列を使用できます。キーは文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

value

value には、63 文字までの文字列を使用できます。値は文字または数字で開始する必要があり、文字、数字、ハイフン、ドットおよびアンダースコアを含めることができます。

effect

effect は以下のいずれかにすることができます。

NoSchedule

  • テイントに一致しない新規 Pod はノードにスケジュールされません。
  • ノードの既存 Pod はそのままになります。

PreferNoSchedule

  • テイントに一致しない新規 Pod はノードにスケジュールされる可能性がありますが、スケジューラーはスケジュールしないようにします。
  • ノードの既存 Pod はそのままになります。

NoExecute

  • テイントに一致しない新規 Pod はノードにスケジュールできません。
  • 一致する容認を持たないノードの既存 Pod は削除されます。

operator

Equal

key/value/effect パラメーターは一致する必要があります。これはデフォルトになります。

Exists

key/effect パラメーターは一致する必要があります。いずれかに一致する value パラメーターを空のままにする必要があります。

容認はテイントと一致します。

  • 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 は複数のテイントと容認を以下のように処理します。

  1. Pod に一致する容認のあるテイントを処理します。
  2. 残りの一致しないテイントは 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 は指定された期間バインドされます。

例:

  • ノードには以下のテイントがあります。

    $ 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-readyunreachable などの特定の状態にあるノードから 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 を制御できます。

手順

  1. テイントおよび容認コンポーネントの表で説明されているパラメーターを使って、以下のコマンドを使用します。

    $ oc adm taint nodes <node-name> <key>=<value>:<effect>

    以下は例になります。

    $ oc adm taint nodes node1 key1=value1:NoExecute

    この例では、テイントを、キーkey1、値 value1、およびテイント effect NoExecute を持つ node1 にテイントを配置します。

  2. Pod 仕様を tolerations セクションを含めるように編集して、容認を Pod に追加します。

    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 をどの程度の期間ノードにバインドさせるかを指定します。

    例:

    Exists 演算子を含む Pod 設定ファイルのサンプル

    tolerations:
    - key: "key1"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 3600

    これらの容認のいずれも上記の oc adm taint コマンドで作成されるテイントに一致します。いずれかの容認のある Pod は node1 にスケジュールできます。

2.6.2.1. テイントおよび容認 (Toleration) 使ってノードをユーザー専用にする

ノードのセットを特定のユーザーセットが排他的に使用するように指定できます。

手順

専用ノードを指定するには、以下を実行します。

  1. テイントをそれらのノードに追加します。

    例:

    $ oc adm taint nodes node1 dedicated=groupName:NoSchedule
  2. カスタム受付コントローラーを作成して対応する容認を Pod に追加します。

    容認のある Pod のみが専用ノードを使用することを許可されます。

2.6.2.2. テイントおよび容認 (Toleration) 使ってユーザーをノードにバインドする

特定ユーザーが専用ノードのみを使用できるようにノードを設定することができます。

手順

ノードをユーザーの使用可能な唯一のノードとして設定するには、以下を実行します。

  1. テイントをそれらのノードに追加します。

    例:

    $ oc adm taint nodes node1 dedicated=groupName:NoSchedule
  2. カスタム受付コントローラーを作成して対応する容認を Pod に追加します。

    受付コントローラーは、Pod が key:value ラベル (dedicated=groupName) が付けられたノードのみにスケジュールされるようにノードのアフィニティーを追加します。

  3. テイントと同様のラベル (key:value ラベルなど) を専用ノードに追加します。

2.6.2.3. テイントおよび容認 (Toleration) を使って特殊ハードウェアを持つノードを制御する

ノードの小規模なサブセットが特殊ハードウェア(GPU など) を持つクラスターでは、テイントおよび容認 (Toleration) を使用して、特殊ハードウェアを必要としない Pod をそれらのノードから切り離し、特殊ハードウェアを必要とする Pod をそのままにすることができます。また、特殊ハードウェアを必要とする Pod に対して特定のノードを使用することを要求することもできます。

手順

Pod が特殊ハードウェアからブロックされるようにするには、以下を実行します。

  1. 以下のコマンドのいずれかを使用して、特殊ハードウェアを持つノードにテイントを設定します。

    $ oc adm taint nodes <node-name> disktype=ssd:NoSchedule
    $ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
  2. 受付コントローラーを使用して、特別なハードウェアを使用する Pod に対応する容認を追加します。

たとえば受付コントローラーは容認を追加することで、Pod の一部の特徴を使用し、Pod が特殊ノードを使用できるかどうかを判別できます。

Pod が特殊ハードウェアのみを使用できるようにするには、追加のメカニズムが必要です。たとえば、特殊ハードウェアを持つノードにラベルを付け、ハードウェアを必要とする Pod でノードのアフィニティーを使用できます。

2.6.3. テイントおよび容認 (Toleration) の削除

必要に応じてノードからテイントを、Pod から容認をそれぞれ削除できます。

手順

テイントおよび容認 (Toleration) を削除するには、以下を実行します。

  1. ノードからテイントを削除するには、以下を実行します。

    $ 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
  2. Pod から容認を削除するには、容認を削除するための Pod 仕様を編集します。

    tolerations:
    - key: "key2"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 3600