広告

kubernetes – TaintsとTolerations

infrastructure as code

k8sスケジューリングの方法

k8sでは、Podのスケーリングは以下の2つの方法で行います。

  • Affinity:Podのスケジューリング時に特定のNodeを選択する方法
    • 特徴:Podに選択権を持つ
  • TaintsとTolerations:Nodeに属性(Taints)を付け、Podにも属性(Tolerations)を付け、属性の比較でスケジューリングする方法
    • 特徴:Nodeにも選択権を持てる

TaintsとTolerations

TaintsとTolerationsについて、公式ドキュメントでは、以下のように説明しています。

Taints and tolerations work together to ensure that pods are not scheduled onto inappropriate nodes. One or more taints are applied to a node; this marks that the node should not accept any pods that do not tolerate the taints.

簡単にイメージすると:

  • Nodeにロック(Taints)を付ける
  • Podに鍵(Tolerations)を渡す
  • 鍵が正しいPodのみがNodeにスケジューリングできる

そのため、Taintsを持っているNodeは、正しいTolerationsを持っているPodしかスケジューリングされないです。

また、Node Affinityはスケジューリング時にのみ作用するに対して、TaintsとTolerationsは随時適用されます。
即ち、スケジューリング済みのPodでも、随時TaintsとTolerationsをチェックし、Podのスケジューリングを動的に実施されます。

TaintsとTolerationsの情報構成

TaintsとTolerationsは以下の情報で構成されています。

<Key>=<Value>:<Effect>
  • =:TaintsはKey-Value形式のデータ
  • :TaintsとTolerationsがマッチしない時の挙動

<Effect>は以下の3種類があります

  • PreferNoSchedule:可能な限りスケジューリングしない
  • NoSchedule:スケジューリングしない(スケジューリング済みのPodはそのままにする)
    • スケジューリング時のみ考慮すればいい
  • NoExecute:スケジューリング許可しない(スケジューリング済みのPodは追い出される)
    • スケジューリング後も、影響を与えられる
    • 追い出すタイミングはPodのspec.terminationGracePeriodSecondsでコントロールできる

※注意:スケジューリング時の動作はTaintsのに従います。Tolerationsと関係ありません。

NodeへTaintsの付与と削除

KubernetesのNodeはmanifestで定義するものではないため、Taintsの付与はkubectlコマンドで実施します。

使用するコマンドは kubectl taint です

Taints付与例:

# foo=bar:NoExecute のtaintを<nodeName> Nodeに付ける
kubectl taint node <nodeName> foo=bar:NoExecute

# 特定ラベルを持つすべてのNodeにfoo=bar:NoExecute のtaintを付ける
kubectl taint node -l <nodeLabelkey>=<nodeLabelValue> foo=bar:NoExecute

Taints削除例:

# <Key>がfooのTaintを削除
kubectl taint node <nodeName> foo-

# <Key>がfooで、<Effect>がNoScheduleのTaintを削除
kubectl taint node <nodeName> foo:<NoSchedule>

Taints確認:
Node詳細情報確認コマンド(kubectl describe)で、Taints情報も確認でいます

# Node詳細情報確認
kubectl describe node <nodeName>

複数Taintsを持つNode

Nodeが複数Taintsを持っている場合、PodのTolerationsがすべてNodeのTaintsにマッチする場合のみ、スケジューリングされます。

Taintsの応用

Taintsはよく障害時Podの自動退避手段として使用されます。
GKEの場合、Nodeの状態に応じて、リアルタイムでNodeにNoExecuteのTaintsが付けられます。

例えば、cordonを実施したNodeにnode.kubernetes.io/unschedulable:NoScheduleのTaintsがリアルタイムで付けられます。

PodのTolerations

Podのspec.tolerations[]で、Tolerationsを設定することが可能です。

また、Tolerationsの設定では、以下のoperator(演算子)が使えます。

  • Equal
  • Exists

Tolerations例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:  # PodのTolerations指定、複数指定可能:複数鍵を持っているイメージ
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"
  - key: "key2"
    operator: "Exists"
    effect: "NoExecute"

TaintsとTolerations判断

PodのTolerationsとNodeのTaintsのマッチ判断は、公式情報で以下のように述べています。

A toleration “matches” a taint if the keys are the same and the effects are the same, and:

  • the operator is Exists (in which case no value should be specified), or
  • the operator is Equal and the values are equal.

即ち、スケジューリングされる条件は以下です。

  • Taintsのと同じはTolerationsがすべて持っていて、かつも同じ
  • operatorの設定のよる判断
    • Equal:TolerationsのがTaintsのと同じの場合のみ、マッチと判断
    • Exists:が同じでなくても、マッチと判断

Tolerations特例「operator: "Exists"」

ここで、以下の特例を覚えておきましょう

Taintsを無視して、どこでもスケジューリング可能のTolerations条件:operator: "Exists"

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - operator: "Exists"  # この条件は万能キーになる、どのNodeでもスケジューリング可能

Tolerations特例「effect指定なし」

Tolerationsにeffect指定しない場合、Taintsと同じと判断されます。

NoExecuteとtolerationSeconds

TolerationsのEffectが"NoExecute"の場合のみ、TolerationsとTaintsがマッチしても、一定時間しか稼働させない設定ができます。

指定時間を0やマイナス数値にする場合、即時追い出すようになります。

例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoExecute"
    tolerationSeconds: 3000  # TolerationsとTaintsがマッチしても、3000秒の稼働しか許容しない

この設定は、よくTaintsとTolerationsがマッチしても、NoExecuteの場合はPodを追い出すために使われます。(時間を0に設定)
※即ち、どんなPodでも追い出すようにする。

最後に

今回の内容を理解するのに、結構手間がかかりました。
できるだけ分かりやすく書いてみました。
お役に立つと嬉しいです。

ここまで読んでいただいて、お疲れ様でした。

コメント

タイトルとURLをコピーしました