配置 HPA

HPA(Horizontal Pod Autoscaler,水平 Pod 自动扩缩器)根据预设的策略和指标自动上下调整 Pod 数量,使应用能够应对突发的业务流量高峰,同时在低流量时段优化资源利用率。

目录

了解水平 Pod 自动扩缩器

您可以创建一个水平 Pod 自动扩缩器,指定希望运行的 Pod 最小和最大数量,以及 Pod 应达到的 CPU 利用率或内存利用率目标。

创建水平 Pod 自动扩缩器后,平台开始查询 Pod 上的 CPU 和/或内存资源指标。当这些指标可用时,水平 Pod 自动扩缩器计算当前指标利用率与期望指标利用率的比值,并据此进行扩缩容。查询和扩缩容操作以固定间隔执行,但指标可用可能需要一到两分钟。

对于 replication controllers,此扩缩容直接对应 replication controller 的 Replica 数量。对于 deployment configurations,扩缩容直接对应 deployment configuration 的 Replica 数量。注意,自动扩缩容仅适用于处于 Complete 阶段的最新部署。

平台会自动考虑资源情况,避免在资源峰值(如启动期间)时进行不必要的自动扩缩容。处于未就绪状态的 Pod 在扩容时视为 0 CPU 使用率,缩容时会被忽略。没有已知指标的 Pod 在扩容时视为 0% CPU 使用率,缩容时视为 100% CPU 使用率。这有助于 HPA 决策时更稳定。要使用此功能,必须配置 readiness 检查以判断新 Pod 是否已准备好使用。

HPA 是如何工作的?

水平 Pod 自动扩缩器(HPA)扩展了 Pod 自动扩缩的概念。HPA 允许您创建和管理一组负载均衡的节点。当 CPU 或内存达到设定阈值时,HPA 会自动增加或减少 Pod 数量。

HPA 作为一个控制循环运行,默认同步周期为 15 秒。在此期间,controller manager 会根据 HPA 配置查询 CPU、内存利用率或两者。controller manager 从资源指标 API 获取每个被 HPA 目标的 Pod 的资源利用率指标,如 CPU 或内存。

如果设置了利用率目标,controller 会将利用率值计算为各 Pod 容器请求资源的百分比。然后 controller 计算所有目标 Pod 的平均利用率,并生成一个比例,用于调整期望的 Replica 数量。

支持的指标

水平 Pod 自动扩缩器支持以下指标:

指标描述
CPU 利用率使用的 CPU 核数。可用于计算 Pod 请求 CPU 的百分比。
内存利用率使用的内存量。可用于计算 Pod 请求内存的百分比。
网络入流量进入 Pod 的网络流量,单位为 KiB/s。
网络出流量从 Pod 发出的网络流量,单位为 KiB/s。
存储读流量从存储读取的数据量,单位为 KiB/s。
存储写流量写入存储的数据量,单位为 KiB/s。

重要提示:对于基于内存的自动扩缩容,内存使用必须与 Replica 数量成比例地增减。一般来说:

  • Replica 数量增加时,每个 Pod 的内存(工作集)使用应整体下降。
  • Replica 数量减少时,每个 Pod 的内存使用应整体上升。
  • 请使用平台检查应用的内存行为,确保应用满足这些要求后再使用基于内存的自动扩缩容。

前提条件

请确保监控组件已部署在当前集群并正常运行。您可以点击平台右上角 展开 > 平台健康状态,检查监控组件的部署和健康状态。

创建水平 Pod 自动扩缩器

使用 CLI

