Serverless 与容器决战在即?有了弹性伸缩就不一样了

作者 | 阿里云容器技术专家 莫源?
本文整理自莫源于 8 月 31 日?K8s & cloudnative meetup 深圳场的演讲内容。关注“阿里巴巴云原生”公众号,回复关键词 “资料” ,即可获得 2019 全年 meetup 活动 PPT 合集及 K8s 最全知识图谱。

导读:Serverless 和 Autoscaling 是近些年来广大开发者非常关心的内容。有人说 Serverless 是容器 2.0,终有一天容器会和 Serverless 进行一场决战,分出胜负。实际上,容器和 Serverless 是可以共存并且互补的,特别是在 Autoscaling 相关的场景下,Serverless 可以与容器完美兼容,弥补容器场景在使用简单、速度、成本的缺欠,在本文中将会为大家介绍容器在弹性场景下的原理、方案与挑战,以及 Serverless 是如何帮助容器解决这些问题的。

当我们在谈论"弹性伸缩"的时候

当我们在谈论"弹性伸缩"的时候,我们在谈论什么?"弹性伸缩"对于团队中不同的角色有不同的意义,而这正是弹性伸缩的魅力所在。

从一张资源曲线图讲起

这张图是阐述弹性伸缩问题时经常引用的一张图,表示的是集群的实际资源容量和应用所需容量之间的关系。

  • 其中红色的曲线表示的是应用实际所需的容量,因为应用的资源申请量相比节点而言会小很多,因此曲线相对比较平滑;
  • 而绿色的折线表示的是集群的实际资源容量,折线的拐点表明此时进行了手动的容量调整,例如增加节点或者移除节点,因为单个节点的资源容量固定且相对较大,因此以折线为主。

首先,我们先看左侧第一块橙色栅格的区域,这个区域表示集群的容量无法满足业务的容量所需,在实际的场景中,通常会伴随出现由于资源不足而无法调度的 Pod 等现象。

中间的栅格区域,集群的容量远高于实际资源所需的容量,此时会出现资源的浪费,实际的表现通常是节点的负载分配不均,部分节点上面无调度负载,而另外一些节点的负载相对较高。

右侧栅格区域表示的是激增的峰值容量,我们可以看到,到达峰值前的曲率是非常陡峭的,这种场景通常是由于流量激增、大批量任务等非常规容量规划内的场景,激增的峰值流量给运维同学的反应时间非常短,一旦处理不当就有可能引发事故。

弹性伸缩对于不同角色的人员,有着不同的意义:

  • 开发人员希望通过弹性伸缩使应用获得高可用的保障;
  • 运维人员希望通过弹性伸缩降低基础设施的管理成本;
  • 架构师希望通过弹性伸缩得到灵活弹性的架构应对突发的激增峰值。

弹性伸缩有多种不同的组件和方案,选择适合自己业务需求的方案是落地执行前的第一步。

Kubernetes 弹性伸缩能力解读

Kubernetes 弹性伸缩的相关组件

Kubernetes 弹性伸缩的组件可以从两个维度进行解读:一个是伸缩方向,一个是伸缩对象。

从伸缩方向上,分为横向与纵向。从伸缩对象上,分为节点与 Pod。那么将这个象限进行展开,就变成如下 3 类组件:

  1. cluster-autoscaler,节点水平伸缩;
  2. HPA & cluster-proportional-autoscaler,Pod 水平伸缩;
  3. vertical pod autoscaler&addon resizer,Pod 纵向伸缩。

其中 HPA 与 Cluster-Autoscaler 是开发者最常组合使用的弹性伸缩组件。HPA 负责容器的水平伸缩,Cluster-Autoscaler 负责节点的水平伸缩。很多的开发者会产生这样的疑问:为什么弹性伸缩一个功能需要细化成这么多组件分开处理,难道不可以直接设置一个阈值,就实现集群的自动水位管理吗?

Kubernetes 的弹性伸缩挑战

