【ITニュース解説】When Nodes Start Rejecting Pods: Taints and Tolerations
2026年09月22日に「Dev.to」が公開したITニュース「When Nodes Start Rejecting Pods: Taints and Tolerations」について初心者にもわかりやすく解説しています。
ITニュース概要
KubernetesのTaintはノードがPodの配置を拒否する設定だ。PodはTolerationを持つことで、Taintされたノードへの配置を許容し、スケジューリングされる。これにより、コントロールプレーンノードなど、特定のノードに特定のPodだけを配置できる。新規拒否のNoSchedule、避けるPreferNoSchedule、稼働中も排除するNoExecuteの3つの効果がある。
ITニュース解説
TaintsとTolerationsは、Kubernetesクラスター内でPodがどのノードに配置されるかを制御するための重要な仕組みである。これは、Podが「どのノードに行きたいか」を指定するNode SelectorやNode Affinityとは異なり、ノードが「どのPodを拒否するか」を決定する逆方向からの制御を提供する。
このメカニズムが解決する主な問題は、特定のノードに通常のアプリケーションPodがスケジュールされるのを防ぎたい場合である。例えば、Kubernetesクラスターの管理を行うコントロールプレーンノード(マスターノード)には、そのノード自身の重要なプロセスが動作しているため、一般のPodが勝手に配置されてリソースを消費したり、安定性を損なったりするのを避けたい。また、GPUなどの特殊なハードウェアを持つノードには、それらのリソースを必要とする特定のPodだけを配置し、他のPodは排除したい場合がある。TaintsとTolerationsは、このような「ノードがPodを積極的に排除する」ニーズに応えるために導入された。ノードにTaintが設定されると、原則としてそのノードはPodを拒否する。Podは、そのTaintを「許容する」Tolerationを持つことで、初めてそのノードにスケジュールされる資格を得る。
Taintは「キー(key)」「バリュー(value)」「エフェクト(effect)」の3つの要素で構成され、「key=value:effect」という形式でノードに設定される。一方、TolerationはPodの定義内に記述され、どのTaintを許容するかを定義する。PodのTolerationがノードのTaintと一致すると、そのTaintはPodのスケジュールを妨げなくなる。
エフェクトには以下の3種類がある。
- NoSchedule: このエフェクトを持つTaintがノードに設定されている場合、対応するTolerationを持たないPodは一切そのノードにスケジュールされない。これは最も強い拒否の意思表示であり、新規にスケジュールされるPodにのみ影響を与える。既にノード上で実行中のPodには影響しない。
- PreferNoSchedule: このエフェクトは、TaintされたノードへのPodのスケジュールを「推奨しない」という意味合いを持つ。Tolerationを持たないPodは可能な限りそのノードを避けてスケジュールされるが、もし他の適切なノードが全く存在しない場合には、Taintされたノードにもスケジュールされる可能性がある。これも新規Podのみに影響し、既存のPodには影響しない。
- NoExecute: このエフェクトは他の2つとは大きく異なる。
NoScheduleやPreferNoScheduleが新規のPodのスケジュールを制御するのに対し、NoExecuteは既にそのノード上で実行中のPodにも影響を及ぼす。NoExecuteTaintがノードに設定されると、対応するTolerationを持たないPodは即座にそのノードから強制的に排除(エビクト)される。もちろん、新規のPodもスケジュールされない。このエフェクトは、ノードの状態が変化した際に、そのノードにいるべきではないPodを迅速に排除する目的で利用されることが多い。
TolerationをPodに設定する際には、key、value、effectに加えてoperatorを指定できる。operatorがEqualの場合、TaintのvalueとTolerationのvalueが完全に一致する必要がある。operatorがExistsの場合、Taintのkeyが存在すればvalueに関わらずTolerationが適用される。また、NoExecuteエフェクトに対しては、tolerationSecondsというオプションを指定できる。これは、NoExecuteTaintが設定されてからPodが実際にエビクトされるまでの猶予期間(秒数)を定義するもので、突然のPod停止を避けるために利用される。
TaintsとTolerationsの具体的な利用場面は多岐にわたる。Kubernetesクラスターでは、コントロールプレーンノードにデフォルトでTaintが設定されており、一般のPodが誤ってスケジュールされないようになっている。また、GPUリソースを持つノードに専用のTaintを設定し、そのGPUを必要とするPodだけがTolerationを持つことで、リソースを効率的に利用できる。さらに、Kubernetes自体も内部的にTaintsとTolerationsを利用している。例えば、ノードがネットワークから切断されるなどして異常な状態になった場合、ノードコントローラーが自動的にそのノードにNoExecuteTaintを設定し、応答しないノード上のPodを強制的に別の正常なノードへ移動させることがある。
Kubernetesスケジューラは、Podをノードに配置する際にTaintsとTolerationsを評価する。NoScheduleTaintは、スケジューリングの「フィルタリング」段階で処理される。PodがTolerationを持たない場合、TaintされたノードはPodの配置先候補から除外される。これは、Node AffinityのrequiredDuringSchedulingIgnoredDuringExecutionと同様に、Podがノードに配置されるためのハードな要件として機能する。一方、PreferNoScheduleTaintは「スコアリング」段階で評価される。Tolerationを持たないPodに対しては、Taintされたノードのスコアが下げられ、可能な限り他のノードが選択されるように誘導されるが、必須ではない。NoExecuteTaintは、新規Podのスケジュールをブロックするだけでなく、既に実行中のPodに対しても効果を発揮する唯一のエフェクトである。この挙動は、一度Podがスケジュールされると基本的には移動しないというKubernetesの原則の例外となる。
Node AffinityとTaints/Tolerationsは、Podとノード間の関連付けを行う点で似ているが、その方向性が決定的に異なる。Node AffinityはPodが主体となって、特定のラベルを持つノードを「積極的に選びたい」という要望を表現する。例えば、「このPodはGPUを持つノードに配置されたい」という指定である。これに対し、Taints/Tolerationsはノードが主体となって、特定のPodを「排除したい」という要望を表現し、Tolerationを持つPodだけを「許可する」という形になる。例えば、「このGPUノードにはGPUを使わないPodは来るな」という指定である。
この違いが示すように、TolerationはPodが特定のノードを「好む」ことを意味するものではない。Tolerationがあるからといって、そのPodが必ずTaintされたノードにスケジュールされるわけではなく、単にそのTaintによってスケジュールがブロックされない、という状態になるだけである。したがって、特定の専用ノードにPodを確実に配置したい場合は、TaintsとTolerationsだけでなく、Node Affinityも併用することが一般的である。Taintが他のPodの侵入を防ぎ、Node Affinityが目的のPodをそのノードに引き寄せるという役割分担となる。
よくある間違いとして、Tolerationがノードの「優先度」を意味すると誤解されるケースがある。しかし前述の通り、Tolerationは単にスケジュール上の「制限を解除する」だけであり、優先度を上げる機能は持たない。そのため、適切なNode Affinityが設定されていないと、Tolerationを持つPodでも、Taintされていない他のノードにスケジュールされる可能性がある。また、NoExecuteTaintを既存の運用中のノードに適用する際は、対応するTolerationを持たない実行中のPodが予告なくエビクトされるリスクがあるため、慎重な事前確認が不可欠である。DaemonSetによって管理されるPodは、一部の組み込みTaintを自動的に許容するように設計されており、これによって特殊なノードでも安定して動作できる。
Taintの具体的な設定はkubectl taint nodes <node-name> <key>=<value>:<effect>コマンドで行い、解除は<key>=<value>:<effect>-のようにハイフンを付加して行う。PodにTolerationを設定する場合は、PodのYAML定義のspec.tolerationsセクションにkey, operator, value, effectを記述する。これらの基本的な操作を理解することで、KubernetesクラスターにおけるPodの配置をより詳細に制御できるようになる。