乐趣区

使用水平Pod自动缩放器在Kubernetes上自动缩放应用程序

本文概述了 Kubernetes 中的 Horizo​​ntal Pod Autoscaler(HPA)的工作方式以及使用方法。

介绍

部署具有静态配置的副本数的无状态应用不是最佳选择。

而弹性副本数目具备以下特点:

  • 当请求率增加时,应用程序应扩大规模(即增加副本数)以保持响应速度。
  • 当请求率降低时,应用程序应缩小规模(即减少副本数),以避免浪费资源。

在水平缩放的情况下,放大也称为“_scaling out_”,而缩小也称为“_scaling in_”。这与垂直缩放(请参见下文)形成对比,垂直缩放仅使用术语“按比例放大”和“按比例缩小”。

借助 Horizo​​ntal Pod Autoscaler(HPA),Kubernetes 以上述方式为自动缩放应用程序提供了出色的支持。

Kubernetes 中不同类型的自动伸缩

首先,为消除任何误解,让我们澄清一下 Kubernetes 中术语“自动缩放”的用法。

Kubernetes 包括几个自动缩放功能:

  • Horizontal Pod Autoscaler (HPA): 调整应用程序副本 Pod 的数量(水平缩放)
  • Vertical Pod Autoscaler (VPA): 调整资源请求和应用程序容器的限制(垂直缩放)
  • Cluster Autoscaler: 调整集群的节点数

这些自动缩放器彼此完全独立,并且都使用不同的概念和机制。

本文专门讨论 Horizo​​ntal Pod Autoscaler。

什么是 Horizontal Pod Autoscaler?

Horizo​​ntal Pod Autoscaler(HPA)是内置的 Kubernetes 功能,它允许根据一个或多个默认或用户定义的指标来水平缩放应用程序。

水平缩放意味着增加和减少副本数量。垂直缩放意味着增加和减少单个副本的计算资源。

从技术上讲,HPA 是一个 Kubernetes 控制器,用于跟踪 Horizo​​ntalPodAutoscaler 资源并由其配置。

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?

通过 Horizo​​ntalPodAutoscaler 资源完成 HPA 的配置。

Horizo​​ntalPodAutoscaler 资源可以指定以下信息:

  1. 要伸缩的应用
  2. 副本数最大最小值
  3. 伸缩指标
  4. 伸缩指标的目标值

一旦创建了 Horizo​​ntalPodAutoscaler 资源,HPA 就会启动,并根据您提供的参数开始监视和自动缩放应用程序。

这是一个示例 Horizo​​ntalPodAutoscaler 资源:

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

不同的 Horizo​​ntalPodAutoscaler 资源的不同版本。上面的示例是版本 v2beta2,它是撰写本文时的最新版本。

上面的示例 Horizo​​ntalPodAutoscaler 资源包括以下信息:

  1. 要自动缩放的应用程序(扩展目标)是名为 myapp 的部署
  2. 副本的最小和最大数量分别为 1 和 10
  3. 缩放指标称为myapp_requests_per_second
  4. 缩放指标的目标值为 50

这意味着,HPA 将通过尝试将应用程序所有 Pod 的 myapp_requests_per_second 指标的平均值保持在尽可能接近 50 的方式,在 1 至 10 个副本之间自动缩放 myapp 部署。

但是现在有个问题,什么是 myapp_requests_per_second 指标,它来自哪里?

如何获得应用程序指标?

HPA 如何获取在 Horizo​​ntalPodAutoscaler 资源中指定的指标?

事实证明,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 适配器的配置。
  • 在群集中创建一个 Horizo​​ntalPodAutoscaler 资源,该资源根据名为myapp_requests_per_second(由 Custom Metrics API 公开)的度量标准和一些目标值(例如 50)定义要自动缩放的 Deployment 名为myapp。为此,您可以重复使用本文前面显示的 Horizo​​ntalPodAutoscaler 资源。

就是这样 - 一旦创建 Horizo​​ntalPodAutoscaler,HPA 就会启动并开始通过 Custom Metrics API 监视指定的指标,并适当地自动缩放您的应用程序。

将这些知识付诸实践仍然是很多工作。特别是,有许多配置 Prometheus 和 Prometheus Adapter 的特质细节,以正确的方式收集和公开正确的指标。

PS: 本文属于翻译,原文

退出移动版