亲和性实践
Kubernetes 提供了多种节点分配使用的方法,常用的有以下4种:
- 节点筛选器(nodeSelector)
- 节点亲和与反亲和性(nodeAffinity)
- Pod亲和与反亲和性(podAffinity)
- 节点隔离/限制
1. 标签
在做节点选择的时候很多时候用到了 Kubernetes 的 Label 功能,这里我们分别展示给节点及 Pod Label 的方法。
- 给 10.10.10.10 节点增加
disktype=ssd
标签
# kubectl label nodes 10.10.10.10 disktype=ssd
- 给 Pod 增加
disktype=ssd
标签,同理可以针对 Deployment、Service 等对象进行增加标签操作
# kubectl label po unginx-7db67b8c69-zcxmm disktype=ssd
2. 节点筛选器(nodeSelector)
节点筛选器,用于创建 Pod(及 Deployment、StatefulSet 等控制器时),将 Pod 分配给相应的节点。
实例 yaml 创建了一个 Pod 对象,在 spec.nodeSelector
下以 Map 形式增加改容器部署的节点的限制条件,nodeSelector 会筛选拥有
disktype: ssd
的 Node 节点进行 Pod 部署。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
3. 节点亲和与反亲和性(nodeAffinity)
使用节点亲和性与反亲和性,需要在 Deployment spec.template.spec
下增加 affinity
字段,节点亲和分为硬匹配和软匹配 两种。
3.1 硬匹配
在以下 yaml 示例中,requiredDuringSchedulingIgnoredDuringExecution
可以理解为排除不具备指定 Label 的节点,如果节点不含有
ucloud=yes
则 Pod 不会被分配到该节点。
nodeSelectorTerms
下提供了 matchExpressions
(匹配表达式)和 matchFields
(匹配字段),选择使用其一,我们这里使用了
matchExpressions
,下面的表达式中 Key 和 Values对应,operator
的可选参数有In、NotIn、Exists、DoesNotExist、Gt、Lt,这里可以设置
NotIn、DoesNotExist 进行反亲和的设置,也就是如果这里写入了 operator: NotIn
的时候,Pod 将分配在没有 ucloud=yes
Label 的节点上。
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: ucloud
name: ucloud
spec:
replicas: 3
selector:
matchLabels:
run: ucloud
template:
metadata:
creationTimestamp: null
labels:
run: ucloud
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: ucloud
operator: In
values:
- "yes"
containers:
- image: nginx
name: ucloud
ports:
- containerPort: 80
resources: {}
3.2 软匹配
和 requiredDuringSchedulingIgnoredDuringExecution
对应还有
preferredDuringSchedulingIgnoredDuringExecution
,这里称为软匹配,这个参数为对应节点进行打分,降低不具备 Label 的节点的选中几率。
这里的 weight
字段在1-100范围内。对于满足所有调度要求的每个节点,调度程序将通过迭代此字段的元素计算总和,并在节点与对应的节点匹配时将「权重」添加到总和
MatchExpressions
,然后将该分数与节点的其他优先级函数的分数组合。总得分最高的节点是最优选的。
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
3.3 说明
-
如果同时指定 nodeSelector 和 nodeAffinity,节点必须满足全部条件,Pod 才会被调度到该节点。
-
如果指定了多个 nodeSelectorTerms 关联 nodeAffinity 类型,如果能满足其中一个 nodeSelectorTerms,则 Pod 就可以调度到这个节点。
-
如果指定了多个 matchExpressions 关联的 nodeSelectorTerms,则只有在节点满足所有 matchExpressions 要求情况下才能将该容器调度到节点上。
-
如果删除或更改已有容器节点的 Label,Kubernetes 不会主动删除该容器,亲和的调度选择仅在调度 Pod 时起作用。