1. 集群调度简介

Schedulerkubernetes中的调度器组件,主要的任务是把定义的pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:

  • 公平: 如何保证每个节点都能被分配
  • 资源资源高效利用: 集群所有资源最大化被使用
  • 效率: 调度的性能要好,能够尽快地对大批量的pod完成调度工作
  • 灵活: 允许用户根据自己的需求控制调度的逻辑

Sheduler是作为单独的程序运行的(如果是kubeadm则是以pod形式运行的),启动之后会一直和APIServer持续连接,获取PodSpec.NodeName为空的pod,对每个pod都会创建一个binding,表明该 pod 应该放到哪个节点上

这里的PodSpec.NodeName不为空的pod,说明我们手动指定了这个pod应该部署在哪个node上,所以这种情况Sheduler就不需要参与进来了


2. 调度过程

2.1 调度过程概览

调度过程分为两部分,如果中间任何一步骤有错误,直接返回错误:

  1. predicate(预选): 首先是过滤掉不满足条件的节点
  2. priority(优选): 然后从中选择优先级最高的节点

2.2 Predicate(预选)

Predicate有一系列的算法可以使用: 

  • PodFitsResources: 节点上剩余的资源是否大于pod请求的资源
  • Podfitshost: 如果pod指定了NodeName,检查节点名称是否和NodeName相匹配
  • PodFfitsHostPorts: 节点上已经使用的port是否和 pod申请的port冲突
  • PodSelectorMatches: 过滤掉和 pod指定的label不匹配的节点
  • NoDiskConflict: 已经mount的volume和 pod指定的volume不冲突,除非它们都是只读

注意:

如果在predicate过程中没有合适的节点。pod会一直在pending状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续priorities过程

2.3 Priorities(优选)

Priorities是按照优先级大小对节点排序

优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:

  • LeastRequestedPriority:通过计算CPU和 Memory的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点
  • BalancedResourceA1location:节点上CPU和Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用
  • ImageLocalityPriority:倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高

通过算法对所有的优先级项目和权重进行计算,得出最终的结果


3. 调度的亲和性

3.1 node亲和性

3.1.1 node亲和性简介

简单来理解就是,指定调度到的nodenodeAffinity又分为两种:

pod.spec.nodeAffinity

  • preferredDuringSchedulinglgnoredDuringExecution:软策略【我想要去这个节点】
  • requiredDuringschedulinglgnoredDuringExecution:硬策略【我一定要去这个节点】

3.1.2 node亲和性硬策略示例

apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: lzw5399/tocgenerator
affinity:
# 指定亲和性为node亲和性
nodeAffinity:
# 指定为硬策略
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
# key就是node的label
# 这句话代表当前pod一定不能分配到k8s-node02节点上
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- k8s-node02
  • 关于- key: kubernetes.io/hostname,可以通过以下方式查看node的label
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master Ready master 154d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=
node02 Ready <none> 74d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,com=youdianzhishi,course=k8s,kubernetes.io/hostname=node02
node03 Ready <none> 134d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03

3.1.3 node亲和性软策略示例

apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: lzw5399/tocgenerator
affinity:
# 声明节点亲和性为软策略
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
# 当前策略权重为1
- weight: 1
preference:
# [最好]能分配到label为source=k8s-node03的节点上
matchExpressions:
- key: source
operator: In
values:
- k8s-node03

3.2 pod亲和性

3.2.1 pod亲和性/反亲和性简介

pod亲和性主要解决pod可以和哪些pod部署在同一个拓扑域中的问题

拓扑域: 用主机标签实现,可以是单个主机,或者具有同个label的多个主机,也可以是多个主机组成的 cluster、zone 等等

所以简单来说: 比如一个 pod 在一个节点上了,那么我这个也得在这个节点,或者你这个 pod 在节点上了,那么我就不想和你待在同一个节点上

pod亲和性/反亲和性又分为两种:

pod.spec.affinity.podAffinity/podAntiAffinity:

  • preferredDuringSchedulinglgnoredDuringExecution:软策略
  • requiredDuringSchedulinglgnoredDuringExecution:硬策略

3.2.2 pod亲和性/反亲和性示例

