Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

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