Kubernetes 年度关键进展回顾


【编者的话】2017年已经接近尾声,Kubernetes保持者每季度一个大版本的节奏快速发展,1.6至1.9版本共计完成了近150项特新更新,在集群规模、调度能力、可扩展性、安全性等方面都有明显提升。以下,笔者将带你回顾社区的几项关键技术进展。

回顾

集群规模: 3000节点 -> 5000节点

在Kubernetes 1.6版本中,单集群的规模终于达到5千节点15万Pod的水平,而出于诸多因素的影响及考虑,社区没有急于在数值上继续突破。实际上5千节点的规模,已经可以满足大部分的使用场景,毕竟这还只是纯软件优化下的性能,并没有使用过多的优化手段。要知道在规模过大的集群中,整体的状态监控、升级等维护工作都会变得十分复杂,Kubernetes的规模上去了,周边系统却未必跟得上。而在现有能力的基础上,最简单地,用户可以通过Kubernetes直接管理物理节点的方式来达到强悍的单集群性能,或者使用多集群联邦将整个数据中心铺满Kubernetes。

网络方面,得益于kube-proxy IPVS mode的引入,Kubernetes对Service的管理规模从原来的千级别提升到了万级别,大幅提升了Kubernetes在大规模场景下对Service的操作响应速度。

调度能力大增强

亲和/反亲和性调度特性的整体成熟度孵化到Beta,节点亲和性(nodeAffinity)是nodeselector的进阶,支持用in,not in等运算符来指定Pod调度到或者避开一类节点;而Pod间亲和性(podAffinity)则是为了复杂应用的调度需求而引入的高级特性,通过labelselector过滤出目标Pod之后,再借助topologyKey对Node按label进行动态分组,从而决定Pod是否要和目标Pod部署在同一组Node中。值得强调的是,Affinity相关定义已被移到Podspec中,用户终于不必在annotation嵌入JSON字符串来定义亲和性规则,而早期版本中的算法性能问题也在后续的优化中得到了良好的解决,并且Beta之后的API基本不会再有改动,大家可以放心使用。

同样是孵化到Beta的调度特性,taints tolerations的定义也分别被移到了NodeSpec和PodSpec中,在此期间,toleration还引入了超时时间定义(tolerationSeconds),用于细粒度控制节点故障时Pod的迁移触发时间。过去,当集群中某一节点发生故障时,node controller会在全局统一的超时时间后驱逐节点上所有的Pod;而在基于taints tolerations的驱逐模式下,每个Pod都可以独立设置超时时间,甚至可以指定节点故障后不迁移。

作为提高集群资源利用率的杀手级特性,Pod优先级与抢占终于在1.8版本被引入实现,并在1.9版本中进行了初步的修补和改进,但目前仍是alpha,可以考虑在非生产环境开启试用。在1.8之前,Kubernetes已经通过Pod QoS方式实现了节点及的“优先级”——节点内存不足时,OS内核会根据kubelet预制的OOM参数杀掉低QoS的pod,从而保证重要的Pod可以持续运行。Pod优先级与抢占的实现则是将这种资源分配动态可调的能力扩大到了集群级别——当集群资源不足而存在高优先级的pod需要调度时,调度器可以在整个集群内找到合适的pod进行驱逐释放资源,来保证高优先级的pod可被调度运行。

存储增强

自动化配置,优化使用体验:StorageClass和动态存储分配已经GA,内置的默认配置大大简化了存储卷的生命周期管理,大大减轻了集群管理员的压力,也让应用开发者能有更多的精力关注自身应用的开发和维护。

原生供丰富的存储类型,并支持通过插件扩展自定义存储:Kubenretes内置支持的存储类型目前已经超过20种。此外用户还可以基于flexVolume、CSI框架对接自有存储。FlexVolume目前已经GA,是扩展k8s存储能力的首选方式。CSI则是1.9版本新引入的alpha版本,未来更深度的存储框架能力将基于CSI实现,值得长期关注。

安全性增强

Kubernetes这一年中在安全性上的增强可谓是进展巨大:1.6版本引入的RBAC(基于角色的访问控制)目前已经GA,并且支持动态角色权限配置,大幅简化了权限管理。Secret等资源如今可以被加密,并且支持对接外部KMS系统来保存加密密钥。引入高级审计日志功能,支持对特定资源及其子资源的过滤输出。kubelet证书支持自动动态刷新,大大减少了节点维护的工作量。

展望

集群部署与生命周期管理

Kubernetes的部署一直是个饱受诟病的话题,业界充斥了各种各样的集群部署项目,功能实现大不相同,多数人甚至不知道该选择哪一个。Kubeadm作为亲儿子,很大程度上解决了Kubernetes组件安装的易用性问题。截止1.9版本,除了最基本的组件安装配置之外,kubeadm还提供了自举模式,集群升级,安装进度查询控制,健康检查,kubelet动态配置等高级功能。目前业界的部署方案中,kubeadm已经成为作为节点安装工具的首选。

然而Kubernetes依赖的基础设施创建、状态管理、集群升级进度管控等,仍然缺少统一权威的方案。Cluster API的提出正是为了解决这些问题:按照Kubernetes的风格定义声明式的基础设施API,给出环境无关的集群状态定义,针对环境相关的集群状态给出通用的表述机制。其好处显而易见:1)用户可以使用一致的yaml文件定义并创建Kubernetes集群,2)通过声明式的API定义Kubernetes控制面及kubelet升级过程,3)使用声明式的API操作节点OS镜像升级,4)在不同集群、云平台上获得一致的维护体验,5)Kubernetes在云平台之前接入、迁移、释放变得更简单。

打破烟囱,更好的可扩展性,更合理的项目结构

由于借鉴了Google在Borg和Omega设计实践中的大量经验,Kubernetes天生拥有十分易于扩展的松耦合架构。而实际上,对于早些版本的Kubernetes的要实现低成本的改造确并不轻松。比如第三方的云平台Cloud Provider集成,第三方存储引擎对接,定制底层硬件设备等等往往无法避免侵入式的修改。而在Kubernetes处于快速生长期,项目代码频繁重构,下游的私有patch往往维护十分困难。

经过2017这一整年的发展,我们可以欣喜地看到社区在可扩展性上作出的诸多改进:针对自定义API,TPR的进阶版本CRD拥有更强的功能,在此之上,用户还可以通过API Aggregator来实现高度定制的API;CRI的持续完善能够更好地支持可插拔的容器运行时;Device Plugin框架的引入降低了GPU、FPGA等特性实现的侵入性;FlexVolume的GA和CSI的引入为扩展存储提供了极大的便利。

项目结构方面,单仓库的模式很好地支持k8s前期的快速发展,而随着项目的发展,合理的代码库拆分更有利于有针对性地维护不同成熟度的代码,优化他们的依赖关系、测试构建、发布节奏等。在2017的几个版本开发期间,社区完成了client-go,API,apimachinery等仓库的拆分,federation也在1.9期间成为了独立子项目,目前进行中的还有kubectl,相信在未来的一年里,社区会持续优化其项目结构,打破烟囱,更好地适应项目发展需要。

0 个评论

要回复文章请先登录注册