apiVersion: v1
kind: Pod
metadata:
name: pod-3
labels:
app: pod-3
spec:
containers:
- name: pod-3
image: hub.coreqi.cn/library/myapp:v1
affinity:
# 配置一条pod亲和性策略
podAffinity:
# 配置为硬策略
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pod-1
topologyKey: kubernetes.io/hostname
# 配置一条pod反亲和性策略
podAntiAffinity:
# 配置为软策略
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pod-2
topologyKey: kubernetes.io/hostname

3.3 亲和性/反亲和性调度策略比较

调度策略 匹配标签 操作符 拓扑域支持 调度目标
nodeAffinity 主机 IN, NotIn, Exists, DoesNotExist, Gt, Lt 指定主机
podAffinity POD IN, NotIn, Exists, DoesNotExist POD与指定POD同一拓扑域
podAntiAffinity POD IN, NotIn, Exists, DoesNotExist POD与指定POD不在同一拓扑域

4. Taint(污点)和Toleration(容忍)

4.1 Taint和和Toleration简介

节点亲和性是pod的一种属性(偏好或硬性要求),它使pod被吸引到一类特定的节点。Taint则相反,它使节点能够排斥一类特定的pod。

Tainttoleration相互配合,可以用来避免pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的pod,是不会被该节点接受的。如果将toleration 应用于pod上,则表示这些pod 可以(但不要求)被调度到具有匹配 taint 的节点上。

如果没有特别配置toleration,默认是不容忍所有污点的

4.2 Taint(污点)

4.2.1 Taint的组成

污点的value是可选项,即污点有两种组成形式

key-value:effect
key:effect

effect

effect描述污点的作用, 当前支持三种策略:

  • NoSchedu1e:表示k8s将不会将Pod 调度到具有该污点的Node上
  • PreferNoSchedu1e:表示k8s将尽量避免将Pod调度到具有该污点的 Node上
  • NoExecute:表示k8s将不会将 Pod调度到具有该污点的Node上,同时会将Node上已经存在的 Pod 驱逐出去

4.2.2 Taint的设置、查看和去除

  1. 设置污点
# value不为空的格式
kubectl taint nodes node1 key1=value1:NoSchedule # value为空的格式
kubectl taint nodes node1 key1:NoExecute
  1. 污点的查看
# 通过describe node查看Taints属性
kubectl describe node nodename

  1. 污点的去除

    • 通过describe查看污点,然后把污点复制出来,按照如下格式在最后加一个-就好了
# 去除如上截图的一个污点
kubectl taint nodes node1 haha-233:NoSchedule-

4.3 Toleration(容忍)

4.3.1 Toleration简介

设置了污点的Node将根据tainteffect:NoSchedulePreferNoScheduleNoExecute 和 Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到Node上

但我们可以在Pod上设置容忍(Toleration)。意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上

可以被调度不代表一定会被调度,只是保存了可能性

4.3.2 Toleration的资源清单配置

如下是pod.spec.tolerations部分:

tolerations:
# 容忍key1-value1:NoSchedule的污点
# 且需要被驱逐时,可以再呆3600秒
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
# 用于描述当Pod需要被驱逐时可以在 Pod上继续保留运行的时间
tolerationSeconds: 3600 # 容忍key1-value1:NoExecute的污点
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute" # 容忍key2:NoSchedule的污点
- key:"key2"
operator: "Exists"
effect: "NoSchedule"

注意点

  1. key,value, effect要与Node上设置的 taint保持一致
  2. operator的值为Exists将会忽略value值
  3. 如不指定operator,则默认为equal
  4. tolerationSeconds用于描述当Pod需要被驱逐时可以在 Pod上继续保留运行的时间

骚操作

  1. 当不指定key值时,表示容忍所有的污点key
tolerations:
- operator: "Exists"
  1. 当不指定effect时,表示容忍所有的污点作用
tolerations:
- key: "key"
operator: "Exists"
  1. 有多个Master存在时,防止资源浪费,可以如下设置
kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule

5. 指定调度节点

通过指定Pod.spec.nodeName将Pod直接调度到指定的Node节点上

  • 会跳过Scheduler的调度策略
  • 该匹配规则是强制匹配
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myweb
spec:
replicas: 7
template:
metadata:
labels:
app: myweb
spec:
# 直接指定node名称
nodeName: k8s-node01
containers:
- name: myweb
image: lzw5399/tocgenerator
ports:
- containerPort: 80