了解 Kubernetes 的调度方式可以帮助开发者更好的理解 Kubernetes 弹性伸缩的设计哲学。在 Kubernetes 中,调度的最小单元是一个 Pod,Pod 会根据调度策略被调度到满足条件的节点上,这些策略包括资源的匹配关系、亲和性与反亲和性等等,其中资源的匹配关系的计算是调度中的核心要素。

通常和资源相关的有如下四个概念:

  • Capacity 表示一个节点所能分配的容量总量;
  • Limit 表示一个 Pod 能够使用的资源总量;
  • Request 表示一个 Pod 在调度上占用的资源空间;
  • Used 表示一个 Pod 的真实资源使用。

在了解这四个基本概念和使用场景之后,我们再来看下 Kubernetes 弹性伸缩的三大难题:

  1. 容量规划限制
    还记得在没有使用容器前,是如何做容量规划的吗?一般会按照应用来进行机器的分配,例如,应用 A 需要 2 台 4C8G 的机器,应用 B 需要 4 台 8C16G 的机器,应用 A 的机器与应用 B 的机器是独立的,相互不干扰。到了容器的场景中,大部分的开发者无需关心底层的资源了,那么这个时候容量规划哪里去了呢?

在 Kubernetes 中是通过?Request?和?Limit?的方式进行设置,Request?表示资源的申请值,Limit?表示资源的限制值。既然?Request?和?Limit?才是容量规划的对等概念,那么这就代表着资源的实际计算规则要根据?Request?和?Limit?才更加准确。而对于每个节点预留资源阈值而言,很有可能会造成小节点的预留无法满足调度,大节点的预留又调度不完的场景。

  1. 百分比碎片陷阱
    在一个 Kubernetes 集群中,通常不只包含一种规格的机器。针对不同的场景、不同的需求,机器的配置、容量可能会有非常大的差异,那么集群伸缩时的百分比就具备非常大的迷惑性。

假设我们的集群中存在 4C8G 的机器与 16C32G 两种不同规格的机器,对于 10% 的资源预留而言,这两种规格是所代表的意义是完全不同的。特别是在缩容的场景下,通常为了保证缩容后的集群不处在震荡状态,我们会一个节点一个节点来缩容节点,那么如何根据百分比来判断当前节点是处在缩容状态就尤为重要。此时如果大规格机器有较低的利用率被判断缩容,那么很有可能会造成节点缩容后,容器重新调度后的争抢饥饿。如果添加判断条件,优先缩容小配置的节点,则有可能造成缩容后资源的大量冗余,最终集群中可能会只剩下所有的巨石节点。

  1. 资源利用率困境
    集群的资源利用率是否可以真的代表当前的集群状态呢?当一个 Pod 的资源利用率很低的时候,不代表就可以侵占他所申请的资源。在大部分的生产集群中,资源利用率都不会保持在一个非常高的水位,但从调度来讲,资源的调度水位应该保持在一个比较高的水位。这样才能既保证集群的稳定可用,又不过于浪费资源。

如果没有设置?Request?与?Limit,而集群的整体资源利用率很高,这意味着什么?这表示所有的 Pod 都在被以真实负载为单元进行调度,相互之间存在非常严重的争抢,而且简单的加入节点也丝毫无法解决问题,因为对于一个已调度的 Pod 而言,除了手动调度与驱逐,没有任何方式可以将这个 Pod 从高负载的节点中移走。那如果我们设置了?Request?与?Limit?而节点的资源利用率又非常高的时候说明了什么呢?很可惜这在大部分的场景下都是不可能的,因为不同的应用不同的负载在不同的时刻资源的利用率也会有所差异,大概率的情况是集群还没有触发设置的阈值就已经无法调度 Pod 了。

在了解了 Kubernetes 弹性伸缩的三大问题后,我们再来看下 Kubernetes 的解决办法是什么?

Kubernetes 的弹性伸缩设计哲学


Kubernetes 的设计理念是将弹性伸缩分成调度层伸缩和资源层伸缩。调度层负责根据指标、阈值伸缩出调度单元,而资源层伸缩负责满足调度单元的资源需求。

