邱天,腾讯云高级工程师,负责腾讯云 TKE 动态调度器与重调度器产品。
原生 kubernetes 调度器只能基于资源的 resource request 进行调度,然而 Pod 的真实资源使用率,往往与其所申请资源的 request/limit 差异很大,这直接导致了集群负载不均的问题:
集群中的部分节点,资源的真实使用率远低于 resource request,却没有被调度更多的 Pod,这造成了比较大的资源浪费;
而集群中的另外一些节点,其资源的真实使用率事实上已经过载,却无法为调度器所感知到,这极大可能影响到业务的稳定性。
这些无疑都与企业上云的最初目的相悖,为业务投入了足够的资源,却没有达到理想的效果。
既然问题的根源在于 resource request 与真实使用率之间的「鸿沟」,那为什么不能让调度器直接基于真实使用率进行调度呢?这就是 Crane-scheduler 设计的初衷。Crane-scheduler 基于集群的真实负载数据构造了一个简单却有效的模型,作用于调度过程中的 Filter 与 Score 阶段,并提供了一种灵活的调度策略配置方式,从而有效缓解了 kubernetes 集群中各种资源的负载不均问题。换句话说,Crane-scheduler 着力于调度层面,让集群资源使用最大化的同时排除了稳定性的后顾之忧,真正实现「降本增效」。

如上图所示,Crane-scheduler 依赖于 Node-exporter 与 Prometheus 两个组件,前者从节点收集负载数据,后者则对数据进行聚合。而 Crane-scheduler 本身也包含两个部分:
Scheduler-Controller 周期性地从 Prometheus 拉取各个节点的真实负载数据, 再以 Annotation 的形式标记在各个节点上;
Scheduler 则直接在从候选节点的 Annotation 读取负载信息,并基于这些负载信息在 Filter 阶段对节点进行过滤以及在 Score 阶段对节点进行打分;
基于上述架构,最终实现了基于真实负载对 Pod 进行有效调度。
下图是官方提供的 Pod 的调度上下文以及调度框架公开的扩展点:

Crane-scheduler 主要作用于图中的 Filter 与 Score 阶段,并对用户提供了一个非常开放的策略配置。这也是 Crane-Scheduler 与社区同类型的调度器最大的区别之一:
如「整体架构」中所述,Crane-scheduler 所需的负载数据均是通过 Controller 异步拉取。这种数据拉取方式:
一方面,保证了调度器本身的性能;
另一方面,有效减轻了 Prometheus 的压力,防止了业务突增时组件被打爆的情况发生。
此外,用户可以直接 Describe 节点,查看到节点的负载信息,方便问题定位:
[root@test01 ~]# kubectl describe node test01
Name: test01
...
Annotations: cpu_usage_avg_5m: 0.33142,2022-04-18T00:45:18Z
cpu_usage_max_avg_1d: 0.33495,2022-04-17T23:33:18Z
cpu_usage_max_avg_1h: 0.33295,2022-04-18T00:33:18Z
mem_usage_avg_5m: 0.03401,2022-04-18T00:45:18Z
mem_usage_max_avg_1d: 0.03461,2022-04-17T23:33:20Z
mem_usage_max_avg_1h: 0.03425,2022-04-18T00:33:18Z
node.alpha.kubernetes.io/ttl: 0
node_hot_value: 0,2022-04-18T00:45:18Z
volumes.kubernetes.io/controller-managed-attach-detach: true
...
用户可以自定义负载数据的类型与拉取周期,默认情况下,数据拉取的配置如下:
syncPolicy:
## cpu usage
- name: cpu_usage_avg_5m
period: 3m
- name: cpu_usage_max_avg_1h
period: 15m
- name: cpu_usage_max_avg_1d
period: 3h
## memory usage
- name: mem_usage_avg_5m
period: 3m
- name: mem_usage_max_avg_1h
period: 15m
- name: mem_usage_max_avg_1d
period: 3h
用户可以在 Filter 策略中配置相关指标的阈值,若候选节点的当前负载数据超过了任一所配置的指标阈值,则这个节点将会被过滤,默认配置如下:
predicate:
## cpu usage
- name: cpu_usage_avg_5m
maxLimitPecent: 0.65
- name: cpu_usage_max_avg_1h
maxLimitPecent: 0.75
## memory usage
- name: mem_usage_avg_5m
maxLimitPecent: 0.65
- name: mem_usage_max_avg_1h
maxLimitPecent: 0.75
用户可以在 Score 策略中配置相关指标的权重,候选节点的最终得分为不同指标得分的加权和,默认配置如下:
priority:
### score = sum((1 - usage) * weight) * MaxScore / sum(weight)
## cpu usage
- name: cpu_usage_avg_5m
weight: 0.2
- name: cpu_usage_max_avg_1h
weight: 0.3
- name: cpu_usage_max_avg_1d
weight: 0.5
## memory usage
- name: mem_usage_avg_5m
weight: 0.2
- name: mem_usage_max_avg_1h
weight: 0.3
- name: mem_usage_max_avg_1d
weight: 0.5
在实际生产环境中,由于 Pod 创建成功以后,其负载并不会立马上升,这就导致了一个问题:如果完全基于节点实时负载对 Pod 调度,常常会出现调度热点(短时间大量 pod 被调度到同一个节点上)。为了解决这个问题,我们设置了一个单列指标 Hot Vaule,用来评价某个节点在近段时间内被调度的频繁程度,对节点实时负载进行对冲。最终节点的 Priority 为上一小节中的 Score 减去 Hot Value。Hot Value 默认配置如下:
hotValue:
- timeRange: 5m
count: 5
- timeRange: 1m
count: 2
注:该配置表示,节点在 5 分钟内被调度 5 个 pod,或者 1 分钟内被调度 2 个 pod,HotValue 加 10 分。
Crane-scheduler 目前有众多公有云用户,包括斗鱼直播、酷狗、一汽大众、猎豹移动等公司均在使用,并给予了产品不错的反馈。这里我们先分享一个某公有云用户的真实案例。该客户集群中的业务大多是内存消耗型的,因此极易出现内存利用率很高的节点,并且各个节点的内存利用率分布也很不平均,如下图所示:

了解到用户的情况后,我们推荐其使用 Crane-scheduler,组件运行一段时间后,该用户集群内各节点的内存利用率数据分布发生了显著变化,如下图 :

可见,用户集群的内存使用率更加趋于均衡。
另外, Crane-scheduler 也在公司内部各个 BG 的自研上云环境中,也得到了广泛的使用。下面是内部自研上云平台 TKEx-CSIG 的两个生产集群的 CPU 使用率分布情况,其中集群 A 未部署 Crane-scheduler:

集群 B 部署了组件并运行过一段时间:

很明显,在集群 B 中,节点 CPU 使用率分布在两端( < 10% 与 > 80%)所占的比例,要显著小于集群 A,并且整体分布也更加紧凑,相对而言更加均衡与健康。
为推进云原生用户在确保业务稳定性的基础上做到真正的极致降本,腾讯推出了业界第一个基于云原生技术的成本优化开源项目 Crane( Cloud Resource Analytics and Economics )。Crane 遵循 FinOps 标准,旨在为云原生用户提供云成本优化一站式解决方案。
Crane-scheduler 作为 Crane 的调度插件实现了基于真实负载的调度功能,旨在从调度层面帮助业务降本增效。
近期,Crane 成功加入 CNCF Landscape,欢迎关注项目:https://github.com/gocrane/crane。
更多关于云原生的案例和知识,可关注同名【腾讯云原生】公众号~
①公众号后台回复【手册】,可获得《腾讯云原生路线图手册》&《腾讯云原生最佳实践》~
②公众号后台回复【系列】,可获得《15个系列100+篇超实用云原生原创干货合集》,包含Kubernetes 降本增效、K8s 性能优化实践、最佳实践等系列。
③公众号后台回复【白皮书】,可获得《腾讯云容器安全白皮书》&《降本之源-云原生成本管理白皮书v1.0》
④公众号后台回复【光速入门】,可获得腾讯云专家5万字精华教程,光速入门Prometheus和Grafana。
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我有一个应用程序可以读取文件的内容并为其编制索引。我将它们存储在磁盘本身中,但现在我使用的是AmazonS3,因此以下方法不再适用。事情是这样的:defperform(docId)@document=Document.find(docId)if@document.file?#Youshould'tcreateanewversion@document.versionlessdo|doc|@document.file_content=Cloudoc::Extractor.new.extract(@document.file.file)@document.saveendendend@docu
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