kubernetes系列(十五) - 集群调度的更多相关文章

  1. 二进制方式部署Kubernetes 1.6.0集群(开启TLS)

    本节内容: Kubernetes简介 环境信息 创建TLS加密通信的证书和密钥 下载和配置 kubectl(kubecontrol) 命令行工具 创建 kubeconfig 文件 创建高可用 etcd ...

  2. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  3. dubbo源码解析五 --- 集群容错架构设计与原理分析

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...

  4. k8s学习-集群调度

    4.7.集群调度 4.7.1.说明 简介 Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: 公平:如何保 ...

  5. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  6. (1)quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...

  7. 使用Kubeadm搭建Kubernetes(1.12.2)集群

    Kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,在2018年将进入GA状态,说明离生产环境中使用的距离越来 ...

  8. 利用ansible来做kubernetes 1.10.3集群高可用的一键部署

    请读者务必保持环境一致 安装过程中需要下载所需系统包,请务必使所有节点连上互联网. 本次安装的集群节点信息 实验环境:VMware的虚拟机 IP地址 主机名 CPU 内存 192.168.77.133 ...

  9. 二十六. 集群及LVS简介 LVS-NAT集群 LVS-DR集群

    方案:安装ipvsadm软件包,关于ipvsadm的用法可以参考man ipvsadm资料. 常用ipvsadm命令语法格式如表-1及表-2所示. 1.ipvsadm命令用法(proxy) 1.1 创 ...

随机推荐

  1. Nice Jquery Validator 快速上手

    (1).直接引用 一行代码引入插件,local 参数用来加载对应的配置文件.如果不传 local 参数,配置以及样式就需要自行引入. <script src="path/to/nice ...

  2. Java——八种基本数据类型(常用类)

    装箱和拆箱 装箱:基本数据类型转为包装类 拆箱:包装类转为基本数据类型 jdk1.5(即jdk5.0)之后的版本都提供了自动装箱和自动拆箱功能 基本数据类型的包装类 举两个例子,看一下 public ...

  3. 【JMeter_21】JMeter逻辑控制器__模块控制器<Module Controller>

    模块控制器<Module Controller> 业务逻辑: 可以理解为引用.调用的意思,执行内容为Module To Run种所选的内容,引用范围为当前测试计划内的测试片段.逻辑控制器& ...

  4. 05.DRF-Django REST framework 简介

    一.明确REST接口开发的核心任务 分析一下上节的案例,可以发现,在开发REST API接口时,视图中做的最主要有三件事: 将请求的数据(如JSON格式)转换为模型类对象 操作数据库 将模型类对象转换 ...

  5. 我们是如何做go语言系统测试覆盖率收集的?

    工程效能领域,测试覆盖率度量总是绕不开的话题,我们也不例外.在七牛云,我们主要使用go语言构建云服务,在考虑系统测试覆盖率时,最早也是通过围绕原生go test -c -cover的能力来构建.这个方 ...

  6. Idea 快捷生成类注释与方法注释

    这篇博客应该在刚使用IDEA 的时候就写了.  但是一直忘了.  今天使用新的api 接口文档生成工具 JApiDocs  的时候,看其上面有编码规范, 注释规范. 就想起了IDEA 类中, 方法中快 ...

  7. 3.尚硅谷_MyBatis_HelloWorld.avi

    CREATE TABLE `tbl_employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `last_name` varchar(255) DEFAULT ...

  8. 你的 IDEA 是如何配置的?卡不卡?试试这样配置

    本文作者在和同事的一次讨论中发现,对 IntelliJ IDEA 内存采用不同的设置方案,会对 IDE 的速度和响应能力产生不同的影响. Don't be a Scrooge and give you ...

  9. MarkDown编辑器的区别对比

    标题: MarkDown编辑器的区别对比 作者: 梦幻之心星 sky-seeker@qq.com 标签: [MarkDown, 编辑器,区别] 目录: [软件] 日期: 2020-6-22 前提说明 ...

  10. 腾讯IEG--2020春招实习

    笔试 正常批就五道编程题,可以跳出使用本地IDE,题目很好理解,基本都能写出来,但是要过全部用例不容易.具体题目和题解可以看看这位大佬的牛客帖子,我的就不献丑了,有两题都只过了40%,我当时是用C#做 ...