引言
在 K8s 集群经营过程中,经常会被节点 CPU 和内存的高使用率所困扰,既影响了节点上 Pod 的稳固运行,也会减少节点故障的几率。为了应答集群节点高负载的问题,均衡各个节点之间的资源使用率,应该基于节点的理论资源利用率监控信息,从以下两个策略动手:
- 在 Pod 调度阶段,该当优先将 Pod 调度到资源利用率低的节点上运行,不调度到资源利用率曾经很高的节点上
- 在监控到节点资源率较高时,能够主动干涉,迁徙节点上的一些 Pod 到利用率低的节点上
为此,咱们提供 动静调度器 + Descheduler 的计划来实现,目前在私有云 TKE 集群内【组件治理】-【调度】分类下曾经提供这两个插件的装置入口,文末还针对具体的客户案例提供了最佳实际的例子。
动静调度器
原生的 Kubernetes 调度器有一些很好的调度策略用来应答节点资源分配不均的问题,比方 BalancedResourceAllocation,然而存在一个问题是这样的资源分配是动态的,不能代表资源实在应用状况,节点的 CPU/ 内存利用率 常常处于不平衡的状态。所以,须要有一种策略能够基于节点的理论资源利用率进行调度。动静调度器所做的就是这样的工作。
技术原理
原生 K8s 调度器提供了 scheduler extender 机制来提供调度扩大的能力。相比批改原生 scheduler 代码增加策略,或者实现一个自定义的调度器,应用 scheduler extender 的形式侵入性更少,实现更加灵便。所以咱们抉择基于 scheduler extender 的形式来增加基于节点的理论资源利用率进行调度的策略。
scheduler extender 能够在原生调度器的预选和优选阶段退出自定义的逻辑,提供和原生调度器外部策略同样的成果。
架构
- node-annotator:负责拉取 Prometheus 中的监控数据,定期同步到 Node 的 annotation 外面,同时负责其余逻辑,如动静调度器调度有效性掂量指标,避免调度热点等逻辑。
- dynamic-scheduler:负责 scheduler extender 的优选和预选接口逻辑实现,在预选阶段过滤掉资源利用率高于阈值的节点,在优选阶段优先选择资源利用率低的节点进行调度。
实现细节
- 动静调度器的策略在优选阶段的权重如何配置?
原生调度器的调度策略在优选阶段有一个权重配置,每个策略的评分乘以权重失去该策略的总得分。对权重越高的策略,符合条件的节点越容易调度上。默认所有策略配置权重为 1,为了晋升动静调度器策略的成果,咱们把动静调度器优选策略的权重设置为 2。
- 动静调度器如何避免调度热点?
在集群中,如果呈现一个新增的节点,为了避免新增的节点调度上过多的节点,咱们会通过监听调度器调度胜利事件,获取调度后果,标记每个节点过来一段时间的调度 Pod 数, 比方 1min、5min、30min 内的调度 Pod 数量,掂量节点的热点值而后弥补到节点的优选评分中。
产品能力
组件依赖
组件依赖较少,仅依赖根底的节点监控组件 node-exporter 和 Prometheus。Prometheus 反对托管和自建两种形式,应用托管形式能够一键装置动静调度器,而应用自建 Prometheus 也提供了监控指标配置办法。
组件配置
调度策略目前能够基于 CPU 和内存两种资源利用率。
预选阶段
配置节点 5 分钟内 CPU 利用率、1 小时内最大 CPU 利用率,5 分钟内均匀内存利用率,1 小时内最大内存利用率的阈值,超过了就会在预选阶段过滤节点。
优选阶段
动静调度器优选阶段的评分依据截图中 6 个指标综合评分得出,6 个指标各自的权重示意优选时更侧重于哪个指标的值,应用 1h 和 1d 内最大利用率的意义是要记录节点 1h 和 1d 内的利用率峰值,因为有的业务 Pod 的峰值周期可能是依照小时或者天,防止调度新的 Pod 时导致在峰值工夫节点的负载进一步升高。
产品成果
为了掂量动静调度器对加强 Pod 调度到低负载节点的晋升成果,联合调度器的理论调度后果,获取所有调度到的节点在调度时刻的的 CPU/ 内存利用率当前统计以下几个指标:
- cpu_utilization_total_avg:所有调度到的节点 CPU 利用率平均值。
- memory_utilization_total_avg:所有调度到的节点内存利用率平均值。
- effective_dynamic_schedule_count:无效调度次数,当调度到节点的 CPU 利用率小于以后所有节点 CPU 利用率的中位数,咱们认为这是一次无效调度,effective_dynamic_schedule_count 加 0.5 分,对内存也是同理。
- total_schedule_count:所有调度次数,每次新的调度累加 1。
- effective_schedule_ratio:无效调度比率,即 effective_dynamic_schedule_count/total_schedule_count
上面是在同一集群中不开启动静调度和开启动静调度各自运行一周的指标变动,能够看到对于集群调度的加强成果。
指标 | 未开启动静调度 | 开启动静调度 |
---|---|---|
cpu_utilization_total_avg | 0.30 | 0.17 |
memory_utilization_total_avg | 0.28 | 0.23 |
effective_dynamic_schedule_count | 2160 | 3620 |
total_schedule_count | 7860 | 7470 |
effective_schedule_ratio | 0.273 | 0.486 |
Descheduler
现有的集群调度场景都是一次性调度,即一锤子买卖。后续呈现节点 CPU 和内存利用率过高,也无奈主动调整 Pod 的散布,除非触发节点的 eviction manager 后驱赶,或者人工干预。这样在节点 CPU/ 内存利用率高时,影响了节点上所有 Pod 的稳定性,而且负载低的节点资源还被节约。
针对此场景,借鉴 K8s 社区 Descheduler 重调度的设计思维,给出基于各节点 CPU/ 内存理论利用率进行驱赶的策略。
架构
Descheduler 从 apiserver 中获取 Node 和 Pod 信息,从 Prometheus 中获取 Node 和 Pod 监控信息,而后通过 Descheduler 的驱赶策略,驱赶 CPU/ 内存使用率高的节点上的 Pod,同时咱们增强了 Descheduler 驱赶 Pod 时的排序规定和查看规定,确保驱赶 Pod 时服务不会呈现故障。驱赶后的 Pod 通过动静调度器的调度会被调度到低水位的节点上,实现升高高水位节点故障率,晋升整体资源利用率的目标。
产品能力
产品依赖
依赖根底的节点监控组件 node-exporter 和 Prometheus。Prometheus 反对托管和自建两种形式,应用托管形式能够一键装置 Descheduler,应用自建 Prometheus 也提供了监控指标配置办法。
组件配置
Descheduler 依据用户配置的利用率阈值,超过阈值水位后开始驱赶 Pod,使节点负载尽量升高到指标利用率水位以下。
产品成果
通过 K8s 事件
通过 K8s 事件能够看到 Pod 被重调度的信息,所以能够开启集群事件长久化性能来查看 Pod 驱赶历史。
节点负载变动
在相似如下节点 CPU 使用率监控视图内,能够看到在开始驱赶之后,节点的 CPU 利用率降落。
最佳实际
集群状态
拿一个客户的集群为例,因为客户的业务大多是内存消耗型的,所以更容易呈现内存利用率很高的节点,各个节点的内存利用率也很不均匀,未应用动静调度器之前的各个节点监控是这样的:
动静调度器配置
配置预选和优选阶段的参数如下:
在预选阶段过滤掉 5 分钟内均匀内存利用率超过 60% 或者 1h 内最大内存利用率超过 70% 的节点,即 Pod 不会调度到这些这些节点上。
在优选阶段将 5 分钟均匀内存利用率权重配置为 0.8,1h 和 1d 内最大内存利用率权重配置为 0.2、0.2,而将 CPU 的指标权重都配置为 0.1。这样优选时更优先选择调度到内存利用率低的节点上。
Descheduler 配置
配置 Descheduler 的参数如下,当节点内存利用率超过 80% 这个阈值的时候,Descheduler 开始对节点上的 Pod 进行驱赶,尽量使节点内存利用率升高到目标值 60% 为止。
集群优化后状态
通过以上的配置,运行一段时间后,集群内各节点的内存利用率数据如下,能够看到集群节点的内存利用率散布曾经趋向于平衡:
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!