共计 5110 个字符,预计需要花费 13 分钟才能阅读完成。
本文概述了 Kubernetes 中的 Horizontal Pod Autoscaler(HPA)的工作方式以及使用方法。
介绍
部署具有静态配置的副本数的无状态应用不是最佳选择。
而弹性副本数目具备以下特点:
- 当请求率增加时,应用程序应扩大规模(即增加副本数)以保持响应速度。
- 当请求率降低时,应用程序应缩小规模(即减少副本数),以避免浪费资源。
在水平缩放的情况下,放大也称为“_scaling out_”,而缩小也称为“_scaling in_”。这与垂直缩放(请参见下文)形成对比,垂直缩放仅使用术语“按比例放大”和“按比例缩小”。
借助 Horizontal Pod Autoscaler(HPA),Kubernetes 以上述方式为自动缩放应用程序提供了出色的支持。
Kubernetes 中不同类型的自动伸缩
首先,为消除任何误解,让我们澄清一下 Kubernetes 中术语“自动缩放”的用法。
Kubernetes 包括几个自动缩放功能:
- Horizontal Pod Autoscaler (HPA): 调整应用程序副本 Pod 的数量(水平缩放)
- Vertical Pod Autoscaler (VPA): 调整资源请求和应用程序容器的限制(垂直缩放)
- Cluster Autoscaler: 调整集群的节点数
这些自动缩放器彼此完全独立,并且都使用不同的概念和机制。
本文专门讨论 Horizontal Pod Autoscaler。
什么是 Horizontal Pod Autoscaler?
Horizontal Pod Autoscaler(HPA)是内置的 Kubernetes 功能,它允许根据一个或多个默认或用户定义的指标来水平缩放应用程序。
水平缩放意味着增加和减少副本数量。垂直缩放意味着增加和减少单个副本的计算资源。
从技术上讲,HPA 是一个 Kubernetes 控制器,用于跟踪 HorizontalPodAutoscaler 资源并由其配置。
HPA 持续监视有关一个应用程序的一个或多个指标,并调整此应用程序的副本数,以使指标尽可能接近指定的目标值。
HPA 可以使用 scale 子资源来扩展所有这些 Kubernetes 资源,其中包括 Deployment,StatefulSet 和 ReplicaSet。
HPA 执行的控制循环如下所示:
控制循环的步骤为:
- 查询缩放指标
- 计算所需的副本数
- 将应用程序缩放到所需数量的副本
默认情况下,此控制循环每 15 秒执行一次。
所需副本数的计算基于缩放指标和这些指标的用户提供的目标值。
在控制循环的每次迭代中,HPA 都会计算出一个副本计数,该副本计数将使度量的测量值尽可能接近目标值。
例如,假设缩放指标是应用程序所有副本 Pod 每秒平均接收的请求数(req/sec):
- 如果目标值为 10 req / sec,当前值为 20 req / sec,则应用程序过载,并且 HPA 必须扩大应用程序的规模(即增加副本数),以使度量标准减小并接近目标值。
- 如果目标值为 10 req / sec,当前值为 2 req / sec,则该应用程序未充分利用,因此 HPA 必须缩小该应用程序的比例(即减少副本数),以使度量标准提高并更加接近目标值。
用于计算所需副本数的算法基于以下公式:
X = N * (c/t)
解读:
-
X
是期望的副本数 -
N
是当前的副本数 -
c
伸缩指标的当前值 -
t
伸缩指标的目前值
这就是 HPA 的总体运作方式 - 现在让我们看一下它的配置方式。
如何配置 Horizontal Pod Autoscaler?
通过 HorizontalPodAutoscaler 资源完成 HPA 的配置。
HorizontalPodAutoscaler 资源可以指定以下信息:
- 要伸缩的应用
- 副本数最大最小值
- 伸缩指标
- 伸缩指标的目标值
一旦创建了 HorizontalPodAutoscaler 资源,HPA 就会启动,并根据您提供的参数开始监视和自动缩放应用程序。
这是一个示例 HorizontalPodAutoscaler 资源:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: myhpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: myapp_requests_per_second
target:
type: AverageValue
averageValue: 50
不同的 HorizontalPodAutoscaler 资源的不同版本。上面的示例是版本 v2beta2,它是撰写本文时的最新版本。
上面的示例 HorizontalPodAutoscaler 资源包括以下信息:
- 要自动缩放的应用程序(扩展目标)是名为
myapp
的部署 - 副本的最小和最大数量分别为 1 和 10
- 缩放指标称为
myapp_requests_per_second
- 缩放指标的目标值为 50
这意味着,HPA 将通过尝试将应用程序所有 Pod 的 myapp_requests_per_second
指标的平均值保持在尽可能接近 50 的方式,在 1 至 10 个副本之间自动缩放 myapp
部署。
但是现在有个问题,什么是 myapp_requests_per_second
指标,它来自哪里?
如何获得应用程序指标?
HPA 如何获取在 HorizontalPodAutoscaler 资源中指定的指标?
事实证明,HPA 从度量标准 API 查询这些度量标准(然后,必须通过度量标准 API 公开用于自动缩放的任何应用程序度量标准):
指标 API 是 Kubernetes 集群中的中心位置,不同类型的指标可以暴露给不同类型的客户端 -HPA 是这些客户端之一。
存在三种旨在提供不同类型指标的不同指标 API:
- Resource Metrics API 提供 Pod 和节点的预定义资源使用率指标(当前支持 CPU 和内存使用率)。
- Custom Metrics API 提供与群集中的 Kubernetes 对象相关联的用户指定的自定义指标。
- External Metrics API 提供了用户定义的自定义指标,这些指标未与集群中的任何 Kubernetes 对象相关联(这些指标可能是来自集群外部服务(例如云服务)的指标)。
从技术角度来看,指标 API 是 Kubernetes 扩展 API。这意味着它们是 Kubernetes 核心 API 的扩展,可通过 Kubernetes API 服务器进行访问。
API 服务器上这些指标 API 的端点路径为:
-
/apis/metrics.k8s.io/v1beta1/
(用于 Resource Metrics API) -
/apis/custom.metrics.k8s.io/v1beta1/
(用于自定义指标 API) -
/apis/external.metrics.k8s.io/v1beta1/
(用于外部指标 API)
默认情况下,Kubernetes 集群中未启用指标 API。必须通过安装适当的扩展 API 服务器显式启用它们(请参见下文)。
上例中的 myapp_requests_per_second
度量标准是用户定义的度量标准,它与 Pods 相关联(其含义是 Pod 接收到的当前每秒请求数)。
这意味着 myapp_requests_per_second
指标必须通过 Custom Metrics API 进行提供。
但是,该指标如何进入 Custom Metrics API?
答案是您必须为通过 Custom Metrics API 收集,处理和提供服务的该指标进行安排。
为此,您必须首先启用 Custom Metrics API。通过在提供以下特定指标 API 的集群中安装指标 API 服务器来启用指标 API:
- 对于 Resource Metrics API,有一个官方的 Metrics Server。
- 对于自定义指标 API 和外部指标 API,存在各种第三方指标 API 服务器。最受欢迎的软件之一可能是 Prometheus Adapter。
指标 API 可以彼此独立启用。例如,您可以启用资源指标 API,而无需启用其他两个指标 API。
度量标准 API 服务器通过度量标准 API 服务于度量标准,但通常不从度量标准源收集原始度量标准数据。这项工作由另一个称为度量收集器的组件完成(可以在集群内部或外部运行):
对于 Resource Metrics API,默认的指标收集器是 cAdvisor,它已编译到 kubelet 中,因此默认情况下在每个 Kubernetes 集群中运行。它收集节点上以及整个节点上所有容器的资源使用情况指标(例如 CPU 和内存)。
对于自定义指标 API 和外部指标 API,可以使用各种第三方指标收集器。最受欢迎的可能是 Prometheus,但也可以使用其他通用指标收集系统,例如 Datadog 或 Google Stackdriver。
指标收集器和指标 API 服务器形成一个集成的“指标管道”,并且它们必须能够相互通信。大多数度量标准收集系统(例如 Prometheus)都具有关联的度量标准 API 服务器(例如 Prometheus Adapter),并且应将它们相互结合使用。
因此,启用了所有三个指标 API 的典型设置如下所示:
此设置使用由 cAdvisor 和 Metrics Server 组成的指标管道(用于资源指标 API)(官方默认设置),以及由 Prometheus 和 Prometheus Adapter 组成的另一个指标管道,用于 Custom Metrics API 和 External Metrics API。
请务必注意,在默认的 Kubernetes 集群中,这些组件(cAdvisor 除外)均未默认安装。如果要使用指标 API(例如,通过 HPA 自动缩放应用程序),则必须正确安装和配置它们。
回到 myapp_requests_per_second
指标,此示例场景中的情况如下所示:
- Prometheus 从属于
myapp
部署的 Pod 收集度量数据。 - Prometheus 适配器从 Prometheus 获取收集的度量标准数据,并通过 Custom Metrics API 将其用作名为
myapp_requests_per_second
的度量标准。 - HPA 从自定义指标 API 查询
myapp_requests_per_second
指标,并使用它来自动缩放myapp
部署。
这是一个非常大的步骤,因此让我们通过一个例子来概括一下。
示例
为了更好地了解事情是如何协同工作的,让我们逐步介绍根据应用程序 Pod 每秒收到的平均请求数,使用 HPA 自动缩放应用程序所需执行的具体步骤。
以下内容假定集群尚未启用指标 API,要自动伸缩的应用程序是名为 myapp
的 Deployment,要自动伸缩的指标称为myapp_requests_per_second
,并且要使用基于 Prometheus 的自定义指标管道(如如上所示)。
这是您要做的:
- 对应用程序进行检测,以收集原始指标数据(例如已接收请求的总数),并以 Prometheus 格式公开它,以便 Prometheus 可以收集它。通常通过使用 Prometheus 客户端库来完成。
- 在群集中安装 Prometheus(从理论上讲,它也可以在群集外部运行)并配置它以收集应用程序公开的指标数据。使用所谓的 Prometheus“scrape config”文件来配置 Prometheus 以收集特定度量。
- 在群集中安装 Prometheus Adapter 并将其配置为定期查询从 Prometheus 收集的指标数据,将其转换为名为
myapp_requests_per_second
的指标,然后通过 Custom Metrics API 公开它。使用 Prometheus 适配器配置文件完成 Prometheus 适配器的配置。 - 在群集中创建一个 HorizontalPodAutoscaler 资源,该资源根据名为
myapp_requests_per_second
(由 Custom Metrics API 公开)的度量标准和一些目标值(例如 50)定义要自动缩放的 Deployment 名为myapp
。为此,您可以重复使用本文前面显示的 HorizontalPodAutoscaler 资源。
就是这样 - 一旦创建 HorizontalPodAutoscaler,HPA 就会启动并开始通过 Custom Metrics API 监视指定的指标,并适当地自动缩放您的应用程序。
将这些知识付诸实践仍然是很多工作。特别是,有许多配置 Prometheus 和 Prometheus Adapter 的特质细节,以正确的方式收集和公开正确的指标。
PS: 本文属于翻译,原文