kubernetes学习指南,蹲坑学kubernetes之9-3kube-scheduler原理详解
kubernetes学习指南,蹲坑学kubernetes之9-3kube-scheduler原理详解priority:优先级排序,选择优先级最高的节点 predicate:过滤不符合条件的节点二、kube-scheduler工作原理图2:kube-scheduler调度原理kube-scheduler调度分为两个阶段:predicate 和 priority
一、kube-scheduler的作用
kube-scheduler是一个调度器,负责调度Pod到集群内的Node节点上。监听kube-apiserver上Node和Pod变化情况。查询Node节点上未分配的Pod,根据调度策略为这些Pod分配Node节点。
图1:kube-scheduler调度过程
在调度过程中需要考虑:
- 公平调度
- 资源合理和高效利用
- 服务质量(QoS)
- 灵活性
- 可扩展性和高可用性
- 内部负载干扰
二、kube-scheduler工作原理
图2:kube-scheduler调度原理
kube-scheduler调度分为两个阶段:predicate 和 priority
predicate:过滤不符合条件的节点
priority:优先级排序,选择优先级最高的节点
1、predicates 策略:
PodFitsPorts:同 PodFitsHostPorts
PodFitsHostPorts:检查是否有 Host Ports 冲突
PodFitsResources:检查 Node 的资源是否充足
(包括允许的 Pod 数量、CPU、内存、GPU 个数以及其他的 OpaqueIntResources )
HostName:检查 pod.Spec.NodeName 是否与候选节点一致
MatchNodeSelector:检查候选节点的 pod.Spec.NodeSelector 是否匹配
NoVolumeZoneConflict:检查 volume zone 是否冲突
MaxEBSVolumeCount:检查 AWS EBS Volume 数量是否过多(默认不超过 39)
MaxGCEPDVolumeCount:检查 GCE PD Volume 数量是否过多(默认不超过 16)
MaxAzureDiskVolumeCount:检查 Azure Disk Volume 数量是否过多(默认不超过 16)
MatchInterPodAffinity:检查是否匹配 Pod 的亲和性要求
NoDiskConflict:检查是否存在 Volume 冲突,仅限于 GCE PD、AWS EBS、Ceph RBD 以及 ISCSI
GeneralPredicates:分为 noncriticalPredicates 和 EssentialPredicates。
( noncriticalPredicates 中包含 PodFitsResources)
( EssentialPredicates 中包含 PodFitsHost,PodFitsHostPorts 和 PodSelectorMatches )
PodToleratesNodeTaints:检查 Pod 是否容忍 Node Taints
CheckNodeMemoryPressure:检查 Pod 是否可以调度到 MemoryPressure 的节点上
CheckNodeDiskPressure:检查 Pod 是否可以调度到 DiskPressure 的节点上
NoVolumeNodeConflict:检查节点是否满足 Pod 所引用的 Volume 的条件
2、priorities 策略:
SelectorSpreadPriority:优先减少节点上属于同一个 Service 或 Replication Controller 的 Pod 数量
InterPodAffinityPriority:优先将 Pod 调度到相同的拓扑上(如同一个节点、Rack、Zone 等)
LeastRequestedPriority:优先调度到请求资源少的节点上
BalancedResourceAllocation:优先平衡各节点的资源使用
NodePreferAvoidPodsPriority:alpha.kubernetes.io/preferAvoidPods 字段判断 权重为 10000,避免其他优先级策略的影响
NodeAffinityPriority:优先调度到匹配 NodeAffinity 的节点上
TaintTolerationPriority:优先调度到匹配 TaintToleration 的节点上
ServiceSpreadingPriority:尽量将同一个 service 的 Pod 分布到不同节点上,已经被 SelectorSpreadPriority 替代 [默认未使用]
EqualPriority:将所有节点的优先级设置为 1[默认未使用]
ImageLocalityPriority:尽量将使用大镜像的容器调度到已经下拉了该镜像的节点上 [默认未使用]
MostRequestedPriority:尽量调度到已经使用过的 Node 上,特别适用于 cluster-autoscaler[默认未使用]
3、自定义策略
kube-scheduler还支持使用--policy-config-file指定一个调度策略文件来自定义调度策略,如下图所示:
图3:kube-scheduler调度策略
三、指定Node节点调度
有三种方式指定 Pod 只运行在指定的 Node 节点上
1、nodeSelector:只调度到匹配指定 label 的 Node 上
首先给 Node 打上标签:
kubectl label nodes k8s-node-1 disktype=ssd
然后在 daemonset 中指定 nodeSelector 为 disktype=ssd
2、nodeAffinity:功能更丰富的 Node 选择器,比如支持集合操作。
nodeAffinity 目前支持两种:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,分别代表必须满足条件和优选条件。比如下面的例子代表调度到包含标签 kubernetes.io/e2e-az-name 并且值为 e2e-az1 或 e2e-az2 的 Node 上,并且优选还带有标签 another-node-label-key=another-node-label-value 的 Node。
3、podAffinity:调度到满足条件的 Pod 所在的 Node 上
podAffinity基于Pod的标签来选择Node,仅调度到满足条件Pod所在的Node上,支持podAffinity和podAntiAffinity。
三、设置污点(Taints)和容忍(tolerations)
Taints 和 tolerations 用于保证 Pod 不被调度到不合适的 Node 上,其中 Taint 应用于 Node 上,而 toleration 则应用于 Pod 上。目前支持的 taint 类型:
NoSchedule:新的Pod不调度到该Node 上,不影响正在运行的Pod
PreferNoSchedule:soft版的NoSchedule,尽量不调度到该 Node 上
NoExecute:新的Pod不调度到该 Node 上,并且删除(evict)已在运行的Pod。Pod可以增加一个时间(tolerationSeconds),
然而,当Pod的Tolerations匹配Node的所有Taints的时候可以调度到该Node上;当Pod是已经运行的时候,也不会被删除(evicted)。另外对于NoExecute,如果Pod增加了一个tolerationSeconds,则会在该时间之后才删除Pod。
例: node1上应用以下几个taint:
[root@k8s-master ~]# kubectl taint nodes k8s-master key1=value1:NoSchedule
[root@k8s-master ~]# kubectl taint nodes k8s-master key1=value1:NoExecute
[root@k8s-master ~]# kubectl taint nodes k8s-master key2=value2:NoSchedule
四、优先级调度与多调度器
1、优先级调度
从 v1.8 开始,kube-scheduler 支持定义 Pod 的优先级,从而保证高优先级的 Pod 优先调度。并从 v1.11 开始默认开启。在指定 Pod 的优先级之前需要先定义一个 PriorityClass。value为32位整数的优先级,值越大,优先级越高。
2、多调度器
如果默认的调度器不满足要求,还可以部署自定义的调度器。并且,在整个集群中还可以同时运行多个调度器实例,通过 podSpec.schedulerName 来选择使用哪一个调度器(默认使用内置的调度器)。