nodeSelector用于将Pod调度到匹配Label的节点上,如果没有匹配的标签会调度失败。
作用:
应用场景:
示例:确保Pod分配到具有SSD硬盘的节点上
#kubectl label nodes =
kubectl label nodes k8s-node1 disktype=ssd
#验证
kubectl get nodes --show-labels
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
kubectl get pods -o wide
删除节点标签:
kubectl label node k8s-node1 <label-key>-
#验证
kubectl get pods -o wide
节点亲和性,类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。
相比nodeSelector:
in
、notin
、exists
、doesnotexist
、gt
、lt
操作符。requiredDuringSchedulingIgnoredDuringExecution
:硬策略,必须满足;preferredDuringSchedulingIgnoredDuringExecution
:软策略,尝试满足,但是不保证。举例:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1
- antarctica-west1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
注意:
nodeSelector
和nodeAffinity
,那么k8s在调度Pod时必须同时满足两者的条件。nodeAffinity
时指定了多个nodeSelectorTerms
,那么节点只要满足其中一个nodeSelectorTerms
,就可以被调度分配Pod。nodeSelectorTerms
下指定了多个matchExpressions
,那么节点必须满足所有matchExpressions
,才能被调度分配Pod。基于节点标签分配是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的节点上。相反地,我们也可以在Node节点上添加污点属性(Taints),来避免Pod被分配到不合适的节点上。
taints
:避免Pod调度到特定节点上;tolerations
:允许Pod调度到有Taints的节点上。举例:
#kubectl taint node key=value:[effect]
kubectl taint node k8s-node2 gpu=yes:NoSchedule
其中,effect可以取值为:
NoSchedule
:一定不能被调度;PreferNoSchedule
:尽量不要被调度,非必须;NoExecute
:不仅不会调度,还会驱逐节点上已有的Pod。kubectl describe node k8s-node2 | grep Taint
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "gpu"
operator: "Equal"
value: "yes"
effect: "NoSchedule"
删除污点:
#kubectl taint node key:[effect]-
kubectl taint node k8s-node2 gpu:NoSchedule-
注意:
Taints和Tolerations匹配的原则是key
相同、effect
相同,并且满足:
Exists
(即没有value
);Equal
,且value
相等。两个特例:
key
和运算符Exists
,会匹配所有的key
、value
和effect
,意味著容忍所有污点;key
和一个空的effect
匹配此key
的所有effect
。通过nodeName指定节点名称,可以将Pod调度到指定节点上,不经过调度器。由于不经过调度器,使用nodeName后,nodeSelector、nodeAffinity和Taints都不会起作用。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: k8s-node2
如果指定的节点不存在、或者没有足够的资源,那么该Pod不会运行。如果Pod所在的节点挂了,也不会自动漂移到其他节点。
References
【1】https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
【2】https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/