在调度层通常是通过 HPA 的方式进行 Pod 的水平伸缩,HPA 的使用方式和我们传统意义上理解的弹性伸缩是非常接近和类似的,通过设置判断的指标、判断的阈值来进行水平伸缩。

在资源层目前主流的方案是通过 cluster-autoscaler 进行节点的水平伸缩。当出现 Pod 由于资源不足造成无法调度时,cluster-autoscaler 会尝试从配置伸缩组中,选择一个可以满足调度需求的组,并自动向组内加入实例,当实例启动后注册到 Kubernetes 后,kube-scheduler 会重新触发 Pod 的调度,将之前无法调度的 Pod 调度到新生成的节点上,从而完成全链路的扩容。

同样在缩容时,调度层会现根据资源的利用率与设置的阈值比较,实现 Pod 水平的缩容。当节点上 Pod 的调度资源降低到资源层缩容阈值的时候,此时 Cluster-Autoscaler 会进行低调度百分比的节点的排水,排水完成后会进行节点的缩容,完成整个链路的收缩。

Kubernetes 弹性伸缩方案的阿克琉斯之踵

经典的 Kubernetes 弹性伸缩的案例

这张图是一个非常经典的弹性伸缩的案例,可以代表大多数的在线业务的场景。应用的初始架构是一个 Deployment,下面有两个 Pod,这个应用的接入层是通 过Ingress Controller 的方式进行对外暴露的,我们设置应用的伸缩策略为:单个 Pod 的 QPS 到达 100,则进行扩容,最小为 2 个 Pod,最大为 10 个 Pod。

HPA controller 会不断轮训 alibaba-cloud-metrics-adapter,来获取 Ingress Gateway 当前路由的 QPS 指标。当 Ingress Gateway 的流量到达 QPS 阈值时,HPA controller 会触发 Deployment 的 Pod 数目变化;当 Pod 的申请容量超过集群的总量后,cluster-autoscaler 会选择合适的伸缩组,弹出相应的 Node,承载之前未调度的 Pod。

这样一个经典的弹性伸缩案例就解析完毕了,那么在实际的开发过程中,会遇到哪些问题呢?

经典的 Kubernetes 弹性伸缩的缺点与解法

首先是扩容时延的问题,社区标准模式是通过创建、释放 ECS 的方式,扩容的时延在 2min-2.5min 左右,而阿里云独立的极速模式是通过创建、停机、启动的方式进行实现,停机时只收取存储的费用,不收取计算的费用。可以通过非常低廉的价格获得 50% 以上的弹性效率。


此外复杂度也是 cluster-autoscaler 绕不过的问题,想要用好 cluster-autoscaler,需要深入的了解 cluster-autoscaler 的一些内部机制,否则极有可能造成无法弹出或者无法缩容的场景。

对于大多数的开发者而言,cluster-autoscaler 的工作原理是黑盒的,而且 cluster-autoscaler 目前最好的问题排查方式依然是查看日志。一旦 cluster-autoscaler 出现运行异常后者由于开发者配置错误导致无法如预期的伸缩,那么 80% 以上的开发者是很难自己进行纠错的。

阿里云容器服务团队开发了一款 kubectl plugin,可以提供 cluster-autoscaler 更深层次的可观测性,可以查看当前 cluster-autoscaler 所在的伸缩阶段以及自动弹性伸缩纠错等能力。

虽然目前遇到的几个核心的问题,都不是压死骆驼的最后一棵稻草。但是我们一直在思考,是否有其他的方式可以让弹性伸缩使用起来更简单、更高效?

阿克琉斯的马丁靴 - Serverless Autoscaling


资源层伸缩的核心问题在于学习成本较高、排错困难、时效性差。当回过头来看 Serverless 的时候,我们可以发现这些问题恰好是 Serverless 的特点与优势,那么是否有办法让 Serverless 成为 Kubernetes 资源层的弹性方案呢?

