Kubernetes 弹性伸缩全场景解析 (一):概念延伸与组件布局

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 传统弹性伸缩的困境弹性伸缩是 Kubernetes 中被大家关注的一大亮点,在讨论相关的组件和实现方案之前。首先想先给大家扩充下弹性伸缩的边界与定义,传统意义上来讲,弹性伸缩主要解决的问题是容量规划与实际负载的矛盾。

传统弹性伸缩的困境

弹性伸缩是 Kubernetes 中被大家关注的一大亮点,在讨论相关的组件和实现方案之前。首先想先给大家扩充下弹性伸缩的边界与定义,传统意义上来讲,弹性伸缩主要解决的问题是容量规划与实际负载的矛盾。




如上图所示,蓝色的水位线表示集群的容量随着负载的提高不断的增长,红色的曲线表示集群的实际的负载真实的变化。而弹性伸缩要解决的就是当实际负载出现激增,而容量规划没有来得及反应的场景。


常规的弹性伸缩是基于阈值的,通过设置一个资源缓冲水位来保障资源的充盈,通常 15%-30% 左右的资源预留是比较常见的选择。换言之就是通过一个具备缓冲能力的资源池用资源的冗余换取集群的可用。


这种方式表面上看是没有什么问题的,确实在很多的解决方案或者开源组件中也是按照这种方式进行实现的,但是当我们深入的思考这种实现方案的时候会发现,这种方式存在如下三个经典问题。

1. 百分比碎片难题

在一个 Kubernetes 集群中,通常不只包含一种规格的机器,针对不同的场景、不同的需求,机器的配置、容量可能会有非常大的差异,那么集群伸缩时的百分比就具备非常大的迷惑性。假设我们的集群中存在 4C8G 的机器与 16C32G 的机器两种不同规格,对于 10% 的资源预留,这两种规格是所代表的意义是完全不同的。




特别是在缩容的场景下,通常为了保证缩容后的集群不处在震荡状态,我们会一个节点一个节点或者二分法来缩容节点,那么如何根据百分比来判断当前节点是处在缩容状态就尤为重要,此时如果大规格机器有较低的利用率被判断缩容,那么很有可能会造成节点缩容后,容器重新调度后的争抢饥饿。如果添加判断条件,优先缩容小配置的节点,则有可能造成缩容后资源的大量冗余,最终集群中可能会只剩下所有的巨石节点。

2. 容量的规划炸弹

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


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

3. 资源利用率困境

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


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

弹性伸缩概念的延伸

既然基于资源利用率的弹性伸缩有上述已知的三个问题,有什么办法可以来解决呢?随着应用类型的多样性发展,不同类型的应用的资源要求也存在越来越大的差异。弹性伸缩的概念和意义也在变化,传统理解上弹性伸缩是为了解决容量规划和在线负载的矛盾,而现在是资源成本与可用性之间的博弈。如果将常见的应用进行规约分类,可以分为如下四种不同类型:

1. 在线任务类型

比较常见的是网站、API 服务、微服务等常见的互联网业务型应用,这种应用的特点是对常规资源消耗较高,比如 CPU、内存、网络 IO、磁盘 IO 等,对于业务中断容忍性差。

2. 离线任务类型

例如大数据离线计算、边缘计算等,这种应用的特点是对可靠性的要求较低,也没有明确的时效性要求,更多的关注点是成本如何降低。

3. 定时任务类型

定时运行一些批量计算任务是这种应用的比较常见形态,成本节约与调度能力是重点关注的部分。

4. 特殊任务类型

例如闲时计算的场景、IOT 类业务、网格计算、超算等,这类场景对于资源利用率都有比较高的要求。


单纯的基于资源利用率的弹性伸缩大部分是用来解决第一种类型的应用而产生的,对于其他三种类型的应用并不是很合适,那么 Kubernetes 是如何解决这个问题的呢?

Kubernetes 的弹性伸缩布局

Kubernetes 将弹性伸缩的本质进行了抽象,如果抛开实现的方式,对于不同应用的弹性伸缩而言,该如何统一模型呢? Kubernetes 的设计思路是将弹性伸缩划分为保障应用负载处在容量规划之内与保障资源池大小满足整体容量规划两个层面。简单理解,当需要弹性伸缩时,优先变化的应该是负载的容量规划,当集群的资源池无法满足负载的容量规划时,再调整资源池的水位保证可用性。而两者相结合的方式是无法调度的 Pod 来实现的,这样开发者就可以在集群资源水位较低的时候使用 HPA、VPA 等处理容量规划的组件实现实时极致的弹性,资源不足的时候通过 Cluster-Autoscaler 进行集群资源水位的调整,重新调度,实现伸缩的补偿。两者相互解耦又相互结合,实现极致的弹性。


在 Kubernetes 的生态中,在多个维度、多个层次提供了不同的组件来满足不同的伸缩场景。如果我们从伸缩对象与伸缩方向两个方面来解读 Kubernetes 的弹性伸缩的话,可以得到如下的弹性伸缩矩阵。



  • cluster-autoscaler: kubernetes 社区中负责节点水平伸缩的组件,目前处在 GA 阶段 (General Availability, 即正式发布的版本)。
  • HPA: kubernetes 社区中负责 Pod 水平伸缩的组件,是所有伸缩组件中历史最悠久的,目前支持 autoscaling/v1、 autoscaling/v2beta1 与 autoscaling/v2beta2, 其中 autoscaling/v1 只支持 CPU 一种伸缩指标,在 autoscaling/v2beta1 中增加支持 custom metrics,在 autoscaling/v2beta2 中增加支持 external metrics。
  • cluster-proportional-autoscaler: 根据集群的节点数目,水平调整 Pod 数目的组件,目前处在 GA 阶段。
  • vetical-pod-autoscaler: 根据 Pod 的资源利用率、历史数据、异常事件,来动态调整负载的 Request 值的组件,主要关注在有状态服务、单体应用的资源伸缩场景,目前处在 beta 阶段。
  • addon-resizer: 根据集群中节点的数目,纵向调整负载的 Request 的组件,目前处在 beta 阶段。


