kubernetes系列(十五) - 集群调度
1. 集群调度简介
Scheduler是kubernetes中的调度器组件,主要的任务是把定义的pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
- 公平: 如何保证每个节点都能被分配
- 资源资源高效利用: 集群所有资源最大化被使用
- 效率: 调度的性能要好,能够尽快地对大批量的pod完成调度工作
- 灵活: 允许用户根据自己的需求控制调度的逻辑
Sheduler是作为单独的程序运行的(如果是kubeadm则是以pod形式运行的),启动之后会一直和APIServer持续连接,获取PodSpec.NodeName为空的pod,对每个pod都会创建一个binding,表明该 pod 应该放到哪个节点上
这里的
PodSpec.NodeName不为空的pod,说明我们手动指定了这个pod应该部署在哪个node上,所以这种情况Sheduler就不需要参与进来了
2. 调度过程
2.1 调度过程概览
调度过程分为两部分,如果中间任何一步骤有错误,直接返回错误:
predicate(预选): 首先是过滤掉不满足条件的节点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亲和性简介
简单来理解就是,指定调度到的node,nodeAffinity又分为两种:
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。
Taint和toleration相互配合,可以用来避免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的设置、查看和去除
- 设置污点
# value不为空的格式
kubectl taint nodes node1 key1=value1:NoSchedule
# value为空的格式
kubectl taint nodes node1 key1:NoExecute
- 污点的查看
# 通过describe node查看Taints属性
kubectl describe node nodename

- 污点的去除
- 通过describe查看污点,然后把污点复制出来,按照如下格式在最后加一个
-就好了
- 通过describe查看污点,然后把污点复制出来,按照如下格式在最后加一个
# 去除如上截图的一个污点
kubectl taint nodes node1 haha-233:NoSchedule-
4.3 Toleration(容忍)
4.3.1 Toleration简介
设置了污点的Node将根据taint的effect:NoSchedule、PreferNoSchedule、NoExecute 和 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"
注意点
key,value,effect要与Node上设置的 taint保持一致operator的值为Exists将会忽略value值- 如不指定
operator,则默认为equal tolerationSeconds用于描述当Pod需要被驱逐时可以在 Pod上继续保留运行的时间
骚操作
- 当不指定key值时,表示容忍所有的污点key
tolerations:
- operator: "Exists"
- 当不指定
effect时,表示容忍所有的污点作用
tolerations:
- key: "key"
operator: "Exists"
- 有多个
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系列(十五) - 集群调度的更多相关文章
- 二进制方式部署Kubernetes 1.6.0集群(开启TLS)
本节内容: Kubernetes简介 环境信息 创建TLS加密通信的证书和密钥 下载和配置 kubectl(kubecontrol) 命令行工具 创建 kubeconfig 文件 创建高可用 etcd ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- dubbo源码解析五 --- 集群容错架构设计与原理分析
欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...
- k8s学习-集群调度
4.7.集群调度 4.7.1.说明 简介 Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: 公平:如何保 ...
- quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- (1)quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...
- 使用Kubeadm搭建Kubernetes(1.12.2)集群
Kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,在2018年将进入GA状态,说明离生产环境中使用的距离越来 ...
- 利用ansible来做kubernetes 1.10.3集群高可用的一键部署
请读者务必保持环境一致 安装过程中需要下载所需系统包,请务必使所有节点连上互联网. 本次安装的集群节点信息 实验环境:VMware的虚拟机 IP地址 主机名 CPU 内存 192.168.77.133 ...
- 二十六. 集群及LVS简介 LVS-NAT集群 LVS-DR集群
方案:安装ipvsadm软件包,关于ipvsadm的用法可以参考man ipvsadm资料. 常用ipvsadm命令语法格式如表-1及表-2所示. 1.ipvsadm命令用法(proxy) 1.1 创 ...
随机推荐
- const修饰this指针的用法
#include <iostream> #include <string> using namespace std; class Base { }; class Excepti ...
- while or if
多线程 wait && notifyAll 模式实现时,如果 锁中有判断,对共享对象有curd 操作时,有可能出现异常 即,判断 条件 这个时候关键字有 if 改为while 即可 ...
- Java 多线程基础(五)线程同步
Java 多线程基础(五)线程同步 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题. 要解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制 ...
- uni-app热更新
开发工具HbuilderX开发框架 uni-app.h5+1.生成 App 资源升级包1.1.修改版本号1.2.首先,更新 manifest.json 中的版本号.比如之前是 1.0.0,那么新版本应 ...
- MSCHART控件中长字符的X轴坐标标注全部显示
X轴坐标如果超过9位的话,就不能完全显示了,就会一个隔一个的显示,解决的办法: Chart1.ChartAreas[].AxisX.Interval = ; //设置X轴坐标的间隔为1 Chart1. ...
- Jenkins登录无效
解决办法: 进入Jenkins安装目录: 1:进入D:\jenkins\users\admin 这个目录下找到config.xml 可以看到里面的用户名是admin 2:进入D:\jenkins\s ...
- jmeter组件中 测试计划,线程组,sampler等等
[测试计划] 这边用户定义的变量,定义整个测试中使用的重复值(全局变量),一般定义服务器的ip,端口号 [线程组] 关于,线程组,我简单聊聊,有不对的地方欢迎大家拨乱反正 线程数:你需要运行的线程 比 ...
- Java二次复习笔记(1)
Java二次复习笔记(1) Java采用的默认字符编码集是Unicode. byte=byte+byte报错,值为int,而byte+=byte不报错.同样short = short+short报错, ...
- 多语言工作者の十日冲刺<8/10>
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 团队进行Alpha冲刺--第八天(05.07) 作业正文 ...
- Python学习之准备工作
Python学习之准备工作 编程语言历史 在计算机硬件基础中我们大概介绍了一下计算机的发展历史.了解到在曾经有一段时期里计算机是不存在操作系统这一概念的,所有需要计算机完成的操作都需要当时的程序员来与 ...