Serverless Autoscaling 组件 - virtual-kubelet-autoscaler

阿里云容器服务团队开发了 virtual-kubelet-autoscaler,一个在 Kubernetes 中实现 serverless autoscaling 的组件。

当出现了无法调度的 Pod 的时候,virtual-kubelet 负责承载真实的负载,可以理解为一个虚拟节点,拥有无限大的 capacity。当 Pod 调度到 virtual-kubelet 上时,会将 Pod 通过轻量级实例 ECI 进行启动。目前 ECI 的启动时间在 30s 之内,程序从调度开始到运行一般会在 1 分钟内拉起。

与 cluster-autoscaler 类似,virtual-kubelet-autoscaler 也需要使用模拟调度的机制来判断 Pod 是否可以被真实处理和承载,但是相比 cluster-autoscaler 而言,存在如下差异:

  1. virtual-kubelet-autoscaler 模拟调度的对象是增加了调度策略的 Pod Template 并非 Node Template。
  2. virtual-kubelet-autoscaler 的核心是选择 virtual-kubelet 来承载负载,一旦 Pod 模拟调度成功绑定到 virtual-kubelet 上后,Pod 的生命周期管理、问题的排查等就与传统的 Pod 没有差异,不再是黑盒排查问题。

virtual-kubelet-autoscaler 不是"银弹"

virtual-kubelet-autoscaler 并不是用来替代 cluster-autoscaler 的,virtual-kubelet-autoscaler 的优势在于使用简单、高弹性高并发,按量按需计费。但是与此同时也牺牲了部分的兼容性,目前对 cluster-pi、coredns 等机制支持的还并不完善,只需少许的配置 virtual-kubelet-autoscaler 是可以和 cluster-autoscaler 兼容的。virtual-kubelet-autoscaler 特别适合的场景是大数据离线任务、CI/CD 作业、突发型在线负载等。

最后

serverless autoscaling 已经逐渐成为 Kubernetes 弹性伸缩的重要组成部分,当 serverless autoscaling 兼容性基本补齐的时候,serverless 使用简单、无需运维、成本节约的特性会与 Kubernetes 形成完美互补,实现 Kubernetes 弹性伸缩的新飞跃。

原文地址:https://blog.51cto.com/13778063/2435701

时间: 2024-11-08 18:14:47

Serverless 与容器决战在即?有了弹性伸缩就不一样了的相关文章

京东618:Docker扛大旗,弹性伸缩成重点

转载:http://www.infoq.com/cn/news/2015/06/jd-618-docker?utm_source=infoq&utm_medium=popular_widget&utm_campaign=popular_content_list&utm_content=homepage 不知不觉中,年中的618和年终的11.11已经成为中国电商的两大促销日,当然,这两天也是一年中系统访问压力最大的两天.对于京东而言,618更是这一年中最大的一次考试,考点是系统的扩展

京东618:Docker扛大旗,弹性伸缩成重点 (2015-06-23)

不知不觉中,年中的618和年终的11.11已经成为中国电商的两大促销日,当然,这两天也是一年中系统访问压力最大的两天.对于京东而言,618更是这一年中最大的一次考试,考点是系统的扩展性.稳定性.容灾能力.运维能力.紧急故障处理能力.弹性计算云是京东2015年研发部战略项目,它基于Docker简化了应用的部署和扩容,提高了系统的伸缩能力.目前京东的图片系统.单品页.频道页.风控系统.缓存.登录.团购.O2O.无线.拍拍等业务都已经运行在弹性计算云系统中. 过去的一段时间里,弹性计算云项目在京东内部

DCOS中监控和弹性伸缩方案经验

监控的选型 我们的DCOS 主要是面向2种业务形态:互联网应用,NFV组件和相关的数据库.2种不同的业务虽然说都是跑在容器内部,但是其实需要监控的信息和指标都是各不相同.因此在选择监控方案的时候我们更多的考虑了多样性和可定制化方案,同时最重要的是反应速度和自动化的因素 我们的方案需要有告警和自动的弹性伸缩功能来保证业务的可靠性和健壮性. 去年有幸听取了Brian Christner对于容器监控的讲解,所以对他当时提出的cAdvisor+Prometheus+InfluxDB+Grafana 的方

