節點親和性是描述Pods如何分配到一個或一組節點的策略,與之相反 Taints 描述節點拒絕一個或一組Pods的策略。其實現原理爲首先通過kubectl taint
命令爲Node定義一些瑕疵,然後在Pod的描述文件中指定它的容忍度,即不能夠容忍哪些瑕疵,這樣在調度的時候Pod將不會被調度到哪些有瑕疵的Node上。
1. 設置與解除Taint
kubectl taint nodes node1 key=value:NoSchedule
這個命令的效果是任何Pod不會被調度到節點node1上,除非這個Pod具有相應的toleration。
通過下面的命令,可以刪除這個策略。
kubectl taint nodes node1 key:NoSchedule-
2. 定義 Toleartions
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的靈活方法,有一些應用場景:
- 專用節點 Dedicated Nodes
- 特殊硬件的節點
- 節點出問題時進行Pod的驅逐(alpha特性)
在1.12版本中 TaintNodesByCondition 特性已經提升爲 beta。