选择节点步骤
k8s默认的调度器是kube-scheduler,它会为新创建的pod且未被调度的pod选择最合适的节点。这个过程如下
- 过滤:节点是否有足够的资源满足请求资源条件,满足条件的节点被称为可调度节点
- 打分:根据不同的条件对节点进行打分,调度器会把pod调度到得分最高的节点
- 绑定:选出得分最高的节点后,调度器会把调度决定通知给kube-apiserver
常用的打分条件
nodeSelector
通过指定节点的标签来选择节点,调度器只会将 Pod 调度到拥有你所指定的每个标签的节点上。如果没有满足条件就不会调度,pod处于pending状态。这个选项是必须满足条件才会调度。
# 给节点添加标签
kubectl label nodes <your-node-name> disktype=ssd
# 展示节点的标签
kubectl get nodes --show-labels
# 该例子会将pod调度到有disktype:ssd标签的节点上
nodeSelector:
disktype: ssd
节点亲和性和反亲和性
节点亲和性概念上类似于 nodeSelector, 但相比于nodeSelector有更丰富的表达能力,支持硬性条件和软条件、权重。 节点亲和性有两种:
- requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。
- preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。
# 该例子会将pod调度到有cpu:cpu标签的节点(必须满足)
# 该例子会将pod尽量调度到北京g区和h区的机器
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- cn-beijing-g
- cn-beijing-h
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cpu
operator: In
values:
- cpu
operator 字段来为 Kubernetes 设置在解释规则时要使用的逻辑操作符。 你可以使用 In、NotIn、Exists、DoesNotExist、Gt 和 Lt 之一作为操作符。NotIn 和 DoesNotExist 可用来实现节点反亲和性行为。
节点亲和性权重的取值范围为1到100,这个值会影响节点的打分。
pod间亲和性和反亲和性
Pod 间亲和性与反亲和性可以基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到的节点,而不是基于节点上的标签。
与节点亲和性类似,Pod 的亲和性与反亲和性也有两种类型:
- requiredDuringSchedulingIgnoredDuringExecution:必须满足
- preferredDuringSchedulingIgnoredDuringExecution:尽量满足
# 该例子尽量让具有app:serviceA标签的pod不在同一台机器上
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- serviceA
topologyKey: kubernetes.io/hostname
weight: 100
污点和容忍度
节点亲和性是Pod的一种属性,用来将Pod吸引到某些特定的节点,而污点是排斥pod,不让pod调度到有污点的机器;
容忍度是允许pod调度到污点机器,污点和容忍度相互配合来避免pod被调度到不合适的节点。注意:如果节点有多个污点,那必须满足所有污点条件才会调度。
# 给节点node1添加污点,键为key1,值为value1,效果是NoSchedule
kubectl taint nodes node1 key1=value1:NoSchedule
# 给节点node1移除污点
kubectl taint nodes node1 key1=value1:NoSchedule-
关于effect(效果)有3个值:
- NoSchedule:新创建pod不会调度到该节点,已运行pod不会被驱逐
- PreferNoSchedule:新创建的pod尽量不调度到该节点,已运行pod不会被驱逐
- NoExecute:新创建的pod不会被调度到该节点,已运行pod会被驱逐,可以设置等待多长时间被驱逐
# 专用节点,具有researchcenter:researchcenter标签,且有污点researchcenter
nodeSelector:
researchcenter: researchcenter
tolerations:
- effect: NoSchedule
key: researchcenter
operator: Equal
# k8s会自动给pod添加2个容忍度,防止网络抖动或者宕机造成pod被驱逐
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
优先级和抢占
pod具有优先级和抢占属性,会根据pod的优先级和抢占来决定pod是否调度和抢占。主要用于任务的抢占。
# 新增一个优先级
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority
value: -20 # 值越高,优先级越高
globalDefault: false
preemptionPolicy: PreemptLowerPriority # 如果值为Never,则为非抢占式
# 系统默认有2个PriorityClass:system-cluster-critical 和 system-node-critical
# 这2个PriorityClass用于确保优先调度关键组件
优先级
默认情况下pod没有开启优先级,那默认的优先级值就是0。当启用 Pod 优先级时,调度程序会按优先级对未调度 Pod 进行排序, 并且每个未调度的 Pod 会被放置在调度队列中其他优先级较低的Pod 之前。 如果满足调度要求,较高优先级的 Pod 可能会比具有较低优先级的 Pod 更早调度。 如果无法调度此类 Pod,调度程序将继续并尝试调度其他较低优先级的 Pod。
抢占
Pod 被创建后会进入队列等待调度。 调度器从队列中挑选一个 Pod 并尝试将它调度到某个节点上。 如果没有找到满足 Pod 的所指定的所有要求的节点,则触发对未调度 Pod 的抢占逻辑。 让我们将 Pod 称为 P。抢占逻辑试图找到一个节点, 在该节点中删除一个或多个优先级低于 P 的 Pod,则可以将 P 调度到该节点上。 如果找到这样的节点,一个或多个优先级较低的 Pod 会被从节点中驱逐。 被驱逐的 Pod 消失后,P 可以被调度到该节点上。
参考
https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/
标签:优先级,亲和性,调度,节点,Pod,k8s,pod From: https://blog.51cto.com/liuping0906/5797992