您可以通过命令行界面创建水平 Pod 自动扩缩器,方法是定义一个 YAML 文件并使用 kubectl create 命令。以下示例展示了针对 Deployment 对象的自动扩缩容。初始部署需要 3 个 Pod,HPA 对象将最小值提升到 5。如果 Pod 的 CPU 使用率达到 75%,Pod 数量将增加到 7:

  1. 创建名为 hpa.yaml 的 YAML 文件,内容如下:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: hpa-demo
      namespace: default
    spec:
      maxReplicas: 7
      minReplicas: 3
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: deployment-demo
      targetCPUUtilizationPercentage: 75
    1. 使用 autoscaling/v2 API。
    2. HPA 资源的名称。
    3. 需要扩缩容的 Deployment 名称。
    4. 最大扩缩容副本数。
    5. 最小维持副本数。
    6. 指定扩缩容对象的 API 版本。
    7. 指定对象类型。对象必须是 Deployment、ReplicaSet 或 StatefulSet。
    8. HPA 作用的目标资源。
    9. 触发扩缩容的目标 CPU 利用率百分比。
  2. 应用 YAML 文件创建 HPA:

    kubectl create -f hpa.yaml

    示例输出:

    horizontalpodautoscaler.autoscaling/hpa-demo created
  3. 创建 HPA 后,可以运行以下命令查看 Deployment 的新状态:

    kubectl get deployment deployment-demo

    示例输出:

    NAME              READY   UP-TO-DATE   AVAILABLE   AGE
    deployment-demo   5/5     5            5           3m
  4. 也可以检查 HPA 的状态:

    kubectl get hpa hpa-demo

    示例输出:

    NAME         REFERENCE                  TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
    hpa-demo   Deployment/deployment-demo   0%/75%     3         7         3          2m

使用 Web 控制台

  1. 进入 Container Platform

  2. 在左侧导航栏点击 Workloads > Deployments

  3. 点击 Deployment 名称

  4. 向下滚动到 弹性伸缩 区域,点击右侧的 更新

  5. 选择 水平伸缩 并完成策略配置。

    参数描述
    Pod 数量部署成功后,需要评估对应已知和常规业务量变化的最小 Pod 数量,以及在高业务压力下命名空间配额可支持的最大 Pod 数量。最大或最小 Pod 数量可在设置后更改,建议先通过性能测试推导更准确的值,并在使用过程中持续调整以满足业务需求。
    触发策略列出对业务变化敏感的指标及其目标阈值,以触发扩容或缩容操作。
    例如,设置 CPU 利用率 = 60%,一旦 CPU 利用率偏离 60%,平台将根据当前部署资源不足或过剩情况自动调整 Pod 数量。
    注意:指标类型包括内置指标和自定义指标。自定义指标仅适用于原生应用中的部署,且需先添加自定义指标
    扩缩容步长(Alpha)对于有特定扩缩容速率要求的业务,可以通过指定扩容步长缩容步长逐步适应业务量变化。
    缩容步长可自定义稳定窗口,默认 300 秒,表示执行缩容操作前需等待 300 秒。
  6. 点击 更新

使用自定义指标进行 HPA

自定义指标 HPA 扩展了原有的 HorizontalPodAutoscaler,支持除 CPU 和内存利用率外的更多指标。

要求

  • kube-controller-manager:horizontal-pod-autoscaler-use-rest-clients=true
  • 预先安装 metrics-server
  • Prometheus
  • custom-metrics-api

传统(核心指标)HPA

传统 HPA 支持 CPU 利用率和内存指标动态调整 Pod 实例数量,示例如下:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-app-nginx
  namespace: test-namespace
spec:
  maxReplicas: 1
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-app-nginx
  targetCPUUtilizationPercentage: 50

该 YAML 中,scaleTargetRef 指定了扩缩容的工作负载对象,targetCPUUtilizationPercentage 指定 CPU 利用率触发指标。

自定义指标 HPA

使用自定义指标需安装 prometheus-operator 和 custom-metrics-api。安装后,custom-metrics-api 提供大量自定义指标资源:

{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "custom.metrics.k8s.io/v1beta1",
  "resources": [
    {
      "name": "namespaces/go_memstats_heap_sys_bytes",
      "singularName": "",
      "namespaced": false,
      "kind": "MetricValueList",
      "verbs": ["get"]
    },
    {
      "name": "jobs.batch/go_memstats_last_gc_time_seconds",
      "singularName": "",
      "namespaced": true,
      "kind": "MetricValueList",
      "verbs": ["get"]
    },
    {
      "name": "pods/go_memstats_frees",
      "singularName": "",
      "namespaced": true,
      "kind": "MetricValueList",
      "verbs": ["get"]
    }
  ]
}

