K8s - 3 核心概念 - 13 调度器


K8s - 目录



一、kubernetes 核心技术-调度器


1. 概述

一个容器平台的主要功能就是为容器分配运行时所需要的计算、存储和网络资源。容器调度系统负责选择在最合适的主机上启动容器,并且将它们关联起来。它必须能够自动的处理容器故障并且能够在更多的主机上自动启动更多的容器来应对更多的应用访问。 目前三大主流的容器平台 Swarm,Mesos 和 Kubernetes 具有不同的容器调度系统。

Swarm

  • 直接调度 Docker 容器,并且提供和标准 Docker API 一致的 API。

Mesos

  • 针对不同的运行框架采用相对独立的调度系统;
  • Marathon 框架提供了 Docker 容器的原生支持。

Kubernetes

  • 采用了 Pod 和 Label 这样的概念把容器组合成一个个的互相存在依赖关系 的逻辑单元。相关容器被组合成 Pod 后被共同部署和调度,形成服务(Service) 。这个是 Kubernetes 和 Swarm,Mesos 的主要区别。

相对来说,Kubernetes采用这样的方式简化了集群范围内相关容器被共同调度管理的复杂性。换一种角度来看,Kubernetes 采用这种方式能够相对容易的支持更强大,更复杂的容器调度算法。

2. k8s 调度工作方式

Kubernetes调度器作为集群的大脑,在如何提高集群的资源利用率、保证集群中服务的稳定运行中也会变得越来越重要。

Kubernetes 的资源分为两种属性:

  1. 可压缩资源(例如 CPU 循环,Disk I/O 带宽) 都是可以被限制和被回收的,对于一个 Pod 来说可以降低这些资源的使用量而不去杀掉 Pod。
  2. 不可压缩资源(例如内存、硬盘空间) 一般来说不杀掉 Pod 就没法回收。未来 Kubernetes 会加入更多资源,如网络带宽,存储 IOPS 的支持。

3. k8s 调度器

(1) kube-scheduler 是 kubernetes 系统的核心组件之一,主要负责整个集群资源的调 度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理、更加充分的利用集群的资源,这也是选择使用 kubernetes 一个非常重要的理由。如果一门新的技术不能帮助企业节约成本、提供效率,我相信是很难推进的。
(2) 调度流程
默认情况下,kube-scheduler 提供的默认调度器能够满足我们绝大多数的要求,前面接触的示例也基本上用的默认的策略,都可以保证我们的 Pod 可以被分配到资源充足的节点上运行。但是在实际的线上项目中,可能我们自己会比 kubernetes 更加了解我们自己的应用,比如我们希望一个 Pod 只能运行在特定的几个节点上,或者这几个节点只能用来运行特定类型的应用,这就需要我们的调度器能够可控。
kube-scheduler 是 kubernetes 的调度器,它的主要作用就是根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上去,是一个独立的二进制程序,启动之后会一直监听 API Server,获取到 PodSpec.NodeName 为空的 Pod,对每个 Pod 都会创建一个 binding。
在这里插入图片描述
调度主要分为以下几个部分:

  1. 预选过程,过滤掉不满足条件的节点,这个过程称为 Predicates。

  2. 优选过程,对通过的节点按照优先级排序,称之为 Priorities。

  3. 从中选择优先级最高的节点,如果中间任何一步骤有错误,就直接返回错误。

Predicates 阶段首先遍历全部节点,过滤掉不满足条件的节点,属于强制性规则,这一阶 段输出的所有满足要求的 Node 将被记录并作为第二阶段的输入,如果所有的节点都不满 足条件,那么 Pod 将会一直处于 Pending 状态,直到有节点满足条件,在这期间调度器 会不断的重试。

所以我们在部署应用的时候,如果发现有 Pod 一直处于 Pending 状态,那么就是没有满足调度条件的节点,这个时候可以去检查下节点资源是否可用。

Priorities 阶段即再次对节点进行筛选,如果有多个节点都满足条件的话,那么系统会按 照节点的优先级(priorites)大小对节点进行排序,最后选择优先级最高的节点来部署 Pod 应用。

下面是调度过程的简单示意图:
在这里插入图片描述
在这里插入图片描述
更详细的流程是这样的:
首先,客户端通过 API Server 的 REST API 或者 kubectl 工具创建 Pod 资源 API Server 收到用户请求后,存储相关数据到 etcd 数据库中
调度器监听 API Server 查看为调度(bind)的 Pod 列表,循环遍历地为每个 Pod 尝试分 配节点,这个分配过程就是我们上面提到的两个阶段:

预选阶段(Predicates),过滤节点,调度器用一组规则过滤掉不符合要求的 Node 节点, 比如 Pod 设置了资源的 request,那么可用资源比 Pod 需要的资源少的主机显然就会被 过滤掉
优选阶段(Priorities),为节点的优先级打分,将上一阶段过滤出来的 Node 列表进行打 分,调度器会考虑一些整体的优化策略,比如把 Deployment 控制的多个 Pod 副本分布到 不同的主机上,使用最低负载的主机等等策略
经过上面的阶段过滤后选择打分最高的 Node 节点和 Pod 进行 binding 操作,然后将结 果存储到 etcd 中
最后被选择出来的 Node 节点对应的 kubelet 去执行创建 Pod 的相关操作 其中 Predicates 过滤有一系列的算法可以使用,我们这里简单列举几个: PodFitsResources: 节点上剩余的资源是否大于 Pod 请求的资源
PodFitsHost: 如果 Pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配 PodFitsHostPorts: 节点上已经使用的 port 是否和 Pod 申请的 port 冲突
PodSelectorMatches: 过滤掉和 Pod 指定的 label 不匹配的节点
NoDiskConflict: 已经 mount 的 volume 和 Pod 指定的 volume 不冲突,除非它们都是 只读的
CheckNodeDiskPressure: 检查节点磁盘空间是否符合要求
CheckNodeMemoryPressure: 检查节点内存是否够用
除了这些过滤算法之外,还有一些其他的算法,更多更详细的我们可以查看源码文件: k8s.io/kubernetes/pkg/scheduler/algorithm/predicates/predicates.go。
而 Priorities优先级是由一系列键值对组成的,键是该优先级的名称,值是它的权重值, 同样,我们这里给大家列举几个具有代表性的选项:
LeastRequestedPriority: 通过计算 CPU 和内存的使用率来决定权重,使用率越低权重越 高,当然正常肯定也是资源是使用率越低权重越高,能给别的 Pod 运行的可能性就越大
SelectorSpreadPriority: 为了更好的高可用,对同属于一个 Deployment 或者 RC 下面 的多个 Pod 副本,尽量调度到多个不同的节点上,当一个 Pod 被调度的时候,会先去查 找该 Pod 对应的 controller,然后查看该 controller 下面的已存在的 Pod,运行 Pod 越少的节点权重越高
ImageLocalityPriority: 就是如果在某个节点上已经有要使用的镜像节点了,镜像总大小 值越大,权重就越高
NodeAffinityPriority: 这个就是根据节点的亲和性来计算一个权重值,后面我们会详细 讲解亲和性的使用方法。

4. 节点调度亲和性

5. Pod 资源亲和调度

6. 污点和容忍度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qumy97

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值