# Taints & Tolerations 介紹
## [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
[*Node affinity*](https://hackmd.io/GxNJtFfzQ_W8X2Tx6uCtHw?view#Node-affinity) 是 Pod 的屬性,它將 Pod **吸引**到一組 Node(無論是作為偏好還是硬性要求)。Taints 則相反-它們允許一個 Node 排斥一組 Pod。
Tolerations 應用於 Pod。Tolerations 允許 Scheduler 調度 Pod 到有 Taints 的 Node。
Taints 和 Tolerations 協同工作,以確保 Pod 不會被調度到不適當的 Node。一個或多個 Taints 被應用到一個 Node;這標誌著該 Node 不應接受任何不能容忍污點的 Pod。
**對 Node 加上 Taints → Pods 不會被安排到有 Taints 的 Node
對 Pod 加上 Tolerations → 這些 Pods 可以放到有 Taints 的 Node**
## Taints
您可以使用 **`kubectl taint nodes <node-name> <key>=<value>:<taint-effect>`** 將 Taint 新增至 Node。例如:
```bash
kubectl taint nodes node1 key1=value1:NoSchedule
```
在 Node **`node1`** 上放置 Taint。Taint 具有 key **`key1`**、value **`value1`** 和 taint effect **`NoSchedule`**。這意味著沒有 Pod 能夠調度到 **`node1`** 上,除非它具有匹配的 Toleration。
要刪除上面命令添加的 Taint,您可以運行:
```bash
kubectl taint nodes node1 key1=value1:NoSchedule-
```
Taint effect 有三種:
+ **NoExecute**
這會影響 Node 上已經運行的 Pod,如下所示:
+ 不能容忍 Taint 的 Pod 會立即被驅逐
+ 容忍 Taint 但未在其 **`tolerations`** 規範中指定 **`tolerationSeconds`** 的 Pod 永遠保持綁定狀態
+ 能夠容忍指定 **`tolerationSeconds`** 的 Taint 的 Pod 會在指定時間內保持綁定。經過該時間後,Node 生命週期控制器將從 Node 中逐出 Pod。
+ **NoSchedule**
除非新的 Pod 具有匹配的 Toleration,否則不會在有 Taint 的 Node 上調度它們。目前在 Node 上運行的 Pod 不會被驅逐。
+ **PreferNoSchedule**
PreferNoSchedule 是 NoSchedule 的「偏好」或「軟」版本。控制平面會**嘗試**避免在 Node 上放置不能容忍 Taint 的 Pod,但這並不能保證。
:::success
:notebook: **Note:**
您可以在同一個 Node 上放置多個 Taint,並在同一個 Pod 上放置多個 Toleration。Kubernetes 處理多個 Taint 和 Toleration 的方式就像一個過濾器:從 Node 的所有 Taint 開始,然後忽略 Pod 具有匹配 Toleration 的 Taint;其餘未被忽略的 Taint 對 Pod 有指定的影響。
:::
## Tolerations
您可以在 PodSpec 中指定 Pod 的 Toleration。以下兩個 Toleration「符合」上面的 **`kubectl taint`** 指令所建立的 Taint,因此具有任一 Toleration 的 Pod 都能夠調度到 **`node1`** 上:
```yaml
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
```
```yaml
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"
```
以下是使用 Toleration 的 Pod 範例:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
```
**`operator`** 的預設值為 **`Equal`**。
:bulb: 如果 **`key`** 相同且 **`effect`** 相同,則 Toleration「匹配」Taint,且:
+ **`operator`** 是 **`Exists`**(在這種情況下不應指定任何 **`value`**),或者
+ **`operator`** 是 **`Equal`** 並且 **`value`** 應該相等。
:::success
:notebook: **Note:**
有兩種特殊情況:
+ 帶有 **`operator`** 是 **`Exists`** 的空 **`key`** 可匹配所有 key、value 和 effect,這意味著這將容忍一切。
+ 空 **`effect`** 符合所有帶有 key **`key1`** 的效果。
:::