这些资源均为 MetricValueList 的子资源。您可以通过 Prometheus 创建规则来创建或维护子资源。自定义指标 HPA 的 YAML 格式与传统 HPA 不同:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: demo
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: demo
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metricName: metric-demo
        targetAverageValue: 10

示例中,scaleTargetRef 指定了工作负载。

触发条件定义

  • metrics 是数组类型,支持多个指标
  • metric type 可为:Object(描述 k8s 资源)、Pods(描述每个 Pod 的指标)、Resources(内置 k8s 指标:CPU、内存)、External(通常为集群外部指标)
  • 若自定义指标非由 Prometheus 提供,则需通过创建 Prometheus 规则等操作新增指标

指标的主要结构如下:

{
      "describedObject": {  # 描述对象(Pod)
        "kind": "Pod",
        "namespace": "monitoring",
        "name": "nginx-788f78d959-fd6n9",
        "apiVersion": "/v1"
      },
      "metricName": "metric-demo",
      "timestamp": "2020-02-5T04:26:01Z",
      "value": "50"
}

该指标数据由 Prometheus 收集并更新。

自定义指标 HPA 兼容性

自定义指标 HPA YAML 实际兼容原核心指标(CPU),写法如下:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: nginx
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 80
    - type: Resource
      resource:
        name: memory
        targetAverageValue: 200Mi
  • targetAverageValue 是每个 Pod 获取的平均值
  • targetAverageUtilization 是根据直接值计算的利用率

算法参考为:

replicas = ceil(sum(CurrentPodsCPUUtilization) / Target)

autoscaling/v2beta2 的更新

autoscaling/v2beta2 支持内存利用率:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
  namespace: default
spec:
  minReplicas: 1
  maxReplicas: 3
  metrics:
    - resource:
        name: cpu
        target:
          averageUtilization: 70
          type: Utilization
      type: Resource
    - resource:
        name: memory
        target:
          averageUtilization:
          type: Utilization
      type: Resource
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx

变化:targetAverageUtilizationtargetAverageValue 改为 target,并转换为 xxxValuetype 的组合:

  • xxxValue:AverageValue(平均值)、AverageUtilization(平均利用率)、Value(直接值)
  • type:Utilization(利用率)、AverageValue(平均值)

注意

  • 对于 CPU 利用率内存利用率 指标,只有实际值偏离目标阈值 ±10% 范围时才触发自动扩缩容。
  • 缩容可能影响正在进行的业务操作,请谨慎操作。

计算规则

当业务指标变化时,平台会根据以下规则自动计算匹配业务量的目标 Pod 数量并进行调整。如果业务指标持续波动,数值会被调整到设置的最小 Pod 数量最大 Pod 数量

  • 单策略目标 Pod 数量:ceil[(sum(实际指标值)/指标阈值)]。即所有 Pod 的实际指标值之和除以指标阈值后向上取整。例如:当前有 3 个 Pod,CPU 利用率分别为 80%、80%、90%,设置的 CPU 利用率阈值为 60%。根据公式,Pod 数量自动调整为:ceil[(80%+80%+90%)/60%] = ceil 4.1 = 5 个 Pod。

    注意

    • 如果计算出的目标 Pod 数量超过设置的最大 Pod 数量(例如 4),平台只会扩容到 4 个 Pod。如果调整最大 Pod 数量后指标仍持续偏高,可能需要采用其他扩缩容方式,如增加命名空间 Pod 配额或增加硬件资源。
    • 如果计算出的目标 Pod 数量(如上例的 5)小于根据扩容步长调整后的 Pod 数量(例如 10),平台只会扩容到 5 个 Pod。
  • 多策略目标 Pod 数量:取各策略计算结果中的最大值。