在这五个组件中, cluster-autoscaler、 HPA、 cluster-proportional-autoscaler 是目前比较稳定的组件,建议有相关需求的开发者进行选用。


对于百分之八十以上的场景,我们建议客户通过 HPA 结合 cluster-autoscaler 的方式进行集群的弹性伸缩管理, HPA 负责负载的容量规划管理而 cluster-autoscaler 负责资源池的扩容与缩容。

最后

在本文中,和大家主要讨论的是在云原生时代下弹性伸缩概念的延伸,以及 Kubernetes 社区是如何通过解耦的方式通过多个转职的组件实现了两个维度的弹性伸缩,在本系列后面的文章中会为一一解析每个弹性伸缩组件的相关原理与用法。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
29天前
|
算法 Linux C++
【Linux系统编程】深入解析Linux中read函数的错误场景
【Linux系统编程】深入解析Linux中read函数的错误场景
203 0
|
1月前
|
消息中间件 存储 数据库
RocketMQ 流存储解析:面向流场景的关键特性与典型案例
RocketMQ 流存储解析:面向流场景的关键特性与典型案例
88357 0
|
1月前
|
存储 Kubernetes 负载均衡
Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(下)
本文深入探讨了Kubernetes(K8s)的架构、核心组件以及资源对象。Kubernetes作为一个开源的容器编排系统,通过其独特的架构设计和丰富的组件,实现了对容器化应用程序的高效管理和扩展。通过本文的介绍,读者可以深入了解Kubernetes的架构、核心组件以及资源对象,从而更好地应用和管理容器化应用程序。Kubernetes的灵活性和可扩展性使得它成为容器编排领域的领先者,为企业提供了强大的容器运行环境。
|
1月前
|
存储 关系型数据库 OLAP
TiDB适用场景解析:海量数据存储与高并发读写的利器
【2月更文挑战第25天】随着大数据时代的到来,海量数据存储和高并发读写成为众多企业面临的挑战。TiDB作为一种高性能、分布式的关系型数据库,以其独特的架构和强大的功能,在多个场景中展现出了卓越的性能。本文将详细探讨TiDB在海量数据存储、高并发读写等场景下的适用情况,分析其在不同业务场景中的优势与应用价值。
|
11天前
|
JSON Kubernetes 网络架构
Kubernetes CNI 网络模型及常见开源组件
【4月更文挑战第13天】目前主流的容器网络模型是CoreOS 公司推出的 Container Network Interface(CNI)模型
|
1月前
|
存储 编解码 索引
了解FFmpeg音频通道布局结构:AVChannelLayout结构体解析
了解FFmpeg音频通道布局结构:AVChannelLayout结构体解析
17 1
|
1月前
|
前端开发 开发者 UED
构建响应式Web界面:Flexbox与Grid布局的深度解析
【2月更文挑战第28天】 在现代前端开发中,打造灵活且适应不同屏幕尺寸的用户界面是至关重要的。随着移动设备的普及,响应式设计已经成为网页制作不可或缺的一部分。本文将深入探讨两种强大的CSS布局模块——Flexbox和Grid,它们如何简化布局创建过程,并赋予设计师更大的灵活性去构建动态和流畅的响应式界面。通过对这两种技术的比较、使用场景分析以及代码示例,读者将能够更好地理解何时以及如何使用这些工具来提升前端项目的质量和效率。
16 0
|
1月前
|
Kubernetes Linux Docker
深度解析:Kubernetes 1.28.2集群安装过程中的关键步骤
本文旨在为读者提供一份详尽的Kubernetes 1.28.2集群安装指南,帮助您从零开始构建稳定、高效的Kubernetes集群。我们将从环境准备、软件安装、集群初始化到节点添加等各个环节进行逐步讲解,确保您能够顺利完成集群的搭建。
|
1月前
|
Kubernetes API 调度
Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(上)
本文深入探讨了Kubernetes(K8s)的架构、核心组件以及资源对象。Kubernetes作为一个开源的容器编排系统,通过其独特的架构设计和丰富的组件,实现了对容器化应用程序的高效管理和扩展。通过本文的介绍,读者可以深入了解Kubernetes的架构、核心组件以及资源对象,从而更好地应用和管理容器化应用程序。Kubernetes的灵活性和可扩展性使得它成为容器编排领域的领先者,为企业提供了强大的容器运行环境。
|
1月前
|
消息中间件 存储 Cloud Native
深度剖析 RocketMQ 5.0,架构解析:云原生架构如何支撑多元化场景?
了解 RocketMQ 5.0 的核心概念和架构概览;然后我们会从集群角度出发,从宏观视角学习 RocketMQ 的管控链路、数据链路、客户端和服务端如何交互;学习 RocketMQ 如何实现数据的存储,数据的高可用,如何利用云原生存储进一步提升竞争力。
140039 1

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多