Menu Close

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

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

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

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

テイントは Node 仕様 (NodeSpec) でノードに適用され、容認は Pod 仕様 (PodSpec) で Pod に適用されます。テイントをノードに適用する場合、スケジューラーは Pod がテイントを容認しない限り、Pod をそのノードに配置することができません。

ノード仕様のテイントの例

spec:
....
  template:
....
    spec:
      taints:
      - effect: NoExecute
        key: key1
        value: value1
....

Pod 仕様での容認の例

spec:
....
  template:
....
    spec:
      tolerations:
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoExecute"
        tolerationSeconds: 3600
....

テイントおよび容認は、key、value、および effect で構成されています。

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

パラメーター説明

key

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

value

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

effect

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

NoSchedule [1]

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

PreferNoSchedule

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

NoExecute

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

operator

Equal

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

Exists

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

  1. 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 は設定されません。

3.7.1.1. Pod のエビクションを遅延させる容認期間 (秒数) の使用方法

Pod 仕様または MachineSettolerationSeconds パラメーターを指定して、Pod がエビクションされる前にノードにバインドされる期間を指定できます。effect が NoExecute のテイントがノードに追加される場合、テイントを容認する Pod に tolerationSeconds パラメーターがある場合、Pod は期限切れになるまでエビクトされません。

出力例

spec:
....
  template:
....
    spec:
      tolerations:
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoExecute"
        tolerationSeconds: 3600

ここで、この Pod が実行中であるものの、一致する容認がない場合、Pod は 3,600 秒間バインドされたままとなり、その後にエビクトされます。テイントが期限前に削除される場合、Pod はエビクトされません。

3.7.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 はすぐにエビクトされます。
      • 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 には以下の容認があります。

    spec:
    ....
      template:
    ....
        spec:
          tolerations:
          - key: "key1"
            operator: "Equal"
            value: "value1"
            effect: "NoSchedule"
          - key: "key1"
            operator: "Equal"
            value: "value1"
            effect: "NoExecute"

この場合、3 つ目のテイントに一致する容認がないため、Pod はノードにスケジュールできません。Pod はこのテイントの追加時にノードですでに実行されている場合は実行が継続されます。 3 つ目のテイントは 3 つのテイントの中で Pod で容認されない唯一のテイントであるためです。

3.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 (ホストネットワークのみ)

デーモンセットには任意の容認を追加することも可能です。

3.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に変更し、ポッドの削除率が低下します。この状態の小さなクラスター(デフォルトでは50ノード以下)の場合、このゾーンのノードは汚染されず、排除が停止されます。

詳細については、KubernetesドキュメントのRate limits on evictionを参照してください。

OpenShift Container Platform は、node.kubernetes.io/not-ready および node.kubernetes.io/unreachable の容認を、Pod 設定がいずれかの容認を指定しない限り、自動的に tolerationSeconds=300 に追加します。

spec:
....
  template:
....
    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 は、これらのノードの状態が原因でエビクトされることはありません。

3.7.1.5. すべてのテイントの許容

ノードは、operator: "Exists" 容認を key および value パラメーターなしで追加することですべてのテイントを容認するように Pod を設定できます。この容認のある Pod はテイントを持つノードから削除されません。

すべてのテイントを容認するための Pod 仕様

spec:
....
  template:
....
    spec:
      tolerations:
      - operator: "Exists"