节点亲和性调度
节点亲和性调度程序是用来确定Pod对象调度位置的一组规则,这些规则基于节点上的自定义标签和Pod对象上指定的标签选择器进行定义。节点亲和性允许Pod对象定义针对一组可以调度于其上的节点的亲和性或反亲和性,不过,它无法具体到某个特定的节点。例如将Pod调度至有着CPU的节点或者一个可用区域内的节点之上。
定义节点亲和性规则时有两种类型的节点亲和性规则:
- 1.
硬亲和性(required)
:硬亲和性实现的是强制性规则,它是Pod调度时必须要满足的规则,而在不存在满足规则的Node时,Pod对象会被置为Pending
状态。 - 2.
软亲和性(preferred)
:软亲和性规则实现的是一种柔性调度限制,它倾向于将Pod对象运行于某类特定节点之上,而调度器也将尽量满足此需求,但在无法满足需求时它将退而求其次地选择一个不匹配规则的节点之上。
定义节点亲和性规则的关键点有两个:
- 1.为节点配置合乎需求的标签。
- 2.为Pod对象定义合理的标签选择器,从而能够基于标签选择器选择出符合需求的标签。
不过,如requiredDuringSchedulingIgnoredDuringExecution
和preferredDuringSchedulingIgnoredDuringExecution
名字中的后半段字符串IgnoredDuringExecution
隐藏的意义所指,在Pod资源基于节点亲和性规则调度至某节点之后,节点标签发生了改变而不在符合此类节点亲和性规则时,调度器不会将Pod对象从此节点移除,因为它仅对新建的Pod对象生效。
帮助文档:kubectl explain pods.spec.affinity.nodeAffinity
节点硬亲和性
节点硬亲和性类似于Pod对象使用nodeSelector属性可以基于节点标签匹配的方式将Pod对象调度至某一个节点之上。不过它仅能基于简单的等值关系定义标签选择器,而nodeAffinity中支持使用matchExpressions
属性构建更为复杂的标签选择机制。
帮助文档:kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
节点硬亲和性参数解析:
nodeSelectorTerms:节点选择列表(比nodeSelector高级一点)。
matchExpressions:按照节点label列出节点选择器列表。(与matchFields是两种方式,不过结果是一至)
matchFields:按照节点字段列出节点选择器列表。(与matchExpressions是两种方式,不过结果是一至)
key:指定要选择节点label的key。
values:指定要选择节点label的value,值必须为数组 ["value"]
,如果操作符为In
或者 Notin
,value则不能为空,如果操作符为Exists
或者DoesNotExist
,value则必须为空[]
,如果操作符为Gt
或Lt
,则value必须有单个元素,该元素将被解释为整数。
operator:操作符,指定key与value的关系。
In:key与value同时存在,一个key多个value的情况下,value之间就成了逻辑或
效果。
NotIn:label 的值不在某个列表中。
Exists:只判断是否存在key,不用关心value值是什么。
DoesNotExist:某个 label 不存在。
Gt:label 的值大于某个值。
Lt:label 的值小于某个值
1.为Node打上标签
1 2 3 4 5 6 |
#node01打两个标签ssd=true及zone=foo kubectl label node k8s-node01 ssd=true zone=foo #node02打一个标签zone=foo kubectl label node k8s-node02 zone=foo #node03打两个标签ssd=true zone=bar kubectl label node k8s-node03 ssd=true zone=bar |
2.创建Pod资源配置清单
下面Pod资源清单中,该Pod将被绑定到标签key为zone,value为foo的Node上,符合该规则有两个Node,分别是Node01和Node02,下面资源配置清单中只创建了一个Pod,可以来观察下该Pod会被调度至Node01还是Node02。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
apiVersion: apps/v1 kind: Deployment metadata: name: required-nodeaffinity-deploy labels: type: required-deploy spec: replicas: 3 selector: matchLabels: app: required-nodeaffinity-pod template: metadata: labels: app: required-nodeaffinity-pod spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - { key: zone, operator: In, values: ["foo"] } containers: - name: myapp image: busybox:latest command: ["/bin/sh", "-c", "tail -f /etc/passwd"] |
3.查看Pod被调度至哪台Node
如下结果可以看到三个Pod都被调度到了Node01上
1 2 3 4 5 |
kubectl apply -f required-nodeAffinity-pod.yaml kubectl get pods -o wide | grep requ required-nodeaffinity-deploy-55448998fd-hm9ww 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none> required-nodeaffinity-deploy-55448998fd-pkwph 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none> required-nodeaffinity-deploy-55448998fd-z94v2 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none> |
4.创建Pod资源清单2
如下value有两个值,两个值之间是或关系,可以调度到key为zone,values为foo或者bar标签的Node上,下面配置清单中有两个key,两个key之间是与关系,第二个key在第一个key的基础上,Node还有有标签key为ssd,values无需关心,因为使用操作符Exists。
下面的配置清单中,只能调度到标签key为zone,values为foo或者bar以及key为ssd的Node上,满足此需求的Node有Node01和Node03。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
cat required-nodeAffinity-pod.yaml apiVersion: apps/v1 kind: Deployment metadata: name: required-nodeaffinity-deploy labels: type: required-deploy spec: replicas: 3 selector: matchLabels: app: required-nodeaffinity-pod template: metadata: labels: app: required-nodeaffinity-pod spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - { key: zone, operator: In, values: ["foo","bar"] } #foo和bar之间是或关系 - { key: ssd, operator: Exists, values: [] } #两个matchExpressions之间是与关系 containers: - name: myapp image: busybox:latest command: ["/bin/sh", "-c", "tail -f /etc/passwd"] |
5.查看Pod调度结果
如下三个Pod都被调度在Node03节点
1 2 3 4 5 |
kubectl apply -f required-nodeAffinity-pod.yaml kubectl get pods -o wide | grep required-nodeaffinity required-nodeaffinity-deploy-566678b9d8-c84nd 1/1 Running 0 65s 10.244.5.97 k8s-node03 <none> <none> required-nodeaffinity-deploy-566678b9d8-pn27p 1/1 Running 0 65s 10.244.5.95 k8s-node03 <none> <none> required-nodeaffinity-deploy-566678b9d8-x8ttf 1/1 Running 0 65s 10.244.5.96 k8s-node03 <none> <none> |
节点软亲和性
节点软亲和性为节点选择机制提供了一种柔性控逻辑,当调度的Pod对象不再是"必须",而是“应该”放置于某些特性节点之上,当条件不满足时,它也能够接受编排于其它不符合条件的节点之上,另外,它还为每种倾向性提供了weight属性以便用户定义其优先级,取值范围是1-100,数字越大优先级越高。
帮助文档:kubectl explain pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
节点软亲和性参数解析:
preference:节点选择器,与相应的权重相关联。
weight:在1-100范围内,与匹配相应的节点选项相关联的权重。
matchExpressions:按照节点label列出节点选择器列表。(与matchFields是两种方式,不过结果是一至)
matchFields:按照节点字段列出节点选择器列表。(与matchExpressions是两种方式,不过结果是一至)
key:指定要选择节点label的key。
values:指定要选择节点label的value,值必须为数组 ["value"]
,如果操作符为In
或者 Notin
,value则不能为空,如果操作符为Exists
或者DoesNotExist
,value则必须为空[""]
,如果操作符为Gt
或Lt
,则value必须有单个元素,该元素将被解释为整数。
operator:操作符,指定key与value的关系。
In:key与value同时存在,一个key多个value的情况下,value之间就成了逻辑或
效果。
NotIn:label 的值不在某个列表中。
Exists:只判断是否存在key,不用关心value值是什么。
DoesNotExist:某个 label 不存在。
Gt:label 的值大于某个值。
Lt:label 的值小于某个值
1.创建Pod资源配置清单
如下示例中,Pod模版定义了Node软亲和性运行在标签key为zone和values为foo或bar上,以及key为ssd(值无需担心是什么)的Node之上,符合以下需求的是Node01和Node03,但是如下第一个条件key为zoo的权重为60,而key为ssd的为30,所以第一个条件的权重要比第二个条件的权重高一倍,我们下面运行了3个Pod,调度器应该会在Node01上分配两个Pod,Node03上分配1个Pod。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
cat preferred-nodeAffinitt-pod.yaml apiVersion: apps/v1 kind: Deployment metadata: name: preferred-nodeaffinity-deploy labels: type: preferred-deploy spec: replicas: 3 selector: matchLabels: app: preferred-nodeaffinity-pod template: metadata: labels: app: preferred-nodeaffinity-pod spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 60 preference: matchExpressions: - { key: zone, operator: In, values: ["foo","bar"] } - weight: 30 preference: matchExpressions: - { key: ssd, operator: Exists, values: [] } containers: - name: myapp image: busybox:latest command: ["/bin/sh", "-c", "tail -f /etc/passwd"] |
2.查看调度结果
1 2 3 4 |
kubectl get pods -o wide | grep preferred preferred-nodeaffinity-deploy-5bf4699fd9-pcxvz 1/1 Running 0 5m32s 10.244.5.98 k8s-node03 <none> <none> preferred-nodeaffinity-deploy-5bf4699fd9-phm8b 1/1 Running 0 5m32s 10.244.3.106 k8s-node01 <none> <none> preferred-nodeaffinity-deploy-5bf4699fd9-xf87j 1/1 Running 0 5m32s 10.244.3.105 k8s-node01 <none> <none> |