LoginSignup
21
20

More than 3 years have passed since last update.

KubernetesのTaint / Tolerationの使い方

Posted at

Taint / Tolerationとは

Taintとは、PodをNodeへスケジューリングさせないための機能である。
Node Affinityとは逆の機能になる。

TaintsをNodeに設定し、PodにはTolerationsを設定することができる。
これらにはkey, valueなどを設定し、TaintsとTolerationsの条件がマッチした際に、PodはNodeにスケジューリングされるようになる。
それぞれ1つ、または複数のTaints、Tolerationsを設定することができる。

目次

Taints

Taintsは、以下の3つを使って条件をセットする。

  • key
  • value
  • effect

例えば、key: appvalue: batcheffect: NoScheduleというように、Node、Podにそれぞれ設定する。key, valueはそのままセットした値が条件比較で使われる。effectについては次項で説明する。

effectとは

effectとは、条件をどのように受け入れるのかの制約である。
effectは以下の3種類がある。

  • NoSchedule
    • TaintとTolerationがマッチした場合にのみに、PodがNodeにスケジューリングされる。
  • PreferNoSchedule
    • Nodeは条件が一致しないPodを基本的には拒否するが、該当のPodがどのNodeにもスケジューリングされず行き場所がなくなっている場合、PreferNoScheduleが設定されたNodeは、条件にマッチしなくてもそのPodを受け入れてスケジューリングする。
  • NoExecute
    • TaintとTolerationがマッチした場合にのみに、PodがNodeにスケジューリングされる。
    • このTaintがNodeにセットされたときに、条件に合わないPodが既にスケジューリングされていた場合、そのPodはただちにNodeから追い出される。つまり、起動中のPodにも影響が出る。

説明するのが中々難しいので、実際に検証してみる。

ハンズオン

以下のminikubeというnodeにTaintを設定し、Tolerationを設定したPodをスケジューリングしてみる。

$ sudo kubectl get nodes
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   3d    v1.14.3

NoScheduleの挙動を検証

Taintを設定前の状態

nodeをdescribeしてみると、Taintsが<none>になっている。

$ sudo kubectl describe node minikube | grep Taints
Taints:             <none>

Taintを設定

key: appvalue: batcheffect: NoScheduleというTaintを設定する。

$ sudo kubectl taint nodes minikube app=batch:NoSchedule
node/minikube tainted

Taintを設定後の状態

nodeをdescribeすると、Taintsが設定されていることが確認できる。

$ sudo kubectl describe nodes minikube | grep Taints
Taints:             app=batch:NoSchedule

Tolerationの設定

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
   - name: sample-container
     image: nginx
  tolerations:
    # TaintのKeyを指定
    - key: "app"
      # Equal or Exists。Default: Equal。
      operator: "Equal"
      # TaintのValueを指定。operatorがExistsの場合、valueは省略可能。
      # operatorにExistsを設定した場合、keyとeffectのみが一致したNodeを探すことになる。
      value: "batch"
      # Effectを設定。省略した場合、全てのEffectにマッチする。
      effect: "NoSchedule"
      # effectにNoExecuteを設定した場合、PodがNodeから追い出されるまでの時間を設定する。
      # 0や負の数を設定した場合は即座に追い出される。
      #tolerationSeconds: 0

条件が一致した場合

Podがスケジューリングされていることを確認する。

$ sudo kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          4s
$ sudo kubectl describe pod sample-pod
# **snip**
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  25s   default-scheduler  Successfully assigned default/sample-pod to minikube
  Normal  Pulling    25s   kubelet, minikube  Pulling image "nginx"
  Normal  Pulled     22s   kubelet, minikube  Successfully pulled image "nginx"
  Normal  Created    22s   kubelet, minikube  Created container sample-container
  Normal  Started    22s   kubelet, minikube  Started container sample-container

条件が一致しない場合

Nodeにapp=batch:NoScheduleというTaintを設定、
Podにapp=api:NoScheduleというTolerationを設定した場合、Podはスケジューリング先のNodeが存在しないため、以下のようになる。

$ sudo kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   0/1     Pending   0          10s
$ sudo kubectl describe pod sample-pod
# **snip**
Events:
  Type     Reason            Age              From               Message
  ----     ------            ----             ----               -------
  Warning  FailedScheduling  5s (x2 over 5s)  default-scheduler  0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.

PreferNoScheduleの挙動を検証

NodeにTaintの設定

app=batch:PreferNoScheduleというTaintをminikube Nodeに設定する。

$ sudo kubectl taint nodes minikube app=batch:PreferNoSchedule
node/minikube tainted

確認

$ sudo kubectl describe node minikube | grep Taint
Taints:             app=batch:PreferNoSchedule

PodにTolerationの設定

以下のTolerationをPodに設定する。

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
   - name: sample-container
     image: nginx
  tolerations:
    # TaintのKeyを指定
    - key: "sample"
      # Equal or Exists。Default: Equal。
      operator: "Equal"
      # TaintのValueを指定。operatorがExistsの場合、valueは省略可能。
      value: "ThisIsASample"
      # Effectを設定。省略した場合、全てのEffectにマッチする。
      effect: "NoSchedule"

apply

$ sudo kubectl apply -f pod.yml
pod/sample-pod configured

スケジューリング状態確認

Taintはapp=batch:PreferNoSchedule、PodのTolerationsはsample=ThisIsASample:NoScheduleで一致していないが、このPodは他に行き場所がないため、minikubeのNodeにスケジューリングされた。

$ sudo kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          14s
$ sudo kubectl describe pod sample-pod
# **snip**
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  25s   default-scheduler  Successfully assigned default/sample-pod to minikube
  Normal  Pulling    24s   kubelet, minikube  Pulling image "nginx"
  Normal  Pulled     21s   kubelet, minikube  Successfully pulled image "nginx"
  Normal  Created    21s   kubelet, minikube  Created container sample-container
  Normal  Started    21s   kubelet, minikube  Started container sample-container

NoExecuteの挙動を検証

先述のPreferNoScheduleの挙動を検証の環境をそのまま利用する。

作業前のNodeを確認

先程セットしたTaintがNodeにセットされていることを確認。

$ sudo kubectl describe node minikube | grep Taints
Taints:             app=batch:PreferNoSchedule

作業前のPodを確認

先程作成したPodが起動していることを確認。

$ sudo kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          52s

Taintを削除

先程セットしたTaintを削除する。

$ sudo kubectl taint nodes minikube app-
node/minikube untainted

Taintを設定

minikubeのNodeにapp=batch:NoExecuteというTaintを設定する。

$ sudo kubectl taint nodes minikube app=batch:NoExecute
node/minikube tainted

作業後のNodeを確認

$ sudo kubectl describe node minikube | grep Taints
Taints:             app=batch:NoExecute

作業後のPodを確認

先述のPreferNoScheduleの挙動を検証で作成したPodは、条件に合わないため、新たなNoExecuteのTaintをセットしたら、ただちに破棄された。

$ sudo kubectl get pod
NAME         READY   STATUS        RESTARTS   AGE
sample-pod   0/1     Terminating   0          83s

ちなみに、TaintをNoScheduleもしくはPreferNoScheduleにセットし直した場合は、既存のPodは破棄されなかった。

$ sudo kubectl taint nodes minikube app=batch:NoSchedule
$ sudo kubectl taint nodes minikube app=batch:PreferNoSchedule

関連記事

参考

21
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
20