有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
本文向您介绍如何使用原生节点专用调度器。

安装原生节点专用调度器

2. 在左侧选择 TKE Insight > Node Map
3. Node Map 页面中,鼠标悬浮到页面下方某一个 Node 上,单击详情
4. 在该 Node 的详情页的右上角,打开“原生节点专用调度器”开关。


注意
该能力为全局能力,即一个集群只需要开启一次即可,其他节点详情页里的开关会同步开启/关闭。该组件仅针对 原生节点 生效,若原生节点资源不足,容易引发 Pod Pending。

使用原生节点专用调度器

设置节点放大系数和水位线

2. 在左侧选择 TKE Insight > Node Map
3. Node Map 页面中,鼠标悬浮到页面下方某一个需要进行节点放大的原生节点上,单击详情
4. 在该原生节点的详情页的右上角,单击原生节点专用调度器右侧的编辑
5. 在原生节点专用调度器编辑页面,设置节点放大系数和水位线。如下图所示:


字段名称
描述
规格放大
虚拟放大原生节点规格,调度更多的 Pod,让当前节点装箱率突破100%。
注意:
当前节点规格放大系数仅会虚拟放大当前 原生节点 的规格,该功能有一定的风险:若节点上调度过多的 Pod,且 Pod 真正使用的总资源量大于节点规格,会引发 Pod 的驱逐和重新调度。

节点 CPU 放大系数
支持输入1~3之间的数字,保留小数点后一位。
节点内存放大系数
支持输入1~2之间的数字,保留小数点后一位。
调度时水位控制
设定当前原生节点目标资源利用率,保障稳定性。Pod 调度时,高于该水位的节点将不被选中。

调度时水位同时默认作为:
1. 驱逐停止水位线:节点利用率在达到运行时水位,发生驱逐后,驱逐到的目标水位线。 例如: 运行时水位为80,调度时水位为60,则节点利用率达到80后,开始驱逐,会按照可驱逐的 Pod 利用率高低,依次驱逐,直到水位线到60以下。
2. 低负载节点水位线:节点利用率在达到运行时水位,发生驱逐时,需要判断是否至少有三个原生节点的利用率低于这几个节点上的调度时水位线。 例如:有5个原生节点,每个原生节点的配置都是运行时水位为80,调度时水位为60,则节点利用率达到80后,开始判断是否要驱逐,要找可以容纳 Pod 的低负载原生节点,要求至少有三个原生节点的利用率低于60。
注意:
如果不同的原生节点调度水位不一样,需要判断自己原生节点上的利用率和调度时水位。

调度时 CPU 目标利用率
支持输入0~100之间的整数。
调度时内存目标利用率
支持输入0~100之间的整数。
运行时水位控制
设定当前原生节点目标资源利用率,保障稳定性。节点运行时,高于该水位的节点可能引发驱逐,前提需要在指定工作负载上标识可驱逐的标签。
注意:
1. 默认不驱逐业务 Pod。为避免驱逐关键的 Pod,该功能默认不驱逐 Pod。对于可以驱逐的 Pod,用户需要在这些 Pod 所属 workload 上做表示,组件才会在触发水位线时做驱逐操作。例如,statefulset、deployment 等对象设置可驱逐 annotation:descheduler.alpha.kubernetes.io/evictable: 'true'
2. 需要有足够多的低负载节点才会驱逐。为保证 Pod 在驱逐后有节点可以容纳,调度器在驱逐时要求至少有三个原生节点的利用率低于这几个节点上的调度时水位线。因此,如果集群中存在很多原生节点,但是开启水位线的原生节点数量小于三个,或者低于调度时水位线的原生节点少于三个,则驱逐无法执行。

运行时 CPU 目标利用率
支持输入0~100之间的整数。注意:运行时 CPU 目标利用率要大于调度时 CPU 目标利用率。
运行时内存目标利用率
支持输入0~100之间的整数。注意:运行时内存目标利用率要大于调度时内存目标利用率。

设置指定命名空间的 Pod 调度至原生节点

除了设置当前原生节点上放大系数和水位控制参数之外,原生节点专用调度器还支持设置指定命名空间下的 Pod 调度到原生节点上,帮助用户自动化迁移 Pod,充分利用原生节点的优势。操作步骤如下:
1. 登录 容器服务控制台,选择左侧导航栏中的集群
2. 集群管理页面,单击目标集群 ID,进入集群详情页。
3. 选择组件管理,在组件列表页面中选择 “cranescheduler(原生节点专用调度器)”,单击更新配置
4. 选择命名空间。指定命名空间下的 Pod 只能调度到原生节点上,若 原生节点 资源不足,会引发 Pod Pending。

