NodeAffinity節點親和性,是Pod上定義的一種屬性,使Pod能夠按我們的要求排程到某個Node上,而Taints則恰恰相反,它可以讓Node拒絕運作Pod,甚至驅逐Pod。
Taints(污點)是Node的一個屬性,設定了Taints(污點)後,因為有了污點,是以Kubernetes是不會将Pod排程到這個Node上的,
于是Kubernetes就給Pod設定了個屬性Tolerations(容忍),隻要Pod能夠容忍Node上的污點,那麼Kubernetes就會忽略Node上的污點,就能夠(不是必須)把Pod排程過去。
是以 Taints(污點)通常與Tolerations(容忍)配合使用。
1、設定污點:
kubectl taint node [node] key=value[effect]
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule :一定不能被排程。
PreferNoSchedule:盡量不要排程。
NoExecute:不僅不會排程,還會驅逐Node上已有的Pod。
示例:kubectl taint node 10.3.1.16 test=16:NoSchedule
2、去除污點:
比如設定污點:
kubectl taint node 10.3.1.16 test=16:NoSchedule
kubectl taint node 10.3.1.16 test=16:NoExecute
去除指定key及其effect:
kubectl taint nodes node_name key:[effect]- #(這裡的key不用指定value)
去除指定key所有的effect:
kubectl taint nodes node_name key-
示例:
kubectl taint node 10.3.1.16 test:NoSchedule-
kubectl taint node 10.3.1.16 test:NoExecute-
kubectl taint node 10.3.1.16 test-
3、Pod 容忍污點示例:
首先給node設定個污點以觀察排程效果:
kubectl taint node 10.3.1.16 test=16:NoSchedule
當pod沒有設定容忍時被排程到10.3.1.17:
apiVersion: v1
kind: Pod
metadata:
name: pod-taints
labels:
os: ubuntu
spec:
containers:
- name: pod-tains
image: 10.3.1.15:5000/ubuntu:16.04
root@ubuntu:#kubectl create -f pod-taints.yaml
pod "pod-taints" created
###
root@ubuntu# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-taints 1/1 Running 0 7s 192.168.77.216 10.3.1.17
給Pod設定容忍:
apiVersion: v1
kind: Pod
metadata:
name: pod-taints
labels:
os: ubuntu
spec:
tolerations: #設定容忍性
- key: "test"
operator: "Equal" #如果操作符為Exists,那麼value屬性可省略,如果不指定operator,則預設為Equal
value: "16"
effect: "NoSchedule"
#意思是這個Pod要容忍的有污點的Node的key是test Equal 16,效果是NoSchedule,
#tolerations屬性下各值必須使用引号,容忍的值都是設定Node的taints時給的值。
containers:
- name: pod-tains
image: 10.3.1.15:5000/ubuntu:16.04
root@ubuntu15:/data/yaml# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-taints 1/1 Running 0 3m 192.168.150.216 10.3.1.16
#容忍後就立即排程到另外一個Node上了。需要在兩個Node的Pod數量不平衡時才能看到效果。
對于tolerations屬性的寫法:
其中的key、value、effect 與Node的Taint設定需保持一緻, 還有以下幾點說明:
1、如果operator的值是Exists,則value屬性可省略。
2、如果operator的值是Equal,則表示其key與value之間的關系是equal(等于)。
3、如果不指定operator屬性,則預設值為Equal。
另外,還有兩個特殊值:
1、空的key 如果再配合Exists 就能比對所有的key與value ,也是是能容忍所有node的所有Taints。
2、空的effect 比對所有的effect。
一個node上可以有多個污點:
比如 test=16:NoScheduler test2=16:NoSchedule
而在Pod容忍時隻容忍了其中一個:
tolerations:
- key: "test"
operator: "Equal"
value: "16"
effect: "NoSchedule"
這樣的結果是此Pod無法被排程到key為test的node( 10.3.1.16)上去,因為此Node上設定了兩個污點,
而這個Pod隻比對到了一個污點,也就是隻容忍了一個污點,是以可以再加一個容忍:
tolerations:
- key: "test"
operator: "Exists"
effect: "NoSchedule"
- key: "test2"
operator: "Equal"
value: "16"
effect: "NoSchedule"
如果在設定node的Taints(污點)之前,就已經運作了一些Pod,那麼這些Pod是否還能繼續在此Node上運作? 這就要看設定Taints污點時的effect(效果)了。
如果effect的值是NoSchedule或PreferNoSchedule,那麼已運作的Pod仍然可以運作,隻是新Pod(如果沒有容忍)不會再往上排程。
而如果effect的值是NoExecute,那麼此Node上正在運作的Pod,隻要沒有容忍的,立刻被驅逐。
雖然是立刻被驅逐,但是K8S為了彰顯人性化,又給具有NoExecute效果的污點, 在容忍屬性中有一個可選的
tolerationSeconds字段,用來設定這些Pod還可以在這個Node之上運作多久,給它們一點寬限的時間,到時間才驅逐。
如果是以Pod來啟動的,那麼Pod被驅逐後, 将不會再被運作,就等于把它删除了。
如果是deployment/rc,那麼删除的pod會再其它節點運作。
如果是DaemonSet在此Node上啟動的Pod,那麼也不會再被運作,直到Node上的NoExecute污被去除或者Pod容忍。
#設定Pod的寬限時間
spec:
tolerations: #設定容忍性
- key: "test"
operator: "Equal" #如果操作符為Exists,那麼value屬性可省略
value: "16"
effect: "NoExecute"
tolerationSeconds: 180
#如果運作此Pod的Node,被設定了具有NoExecute效果的Taint(污點),這個Pod将在存活180s後才被驅逐。
#如果沒有設定tolerationSeconds字段,将永久運作。
通過對Taints和Tolerations的了解,可以知道,通過它們可以讓某些特定應用,獨占一個Node:
給特定的Node設定一個Taint,隻讓某些特定的應用來容忍這些污點,容忍後就有可能會被排程到此特定Node,