CSS3弹性伸缩布局(上)——box布局

布局简介 CSS3提供了一种崭新的布局方式:Flexbox布局,即弹性伸缩布局模型(Flexible Box)用来提供一个更加有效的方式实现响应式布局. 由于这种布局还处于W3C的草案阶段,并且它分为旧版本.新版本.混合过渡版本三种不同的编码方式.浏览器的兼容性存在一定的问题 首先,我们来看看旧版本的浏览器兼容情况 PS:这是网上的图,浏览器兼容信息可以通过该网站查询:http://www.caniuse.com 开始之前,我们先创建一段内容,分为三个区域 //HTML代码部分 <div> &

第 29 章 CSS3 弹性伸缩布局[下]

学习要点: 1.新版本 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 提供的用来实现未来响应式弹性伸缩布局方案,这里做一个初步的了解. 一.新版本 新版本的 Flexbox 模型是 2012 年 9 月提出的工作草案,这个草案是由 W3C 推出的最新语法.这个版本立志于指定标准,让新式的浏览器全面兼容,在未来浏览器的更新换代中实现了统一. 首先,设置伸缩盒的 display 有如下两个属性值: 属性值 说明 flex 将容器盒模型作为块级弹性伸缩盒显示(新版本) inline-fle

第 29 章 CSS3 弹性伸缩布局[上]

学习要点: 1.布局简介 2.旧版本 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 提供的用来实现未来响应式弹性伸缩布局方案,这里做一个初步的了解. 一.布局简介 CSS3 提供一种崭新的布局方式:Flexbox 布局,即弹性伸缩布局模型(Flexible Box).用来提供一个更加有效的方式实现响应式布局.但是用于这个布局方式还处于 W3C 的草案阶段,并且它还分为旧版本.新版本以及混合过渡版本三种不同的编码方式.在发展中,可能还有各种改动,浏览器的兼容性还存在问题.所以,本节课作

第 29 章 CSS3 弹性伸缩布局[中]

学习要点: 1.混合过度版 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 提供的用来实现未来响应式弹性伸缩布局方案,这里做一个初步的了解. 一.混合过渡版 混合版本的 Flexbox 模型是 2011 年提出的工作草案,主要是针对 IE10 浏览器实现的伸缩布局效果,其功能和旧版本的属性大同小异.我们还是采用上一节课的文件,然后使用混合过渡代码,实现 IE10 的伸缩布局. 首先,设置伸缩盒的 display 有如下两个属性值: 属性值 说明 flexbox 将容器盒模型作为块级弹性

CSS3弹性伸缩布局(二)——flex布局

上一篇博客<CSS3弹性伸缩布局(一)——box布局>介绍了旧版本的box布局,而这篇博客将主要介绍最新版本的flex布局的基础知识. 新版本简介 新版本的Flexbox模型是2012年9月提出的工作草案,这个草案是由W3C 推出的最新语法.这个版本立志于指定标准,让新式的浏览器全面兼容,在未来浏览器的更新换代中实现统一. 这里我们还是继续上一篇博客中的例子,使用最新版本的flex布局来实现相同的效果. html代码: <div> <p>发生过的空间还是看价格哈健康啊水

39.CSS3弹性伸缩布局【下】

第二十九章   CSS3弹性伸缩布局[下] 一.新版本 (可以让心浏览器全面兼容,在未来浏览器更新换代中实现统一) 首先,设置伸缩盒的display有如下两个属性 (1)flex           将容器盒模型作为块级弹性伸缩盒显示(新版本) (2)inline-flex    将容器盒模型作为内联级弹性伸缩盒显示(新版本) //大部分不需要前缀 div{ display:flex: } 属性             IE      Firefox     Chrome      Opera