節點親和性是描述Pods如何分配到一個或一組節點的策略,親和性的相關資料可以參考Kubernetes中的親和性與反親和性。與親和性規則不同, Taints 描述節點拒絕一個或一組Pods的策略。其實現原理為首先通過kubectl taint
命令為Node定義一些瑕疵,然后在Pod的描述文件中指定它的容忍度,即不能夠容忍哪些瑕疵,這樣在調度的時候Pod將不會被調度到哪些有瑕疵的Node上。可以看下圖,只有Taint和Toleration匹配的時候,Pod才會調度到對應的節點上。
1. 設置與解除Taint
Taints包含一個key、value和effect,格式為<key>=<value>:<effect>
。
為Node設置taint的命令如下:
kubectl taint nodes node1 key=value:NoSchedule
執行這個命令后,除非Pod具有相應的toleration,否則不會被調度到node1上。
通過下面的命令,可以刪除這個策略。
kubectl taint nodes node1 key:NoSchedule-
taint支持的effect包括:
- NoSchedule 表示不能容忍taint的Pod不會被調度到這個節點,屬於剛性的限制
- PreferNoSchedule 與上一條相同的效果,但是是柔性的限制,如果集群中沒有其他更合適的Node,則會調度到這個節點
- NoExcute 上兩條只是影響調度,這條還會對正在運行的Pod產生影響,如果在節點上增加一條 taint,那么如果已經運行的Pod沒有設置對應的toleration,則會被立即驅逐
2. 定義 Toleartions
為Pod定義toleration的方法如下:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
上面兩個例子表示如果某個Node存在key=value
的瑕疵或者存在key
的瑕疵,Pod將不會調度到這樣的節點。effect也有三個選項:
- NoSchedule
- NoExecute
- PreferNoScheduled,軟性的限制,避免向有瑕疵的節點調度,但不是強制條件
在書寫tolerations的時候有兩種特殊情況:一是key為空operator為Exists,這種情況匹配所有的keys、values和effects,即對所有的瑕疵都無法忍受;二是effect為空,匹配所有key的瑕疵。
可以向單個Pod和Node增加多個tolerations和taints,Kubernetes采用類似過濾器的方式進行處理,首先遍歷Node上的Taints,並與Pod的tolerations做匹配,如果有匹配的項目則忽略,最后根據剩下為匹配到的taints做判斷:
- 如果至少有一個未匹配到的taints的效果是NoSchedule,則Pod不會被調度到Node上
- 如果僅有一個未匹配到的taints的效果是PreferNoSchedule,則盡量不向這個Node調度
- 如果至少有一個未匹配到的taints的效果是NoExecute,則Pod不會被調度到Node上,已經在Node上運行的Pod會被驅逐。通常,一個NoExcute添加到節點后,不能容忍的Pod會被立即驅逐,可以通過
tolerationSeconds
設置延時驅逐。
3. 例子
Taints和tolerations是避免Pods部署到Node,以及從Node中驅離Pod的靈活方法,有一些應用場景:
3.1 調度場景
控制Pod的調度。例如專用節點 Dedicated Nodes ,對於Kubeadm創建的集群,默認Master節點是tainted,即普通的Pod不會部署到這個節點;例如特殊硬件的節點(GPU),只希望需要使用GPU的應用部署到上面;在節點出問題時,對節點上的Pod進行驅逐(alpha特性)
3.2 配置節點故障后Pod重新調度的時間
例如下面的配置文件,對於notReady和unreachable狀態的節點,其上的Pod等待300秒,如果仍未恢復,則會停止執行。
...
tolerations:
- effect: NoExcute
key: node.alpha.kubernetes.io/notReady
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.alpha.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
在1.12版本中 TaintNodesByCondition 特性已經提升為 beta。