手动干预调度
kubeschedule 首先过滤出可调度的节点,然后给这些节点打分,分值最高的获得调度权,最后如果分值相等随机选择一个。本节我们通过打标签、打污点的方式来干预pod的调度行为。
nodeAffinity
kubectl label node 10.4.7.31 disktype=ssd
kubectl get nodes --show-labels
# kubectl label node 10.4.7.31 disktype- 删除标签disktype
【位置】 pod.spec.affinity下
affinity:
nodeAffinity:
##如果pod 在node上运行期间不满足亲和性要求,不会驱逐正在运行的pod。
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
#In,NotIn,Exists,DoesNotExist,Gt,Lt 当exists和doesnotexists 时不需要values
operator: In
values:
- "ssd"
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 #范围是 1-100。对于所有满足requiredDuring的node进行weight 加权
preference:
matchExpressions:
- key: cputype
operator: In
values: ["AMD"]
podAffinity
【位置】 pod.spec.affinity下
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector: # 对比nodeAffinity 格式上主要留意这里
matchExpressions:
- key: app
operator: In
values:
- alpine
topologyKey: "kubernetes.io/hostname"
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
podAffinityTerm: # 对比nodeAffinity 格式上主要留意这里
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- alpine
topologyKey: "kubernetes.io/hostname"
podAntiAffinity
【位置】 pod.spec.affinity下
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: "kubernetes.io/hostname
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
podAffinityTerm: # 对比nodeAffinity 格式上主要留意这里
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- alpine
topologyKey: "kubernetes.io/hostname"
说明:
Pod 间亲和性与反亲和性需要大量计算的处理,这可能会显著减慢大规模集群中的调度。 我们不建议在超过数百个节点的集群中使用它们。
Pod 反亲和性需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配 topologyKey
。如果某些或所有节点缺少指定的 topologyKey
标签,可能会导致意外行为。
nodeName
存在的弊端:
当指定的node名称不存在,pod 会处于pending 状态
指定的node 资源不足以运行该pod 时 pod 提示 OutOfcpu、OutOfmemory
# pod.spec
nodeName: hdss7-22.host.com
nodeSelector
# pod.spec
nodeSelector:
disk: ssd
污点和容忍度
要使用容忍度,需要先给node 添加污点
# NoSchedule PreferNoSchedule NoExecute
kubectl taint nodes hdss7-21.host.com key1=value1:NoSchedule
# 给拥有标签 myLabel=X 的 node 添加污点
kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule
删除污点
kubectl taint nodes hdss7-21.host.com key1=value1:NoSchedule-
【位置】 pod.spec下
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule" #如果 effect 为空,则可以与所有键名 key1 的效果相匹配。
tolerations:
- key: "key1"
operator: "Exists" #此时容忍度不能指定 value
effect: "NoSchedule"
#如果一个容忍度的 `key` 为空且 operator 为 `Exists`, 表示这个容忍度与任意的 key 、value 和 effect 都匹配,即这个容忍度能容忍任意 taint。
tolerations:
- key: ""
operator: "Exists"
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600 # 如果有tolerattionSeconds 则已经调度上来的pod 会在3600s 后驱逐,否则一直运行在该node上
备注
如果你同时指定了 nodeSelector 和 nodeAffinity,两者必须都要满足, 才能将 Pod 调度到候选节点上。
如果你指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms,则 如果其中一个 nodeSelectorTerms 满足的话,pod将可以调度到节点上
如果你指定了多个与 nodeSelectorTerms 关联的 matchExpressions,则 只有当所有 matchExpressions 满足的话,Pod 才会可以调度到节点上。
preferredDuringSchedulingIgnoredDuringExecution 中的 weight 字段值的 范围是 1-100。
对于每个符合所有调度要求(资源请求、RequiredDuringScheduling 亲和性表达式等) 的节点,调度器将遍历该字段的元素来计算总和,并且如果节点匹配对应的 MatchExpressions,则添加“权重”到总和。
然后将这个评分与该节点的其他优先级函数的评分进行组合。 总分最高的节点是最优选的。