节点规格放大能力说明

若指定了节点的 CPU 和内存的放大系数,您可以查看原生节点上和放大系数相关的 Annotation:expansion.scheduling.crane.io/cpuexpansion.scheduling.crane.io/memory,示例如下:
kubectl describe node 10.8.22.108

...
Annotations: expansion.scheduling.crane.io/cpu: 1.5 # CPU 放大系数
expansion.scheduling.crane.io/memory: 1.2 # 内存放大系数
...
Allocatable:
cpu: 1930m # 该节点原始可调度资源量
ephemeral-storage: 47498714648
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 1333120Ki
pods: 253
...
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 960m (49%) 8100m (419%) # 该节点 Request 和 Limit 占用量
memory 644465536 (47%) 7791050368 (570%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-1Gi 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
...
说明:
当前节点原始 CPU 可调度量:1930m
节点上所有 Pod 的总 CPU Request 申请量:960m
正常情况下,该节点只能最多调度 1930m-960m=970m CPU
但实际上该节点 CPU 的可调度量已经被虚拟放大成:1930m*1.5=2895m;实际剩余 CPU 可调度资源为:2895-960 =1935m
此时,创建一个工作负载,只有一个 Pod,CPU 申请量为 1500m,如果没有节点放大的能力,则无法调度到该节点。
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: test-scheduler
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector: # 指定节点调度
kubernetes.io/hostname: 10.8.20.108 # 指定使用样例中的原生节点
containers:
- name: nginx
image: nginx:1.14.2
resources:
requests:
cpu: 1500m # 申请量大于放大之前的节点可调度量,但有小于放大之后的节点可调度量
ports:
- containerPort: 80
该工作负载创建成功:
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
test-scheduler 1/1 1 1 2m32s

再次检查节点的资源占用情况:
kubectl describe node 10.8.22.108

...
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 2460m (127%) 8100m (419%) # 该节点 Request 和 Limit 占用量。可以看到,Request 总和超过了节点原始可调度量,节点规格放大成功。
memory 644465536 (47%) 7791050368 (570%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-1Gi 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)

自定义设置节点放大系数和水位线

注意
自定义设置节点放大系数和水位线十分灵活,可以选择一个节点或节点池、一批节点或节点池、甚至整个集群配置相同的节点规格放大系数、水位线。 您可以创建多个配置文件作用到不同的节点上。若一个节点被多个配置文件声明,且不同的文件声明的参数不一样,会导致异常问题。
除控制台的操作外,原生节点专用调度器的参数配置也支持通过 YAML 配置,每个配置文件保存在名为 clusternoderesourcepolicies 的资源对象里,您可以直接创建该类型的资源对象:
apiVersion: scheduling.crane.io/v1alpha1
kind: ClusterNodeResourcePolicy
metadata:
name: housekeeper-policy-np-88888888-55555 # name 不能重名
spec:
applyMode: annotation # 默认值,暂不支持其它数值
nodeSelector: # 用来选取一组相同配置的节点,比如下面是用来选取一个原生节点,它的 ID 是 np-88888888-55555。也可以使用一批节点共有的标签,实现批量节点的选择。
matchLabels:
cloud.tencent.com/node-instance-id: np-88888888-55555
template:
spec:
# evictLoadThreshold 是原生节点运行时水位控制,设定当前这批原生节点驱逐资源利用率,保障稳定性。Pod 在原生节点上运行时,高于该水位的原生节点可能发生驱逐。为避免驱逐关键的 Pod,该功能默认不驱逐 Pod。对于可以驱逐的 Pod,用户需要显示给判断 Pod 所属 workload。例如,statefulset、deployment 等对象设置可驱逐 annotation:descheduler.alpha.kubernetes.io/evictable: 'true'。
# evictLoadThreshold 要大于 targetLoadThreshold,否则驱逐后,节点可能持续被调度新的 Pod 导致抖动
evictLoadThreshold:
percents:
cpu: 80
memory: 80
resourceExpansionStrategyType: static # 默认值,暂不支持其它数值
staticResourceExpansion:
ratios: # 节点规格放大系数,设定当前这批原生节点的放大系数
cpu: "3" # 节点 CPU 的放大系数。建议不要设置得过大,否则可能有稳定风险,控制台限制最大数值为3
memory: "2" # 节点内存的放大系数。建议不要设置得过大,否则可能有稳定风险,控制台限制最大数值为2
# targetLoadThreshold 是原生节点调度时水位控制,设定当前这批原生节点目标资源利用率,保障稳定性。Pod 调度时,高于该水位的原生节点将不被选中。
# targetLoadThreshold 要小于 evictLoadThreshold,否则驱逐后,节点可能持续被调度新的 Pod 导致抖动
targetLoadThreshold:
percents:
cpu: 70
memory: 70
您可以修改或者创建该类型的资源对象。如下图所示,您可以在控制台上查看存量的 clusternoderesourcepolicies。
1. 登录容器服务控制台,选择左侧导航栏中的 集群
2. 单击需要查看原生节点专用调度器的集群 ID,进入资源对象浏览器页面。在左上角的方框里搜索 clusternoderesourcepolicies,如下图所示:

如果您是通过控制台页面给原生节点配置的调度参数。这些文件的名字的命名方式为:housekeeper-policy-np-88888888-55555,其中 np-88888888 为该原生节点的节点池ID,np-88888888-55555 为该原生节点的节点 ID。

自定义驱逐停止水位线

上文中提到,当前调度时的水位还有两个额外功能:驱逐停止水位线,低负载节点水位线。但是因为这样的设计,导致了功能绑定的问题,例如:
1. 如果用户想在业务驱逐时,尽量少驱逐一些 Pod,这样就需要调大调度时水位。调大调度时水位会导致节点上调度更多的 Pod,驱逐的概率提升;而又因为驱逐的 Pod 数量变少了,因此节点可能会发生频繁的调度和驱逐,节点不稳定性增加。
2. 如果用户想在业务驱逐时,尽量多驱逐一些 Pod,这样就需要调小调度时水位。调小调度时水位会导致节点上调度更少的 Pod,驱逐的概率降低;而又因为驱逐的 Pod 数量变多了,因此节点可能利用率急剧变化,节点不稳定性也会增加。且因为调度时水位较低,因此利用率无法提升,资源浪费明显。
因此,在新的 Crane Scheduler 中,TKE 推出了第三条水位线:驱逐停止水位线。驱逐停止水位线就包含了调度时的水位的两个额外功能:驱逐停止水位线,低负载节点水位线。



注意:
该功能要求 Crane Scheduler 至少在 1.1.10 版本以上,可参考 文档 查看版本和升级。
apiVersion: scheduling.crane.io/v1alpha1
kind: ClusterNodeResourcePolicy
metadata:
name: housekeeper-policy-np-88888888-55555 # name 不能重名
spec:
applyMode: annotation # 默认值,暂不支持其它数值
nodeSelector: # 用来选取一组相同配置的节点,比如下面是用来选取一个原生节点,它的 ID 是 np-88888888-55555。也可以使用一批节点共有的标签,实现批量节点的选择。
matchLabels:
cloud.tencent.com/node-instance-id: np-88888888-55555
template:
spec:
# evictLoadThreshold 是原生节点运行时水位控制,设定当前这批原生节点驱逐资源利用率,保障稳定性。Pod 在原生节点上运行时,高于该水位的原生节点可能发生驱逐。为避免驱逐关键的 Pod,该功能默认不驱逐 Pod。对于可以驱逐的 Pod,用户需要显示给判断 Pod 所属 workload。例如,statefulset、deployment 等对象设置可驱逐 annotation:descheduler.alpha.kubernetes.io/evictable: 'true'。
# evictLoadThreshold 要大于 targetLoadThreshold,否则驱逐后,节点可能持续被调度新的 Pod 导致抖动
evictLoadThreshold:
percents:
cpu: 80
memory: 80
##################
## 驱逐停止水位线 ##
# 数值要低于运行时水位 evictLoadThreshold
evictTargetLoadThreshold:
percents:
cpu: 75
  memory: 75
resourceExpansionStrategyType: static # 默认值,暂不支持其它数值
staticResourceExpansion:
ratios: # 节点规格放大系数,设定当前这批原生节点的放大系数
cpu: "3" # 节点 CPU 的放大系数。建议不要设置得过大,否则可能有稳定风险,控制台限制最大数值为3
memory: "2" # 节点内存的放大系数。建议不要设置得过大,否则可能有稳定风险,控制台限制最大数值为2
# targetLoadThreshold 是原生节点调度时水位控制,设定当前这批原生节点目标资源利用率,保障稳定性。Pod 调度时,高于该水位的原生节点将不被选中。
# targetLoadThreshold 要小于 evictLoadThreshold,否则驱逐后,节点可能持续被调度新的 Pod 导致抖动
targetLoadThreshold:
percents:
cpu: 70
memory: 70