目录
一、Kubernetes 资源管理
1、Kubernetes管理的资源所管理的集群
2、capacity资源的详细数据从哪里获取?
3、kubernetes集群中的组件
4、应用场景
5、Eciton 分为两种模式
6、Eviction触发
二、Kubernetes 调度器
1、APIserver
2、节点
1. 节点预选
2. 节点优选
三、Kubernetes 调度策略
1、预选策略(Predicates)实际上就是节点过滤器
2、优选策略
四、Kubernetes 调度优先级和抢占机制
1、Kubernetes调度优先级和抢占机制
2、Priorityclass
一、Kubernetes 资源管理
1、Kubernetes管理的资源所管理的集群
Kubernetes管理的资源所管理的集群中的每一台计算节点都包含一定的资源,通过
kubectl get node xxx -o yaml 得到节点有关资源的描述
2、capacity资源的详细数据从哪里获取?
由于capacity反映的是这台机器的资源真实数量,所以确认这个信息的任务理所应当交给运行在每台机器上面的kubelet上。
在kubelet启动后,这个内部的cadvisor子模块也会相应启动,并且获取这台机器上面的各种信息。
其中就包括了有关这台机器的资源信息,而这个信息也自然作为这台机器的真实资源信息,通过kubelet再上报给apiserver
3、kubernetes集群中的组件
1. 在kubernetes 集群中的每一个节点上,除了用户容器还会运行很多其他的重要组件,他们并不是以容器的方式来运行的,这些组件的类型主要分为两个大类:
2. 为了保证这两类组件有足够的资源运行,同时为了保证物理节点的稳定性,kubernetes引入了驱逐 eviction policy 特性
4、应用场景
1. QoS 划分的主要应用场景,
是当宿主机资源紧张的时候,kubelet 对 Pod 信息Eviction(资源回收)时需要用到的
2. 当kubernetes 所管理的不可压缩资源短缺时,就有可能触发Eviction,此类不可压缩资源包括: ①. 可用内存(memory.available)
②. 可用的宿主机磁盘(nodefs.available)等
③.
3. 在kubernetes,设置的eviction 默认阈值为:
5、Eciton 分为两种模式
1. Soft模式(软限制):
允许为某一项参数设置一个“优雅时间”,
给Pod预留退出时间,
当达到阈值之后一定时间之后,kubelet才会启动Eviction过程
2. Hard 模式(硬限制):
直接杀掉Pod
6、Eviction触发
1. 当宿主机的Eviction 阈值达到之后,就会进入 MemoryPressure 或 DiskPressure的状态,从而避免新的Pod被调度到该节点上(通过给节点打上"污点" 的方式实现)
2. 当Eviction发生的时候,kubelet具体会挑选哪些Pod进行删除操作,就要参考这些Pod的类型了:
①.首先被删除的是Besteffort类别的Pod
②.其实是Burstable类别的Pod,并且使用的某一项缺少资源超出了requests值
③.
资源量超过了limits 的限制,才会被Eviction 选中
④. 对于同类别QoS的Pod,kubernetes 会根据优先级来选择移除的顺序
二、Kubernetes 调度器
1、APIserver
API Server 在接受客户端提交Pod对象创建请求后,然后是通过调度器(kube-scheduler)从集群中选择一个可用的最佳节点来创建并运行Pod。
创建Pod对象,在调度的过程当中有3个阶段:
①. 节点预选:
预选规则对每个节点进行检查,将那些不符合条件的节点过滤, 从而完成节点的预选
②. 节点优选:
对预选出的节点进行优先级排序,以便选出最合适运行Pod对象的节点
③. 节点选定:
优先级排序结果中挑选出优先级最高的节点运行Pod,当这类节点多于1个 时,则进行随机选择
2、节点
1. 节点预选
在具体的调度流程中,默认调度器会首先调用一组叫做Predicate的算法,来检查每个Node
2. 节点优选
然后再调用一组叫做priority 的调度算法,来给上一步的到的每个Node打分最终得分最高的那个Node就是调度结果,当调度器对一个Pod调度成功,就会在它的spec.nodeName字段填写上调度结果的名字
三、Kubernetes 调度策略
1、预选策略(Predicates)实际上就是节点过滤器
例如:
预选没能选定一个合适的节点,此时Pod会一直处于pending状态,直到有一个可用节点完成调度
1. CheckNodeCondition
检查是否可以在节点报告磁盘、网络不可用或未准备好的情况下将Pod对象调度其上
2. CheckNodeLabelPresence:
仅检查节点上指定的所有标签的存在性,要检查的标签以及其可否存在于取决于用户的定义
3. PodToleratesNode:
如果Pod对象中定义了spec.tolerrations 属性,
则需要检查该属性值是否可以接纳节点定义的污点(taints)
4. CheckServiceAffinity:
根据当前Pod对象所属的Service已有其他Pod对象所运行的节点调度,
目前是将相同的Service的Pod对象放在同一个或同一类节点上
5. CheckVolumeBinding:
检查节点上已绑定和未绑定的PVC是否满足Pod对象的存储卷需求
6. PodFitsResources:
检查节点上的CPU和内存资源是否满足Pod的requests 字段
7. CheckNodeMemoryPressure:
在给定了节点已经上报了存在内存资源压力过大的状态,
则需要检查该Pod是否可以调度到该节点上
8. CheckNodeDiskPressure:
如果给定的节点存在磁盘资源压力过大,则检查该Pod对象是否可以调度到该节点上
9. MatchInterPodAffinity:
检查给定的节点能否可以满足Pod对象的亲和性和反亲和性条件,
用来实现Pod 亲和性调度或反亲和性调度
2、优选策略
1. 预选策略筛选出一个节点列表就会进入优选阶段(Priorities),在这个过程调度器会向每个通过预选的节点传递一系列的优选函数来计算其优先级分值,优先级分值介于0-10之间,其中0表示不适用,10表示最适合托管该Pod对象
2. 调度器还支持给每个优选函数指定一个简单的值,表示权重,进行节点优先级分值计算时,它首先将每个优选函数的计算得分乘以权重,然后再将所有优选函数的得分相加,从而得出节点的最终优先级分值。权重可以让管理员定义优选函数倾向性的能力
①. LeastRequested:
最低要求,(CPU((capacity-sum(requested)) 10/capacity) + memory ((capacity-sum(requested)) 10/capacity))得数越高,得分越高
②. BalanceResourceAllocation:
以CPU和内存资源占用比率相近的得分越高
③. NodePreferAvoidPods:
得分位10 权重 10000)根据节点注解信息annotations是否有
"scheduler.alpha.kubernetes.io/preferAvoidePods" 如果有 则不能运行
④. TaintToleration:
匹配度越高,得分越低
⑤. SelectorSpreading:
标签选择器分散度,查找与当前pod对象同属一个标签选择器运行的pod的节点越少的得分越高
⑥. InterPodAffinity:
在节点对Pod所需的资源等进行匹配,匹配的越多得分越高
⑦. NodeAffinity:
根据Pod中的nodeSelector对节点进行匹配都检查,匹配数量越多得分越高
⑧. MostRequested:
(CPU((capacity-sum(requested)) 10/capacity) + memory((capacity-sum(requested)) 10/capacity)), 用来替换 LeastRequestedPriority,给使用多资源的节点,更高的调度优先级,即尽量将资源利用率最大化
⑨. NodeLabel:
只要存在就得分,条数越多分数越高
⑩. ImageLocality:
体积大小之和进行判断,存在的镜像体积越大,得分越高
四、Kubernetes 调度优先级和抢占机制
1、Kubernetes调度优先级和抢占机制
1. 当一个Pod被调度失败时,它就会进入Pending状态,直到Pod被更新,或者集群状态发生变化,调度器才会对这个Pod进行重新调度。
但某些高优先级的Pod在调度失败后,并不会Pending,
而是会驱逐某个Node上一些低优先级的Pod,
这样就可以保证这个高优先级的Pod调度成功
2. 优先级(Priority)和抢占(Preemption)这两种机制
是为了解决Pod调度失败之后该如何处理的问题,而非在Pod最开始的调度阶段被触发
2、Priorityclass
1. k8s规定,优先级是一个32bit的整数,最大值不超过10 0000 0000(10亿),并且值越大优先级越高。超过10亿的,是被kubernetes保留下来分配给系统pod使用的。
目的是保证系统Pod不会被用户抢占掉
$ kubectl get priorityclasses
NAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000 false 31d
system-node-critical 2000001000 false 31d
$ kubectl describe priorityclasses system-cluster-critical
Name: system-cluster-critical
Value: 2000000000
GlobalDefault: false
PreemptionPolicy: PreemptLowerPriority
Description: Used for system critical pods that must run in the cluster, but can be moved to another node if necessary.
Annotations: <none>
Events: <none>
$ kubectl describe priorityclasses system-node-critical
Name: system-node-critical
Value: 2000001000
GlobalDefault: false
PreemptionPolicy: PreemptLowerPriority
Description: Used for system critical pods that must not be moved from their current node.
Annotations: <none>
Events: <none>
2. kubernetes中,优先级和抢占机制是在1.10 版本后才逐步可用的。要使用这个机制,首先需要在kubernetes里提交一个Priorityclass 的定义:
$ kubectl apply -f- <<EOF apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: high-priority value: 1000000 globalDefault: false EOF$ kubectl get priorityclasses.scheduling.k8s.io high-priority NAME VALUE GLOBAL-DEFAULT AGE high-priority 1000000 false 3m36s
3. globalDefault被设置成
true的话,那就意味着这个PriorityClass 的值会成为系统的默认值
false表示的是只希望声明使用该PriorityClass 的Pod拥有值为100 0000的优先级,
而对于没有声明Priority的Pod来说,优先级就是0
4. 在Pod创建过程中引用该对象
①. 指定优先级时
$ kubectl apply -f- <<EOF #指定优先级
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
EOF$ kubectl describe pods nginx | grep Priority
Priority: '1000000'
Priority Class Name: high-priority
②. 不指定优先级时
kubectl apply -f- <<EOF #不指定优先级
apiVersion: v1
kind: Pod
metadata:
name: nginx-1
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
# priorityClassName: high-priority
EOF$ kubectl describe pods nginx-1 | grep Priority
Priority: 0