K8S调度器,负责监听新创建、尚未分配到计算节点的Pod;K8S调度器最重要的职责就是为每一个Pod找到最适合其运行的计算节点。
kube-scheduler是K8S集群默认的调度器,如果你愿意,也可以自己写一个调度组件来替代kube-scheduler
,在实际应用中,kube-scheduler
也有许多不尽如人意的地方,很多大厂也或多或少的修改或开发自己的调度器。参见《美团点评Kubernetes集群管理实践》
对于新建的或是未被调度的Pod,kube-scheduler
会选择最优节点运行Pod。除此之外,每个Pod中的容器也会有其特定需求,如资源限制等;因此调度器会根据这些限制条件过滤掉不符合条件的节点。
在集群中,符合Pod调度条件的节点被称为Feasible Node
,如果没有节点符合条件,那么pod会一直停留在unscheduled
状态,直到有节点符合条件。
调度器寻找到Feasible Node
后,还要通过一组函数对这些节点进行打分,从这些节点中找出分数最高的节点作为“最适合节点”,如果最适合节点有多个的话,就需要随机选择啦。最后,调度器要将“调度结果”上报给API Server(这个过程叫做“绑定”)。
调度算法要考虑的因素有很多,包括单独的、整体的资源请求、软硬件条件、策略条件、亲和性与反亲和性、数据本地化、负载间通信等。
Step1: 筛选
Step2: 打分
Step3: 调度
kube-scheduler
的默认策略前面简单的介绍了kube-scheduler及其调度策略,下面重点介绍两个在实践中经常用掉的调度策略:我想去哪里与我能去哪里
nodeSelector
就是PodSpec的一个字段,它指定一组KV键值对,Pod要去的节点必须要有这些KV键值对。不过,在实践中,一般至指定一个键值对。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd // The Pod will get scheduled on the node that you attached the label to.
有了nodeSelector
, 为什么还要有Affinit呢?主要原因是nodeSelector
表达方式过于简单,无法清晰表述一些复杂的条件。
Affinity的主要优势有三点:
Node Affinity是基于Node Label设定调度条件。如下是NodeAffinity的例子,可以看到,调度规则采用的是In
这样范围条件,表达形式更丰富,除此之外,还有NotIn
、Exists
、DoesNotExist
、GT
、LT
。
Pod间的亲和性策略,是基于Pod Label设定的。Pod间亲和性策略,是为了让Pod之间更好系统,哪些Pod运行在同一节点会更好,哪些Pod一定要分开,避免享互影响。
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- xx, yy
topologyKey: kubernetes.io/hostname
Pod亲和性规则:Pod应当(或不应当)运行在X上,如果X上运行的Pod满足了条件Y
topologyKey
表示,它是节点label的某个Key,这个key应当是每个节点都具有的。Label Selector
,定义Pod的标签条件。污点和容忍性,是实现“你能去哪里”策略的重要概念:
污点和容忍性,就好比签证,污点节点是国家,容忍性就是有了该国的签证,没有污点的节点就是免签国家,任由你来去。
默认情况下,集群内节点是共享的,但是由于应用等级、产线事业部的重要程度不同,有些应用需要被放置在孤立的资源中,并保证这些资源不被其他应用占用,就需要实现集群内的资源隔离。污点和容忍性恰是解决资源隔离的重要手段。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。