【编者的话】从2014年v1.0的发布宣布进入production ready状态开始,Kubernetes在社区力量的持续推动下已经相继发布了v1.1、v1.2等多个版本,v1.3也在紧锣密鼓的开发中。本次分享将关注Kubernetes项目的发展动态,探寻有哪些新加入或者即将加入的feature,使得Kubernetes项目本身的适用场景更为丰富。
@Container容器技术大会将于6月4日在上海光大会展中心国际大酒店举办,来自Rancher、携程、PPTV、蚂蚁金服、京东、浙江移动、海尔电器、唯品会、eBay、道富银行、麻袋理财、土豆网、阿里百川、腾讯游戏、数人云、点融网、华为、轻元科技、中兴通讯等公司的技术负责人将带来实践经验分享,5月7日之前购票只需438元,欢迎感兴趣的同学抢购。
2015年7月,Kubernetes发布了1.0版本,宣布其已经正式进入production-ready的状态。2016年3月中旬,Kubernetes发布了1.2.0版本。目前,Kubernetes在GitHub上的star数量超过了14000,社区的活跃程度也是远超想象。他们带来了来自生产环境的诉求,一些呼声极高的feature的加入也让Kubernetes的功能日益完善。另外,在以Google团队为核心开发者的主导下,非常多的组织与个人都加入到了Kubernetes开发者的行列,contributor已经超过了700人。
所以,无论是从使用者还是从开发者的角度而言,Kubernetes都是一个值得着手尝试的项目。有基于此,我希望能给大家带来一些当前被纳入Kubernetes开发计划或者是已经在着手进行开发的项目动态。
相信大家已经对Kubernetes的基本概念非常熟悉了,常见的术语,如pod/node/replication controller/volume等等,都不再展开说明。
今天分享的内容将分为三个部分,分别围绕pod的调度/重调度与自动扩展来展开。
Part1 Multiple Scheduler
众所周知,在Kubernetes诞生之初,其预设的服务场景基本上围绕long-running service展开,例如Web Service。现在,Kubernetes已经有了专门支持batch job的资源——Job,我们可以简单地将其理解为run to terminate的任务。提及batch job和long-running service混合部署,恐怕大家都会聚焦到调度器的调度策略上来。Kubernetes的调度框架是plugin形式的,也就是说,用户可以容易地实现定制化的调度策略。
例如,当集群中有两种优先级不同的pod(如批处理作业和实时响应程序)均在等待调度时,我们往往希望其中优先级较高的pod,即实时响应程序被优先调度。但是,如果我们只采用一个默认的default调度器,显然是不足以支撑这个需求的。包括Omega、Mesos在内的多种集群调度框架都衍生出了多个调度器同时工作的模式或者丰富的两级调度框架。有鉴于实际生产环境中对于不同调度策略乃至于调度器的需求,社区也将multi-scheduler的工作稳步推进。
我们知道,一个pod应当被一个且只被一个调度器调度到某个工作节点上,否则就会发生pod运行失败或者调度工作节点冲突等状况。所以,实现multi-scheduler的关键在于,如何将pod与其对应的scheduler match起来。
社区目前采用了
annotations
来实现这一需求。所谓annotations
,可以看作是一组非结构化的key-value对,在这里我们用到的key值为 scheduler.alpha.kubernetes.io/name
,用于为用户提供自定义使用调度器的自由。若用户没有指定该字段,则系统自动将其指派给默认的调度器进行调度。遗憾的是,这一方案还没有解决用户指定无效调度器(如拼写错误等)的问题,一旦发生这一状况,对应的pod将会一直处于
Pending
的状态。所以,在未来的工作中,可能会考虑引入一个admission controller来辅助完善annotation定义部分的工作。例如,根据pod所在的Namespace来指定annotation,标记出潜在的冲突规则(如指定了两个以上的running scheduler),reject那些可能因为typo或者用户掌握了过时的信息而被指定到一个没有work的scheduler等。Part2 Rescheduler
聊完了Multiple Scheduler,我们继续来看另一个与调度相近的话题。我们知道,Kubernetes依靠Scheduler来将pod与适宜的node进行binding,并且力图通过优化调度策略等方面的努力使得调度决策试图达到运行时最优。
然而不可忽视的是,随着时间的推移,由于种种因素的影响,如工作节点上资源变化、其他pod的创建与删除,在创建pod时做出的调度决策可能已经变得不再适用。在这种情况下,我们希望能够将pod进行重新调度,使得从pod或者从集群的宏观角度来看重新达到更优。
当然,在Kubernetes v1.2.0版本中,从一个pod被调度到某个工作节点开始,直至其生命周期结束,它都不会在节点之间发生迁移。所以重新调度这个术语,在严格意义上来说并不十分准确。社区目前将其称为重调度,是出于易于理解的需要。这里所谓的重新调度,实际上是指controller自行将某个处于运行中的pod终止,并且在其他更适合的工作节点上创建一个pod来作为它的替代,不存在热迁移。
重调度的使用场景可能比你想象到的要多得多,如:
一,将一个运行中的pod“移动”到一个与调度规则匹配程度更高的新的工作节点上,例如资源更充足的工作节点,或者更符合pod预定义的节点亲和性或反亲和性要求。
二,基于可预知的事件推断,将一个运行中的pod从旧的工作节点移除。
- 旧的工作节点即将因为运维、节点自动scale down等原因停止工作,此前应该将该节点上运行的所有pod均预先移动到其他节点。
- 将某个运行中的pod停止,从而在其释放资源的配给后,另一个Pending状态的pod能调度到当前pod工作的节点上。
- 将运行的pod移动到相对集中的一部分节点上,使得在将来出现对于资源使用量要求较高的pod时,该pod能够顺利地被调度。这个使用场景类似于文件系统中的碎片回收的工作。这个使用场景与上一个的区别在于,它是主动发生的投机行为,此时并不存在某个既定的pending的pod在等待调度。
三,运行中的pod在其依附的node上工作状态较差。
社区打算为重调度的实现引入一个专门的Rescheduler,然而毫无疑问的是,整个流程会涉及到多个系统组件协同工作,而不仅仅由Rescheduler单独完成。具体的设计方案还尚未完全敲定,在这里列出一些引起热议的问题。
- 一个pod如何描述对于系统主动终止其运行的容忍程度,而系统又将如何处理主动终止pod的实施限度。用户可能不希望系统过分干预pod的运行,即便系统声称这是出于全局的利益,甚至可能对单个pod的运行也有好处。如何定义这个界限并保证系统不越界,显然是一个重要的议题。
- 对于每个具体场景,由什么组件来具体判定重调度合适的时间点与合适的pod?重要的是各个组件能够分工明确,各司其职。
- Rescheduler需要在多大程度上了解pod的调度策略,以及Rescheduler如何描述它的重调度决策。
可能的选项是,Rescheduler仅声明移除某个pod,或者进一步加上对于新的替代pod被调度到的工作节点的偏好,更甚者Rescheduler可以明确指定重调度到的节点。 - Rescheduler是否考虑级联影响。例如,一个pod的重调度可能会导致其他pod发生重调度,造成一定面积的连锁反应。又或,Rescheduler是否考虑一次性移动多个pod。
可见,在重调度的设计这一议题上,显然还有很多复杂的问题需要权衡。我们也有理由对其实现拭目以待。
Part3 Horizontal Pod Autoscaler
自动扩展作为一个经久不衰的议题,一直为人们津津乐道。系统能够根据负载的变化对计算资源的分配进行自动的扩增或者收缩无疑是一个非常吸引人的特征。自动扩展主要分为两种,其一为Horizontal,针对于实例数目的增减;其二为vertical,即单个实例可以使用的资源的增减。horizontal pod autoscaling属于前者。
那么horizontal pod autoscaling是如何工作的呢?目前pod autoscaling的操作对象是ReplicationController、ReplicaSet或Deployment对应的pod,根据观察到的CPU实际使用量与用户的期望值进行比对,做出是否需要增减实例数量的决策。controller使用heapster来检测CPU使用量。
虽然目前horizontal pod autoscaling的决策依据仅考量了CPU的使用量,但是在将来其他的一些影响因子也可能会被纳入范畴,如内存使用量、网络流量、QPS甚至是用户自定义的metric。
Q&A
Q:谢谢分享Scheduler的演进,想问一下planning的问题,针对multiple scheduler和rescheduler,是谁在主导,有时间线吗?浙大会参与设计和开发吗?Q:这些讨论一般都集中在哪些地方?是公开的吗?
A:据我所知,目前design和implementation都是由Google主导,国内主要是华为的团队在参与开发,网易也有人力投入,当然极有可能存在一些我不知道的团队。Timeline上Multiple Scheduler已经完成了接口,但是有不少细节的工作还没有完成。Rescheduler还在design阶段。据我所知,浙大的确有感兴趣的同学在做相关的内容,但是我不确定有没有向社区贡献code的计划。
Q:Kubernetes目前表现的比较好的托管方式是容器安装吗?还有CoreOS官方给了这么多选择不知道选什么好。
A:大多数在GitHub上可以trace到,当然也有weekly sig视频会议和offline discussion。如果是个人开发者的话,可以在GitHub上的issue/pr里comment或者直接提交pr参与开发。
Q:未来horizontal pod autoscaling将不仅仅是依据CPU,还会有更多的指标。请问如何处理可能的矛盾。如CPU超载指示扩容,而memory可能使用低而指示减少容器数量?
A:definitely not。容器安装是一个快速的solution,但是可能会有很多bug。CoreOS应该是一个支撑性非常高的平台。我本人是Ubuntu平台的 maintainer之一,如果希望play with ubuntu的同学,也可以尝试一下。
Q:还是那个老问题,在企业环境下Kubernetes和Mesos哪个更可取?
A:这是一个策略问题。对应的解决方案无疑会牺牲其中一个,Kubernetes是否允许用户来指定这个priority也还值得讨论。但是就目前看来用户还不需要过分担心,毕竟它还没有实现。
Q:其实去年开年的时候玩过Kubernetes,然后是因为网络部分的限制导致选择了Mesos,想问下容器网络这部分Kubernetes你觉得最成熟的方案是哪一种?
A:如果一定用事实说话的话,当前Mesos在企业中的use case无疑比Kubernetes要多。作为一个两级调度框架,Mesos的完备性相当高。但是我个人并不认为Kubernetes就相对不适用于企业环境。毕竟在选取solution的时候,需要考量的实际因素很多。
Q:Rancher除支持自己的编排方案cattle以外,也支持Kubernetes和Docker Swarm。想听听你的建议,是否可以采用Rancher+Kubernetes这样的方案?谢谢
A:我自己只玩过Flannel(包括UDP和VXLAN),但是它在效率上可能并不是非常好,VXLAN相对来说要好一些。我所知道的方案中,Calico应该做得还不错。您也可以尝试一下OpenVSwitch。
Q:现在所有调度规则都是集中在master控制分发,Kunernetes可不可以在node上面添加像mesos role的概念?
A:非常抱歉没有使用Rancher的经历。但是就大多数我所知道的cross-platform solution而言,通常都出于生产环境中具体的需求。比如我现在实习的公司的AP组就自己写了docker-on-yarn。在solution的选取上很难脱离需求来进行评断。
以上内容根据2016年4月26日晚微信群分享内容整理。分享人何思玫,浙江大学SEL实验室研究生,Kubernetes、Docker等容器相关开源项目的代码贡献者。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesz,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。
A:调度器的演化经历了很长时间的发展,各有千秋。Kunernetes选用的单体调度器,而Mesos是两极调度框架,本质上还是有相当大的gap的。当然现在也有Kunernetes和Mesos的集成,有兴趣的同学也可以尝试一下。
有疑问加站长微信联系(非本文作者)
![](https://static.golangjob.cn/static/img/footer.png?imageView2/2/w/280)