配置 HPA

HPA(Horizontal Pod Autoscaler)会根据预设策略和指标自动增加或减少 pod 数量,使应用能够在业务负载突然激增时保持处理能力,同时在低流量时段优化资源利用率。

了解 Horizontal Pod Autoscaler

您可以创建一个 horizontal pod autoscaler,用于指定要运行的 pod 最小数量和最大数量,以及 pod 应达到的 CPU 利用率或内存利用率目标。

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

对于 replication controller,此扩缩容会直接对应到 replication controller 的从节点。对于 deployment configuration,扩缩容会直接对应到 deployment configuration 的从节点数量。请注意,自动扩缩容仅适用于 Complete 阶段中的最新 deployment。

平台会自动考虑资源情况,并防止在资源峰值期间进行不必要的自动扩缩容,例如启动期间。处于未就绪状态的 pod 在扩容时的 CPU 使用率视为 0,而在缩容时,autoscaler 会忽略这些 pod。没有已知指标的 pod 在扩容时的 CPU 使用率视为 0%,在缩容时视为 100% CPU。这样可以让 HPA 决策更加稳定。要使用此功能,您必须配置 readiness 检查,以确定新的 pod 是否已准备好可供使用。

HPA 如何工作?

horizontal pod autoscaler(HPA)扩展了 pod 自动扩缩容的概念。HPA 允许您创建和管理一组负载均衡的节点。当给定的 CPU 或内存阈值被跨越时,HPA 会自动增加或减少 pod 数量。

HPA 作为一个控制循环运行,默认同步周期为 15 秒。在此期间,controller manager 会针对 HPA 配置中定义的内容,查询 CPU、内存利用率,或二者兼有。controller manager 会从资源指标 API 获取由 HPA 目标 pod 的每个 pod 的 CPU 或内存等按 pod 资源指标所对应的利用率指标。

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

支持的指标

horizontal pod autoscaler 支持以下指标:

指标描述
CPU Utilization使用的 CPU 核心数。可用于计算 pod 请求 CPU 的百分比。
Memory Utilization使用的内存量。可用于计算 pod 请求内存的百分比。
Network Inbound Traffic进入 pod 的网络流量,按 KiB/s 计量。
Network Outbound Traffic从 pod 发出的网络流量,按 KiB/s 计量。
Storage Read Traffic从存储中读取的数据量,按 KiB/s 计量。
Storage Write Traffic写入存储的数据量,按 KiB/s 计量。

重要:对于基于内存的自动扩缩容,内存使用量必须与从节点数量成比例地增加和减少。平均而言:

  • 从节点数量增加时,整体内存(working set)使用量必须随之下降。
  • 从节点数量减少时,单个 pod 的内存使用量必须随之上升。
  • 在使用基于内存的自动扩缩容之前,请使用平台检查应用的内存行为,并确保应用满足这些要求。

前提条件

请确保监控组件已部署到当前集群中并正常运行。您可以通过单击平台右上角的 展开 > 平台健康状态 来查看监控组件的部署和健康状态。

创建 Horizontal Pod Autoscaler

使用 CLI

您可以通过命令行界面创建 horizontal pod autoscaler:定义一个 YAML 文件,并使用 kubectl create 命令。以下示例展示了对 Deployment 对象进行自动扩缩容的配置。初始 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
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 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 Name

  4. 向下滚动到 Elastic Scaling 区域,并在右侧单击 Update

  5. 选择 Horizontal Scaling 并完成策略配置。

    参数描述
    Pod Count在 deployment 成功创建后,您需要评估与已知且常规的业务量变化相对应的 Minimum Pod Count,以及在高业务压力下由命名空间配额所能支持的 Maximum Pod Count。设置后仍可修改最大或最小 pod 数量,建议先通过性能测试得出更准确的值,并在使用过程中持续调整,以满足业务需求。
    Trigger Policy列出对业务变化敏感的 Metrics 及其 Target Thresholds,用于触发扩容或缩容操作。
    例如,如果您设置 CPU Utilization = 60%,一旦 CPU 利用率偏离 60%,平台将开始根据当前 deployment 的资源分配不足或过剩情况自动调整 pod 数量。
    注意:指标类型包括内置指标和自定义指标。自定义指标仅适用于原生应用中的 deployment,且您必须先添加自定义指标。
    Scale Up/Down Step (Alpha)对于有特定扩缩容速率要求的业务,您可以通过指定 Scale-Up StepScale-Down Step 来逐步适应业务量变化。
    对于缩容步长,您可以自定义 Stability Window,默认为 300 秒,这意味着您必须等待 300 秒后才能执行缩容操作。
  6. 单击 Update

将自定义指标用于 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
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 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/v2
kind: HorizontalPodAutoscaler
metadata:
  name: demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: demo
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: metric-demo
        target:
          type: AverageValue
          averageValue: 10

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

触发条件定义

  • metrics 是数组类型,支持多个指标
  • metric type 可以是:Object(描述 k8s 资源)、Pods(描述每个 Pod 的指标)、Resources(内置 k8s 指标:CPU、内存)或 External(通常表示集群外部的指标)
  • 如果自定义指标不是由 Prometheus 提供,则需要通过一系列操作(例如在 Prometheus 中创建规则)创建新指标

指标的主要结构如下:

{
      "describedObject": {  # Described object (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/v2 中的更新

autoscaling/v2 支持内存利用率:

apiVersion: autoscaling/v2
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: 80
          type: Utilization
      type: Resource
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx

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

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

注意

  • 对于 CPU UtilizationMemory Utilization 指标,只有当实际值波动超出目标阈值 ±10% 的范围时,才会触发自动扩缩容。

  • 缩容可能会影响正在进行的业务操作;请谨慎执行。

计算规则

当业务指标发生变化时,平台会根据以下规则自动计算与业务量匹配的目标 pod 数量,并进行相应调整。如果业务指标持续波动,该值将调整为设置的 Minimum Pod CountMaximum Pod Count

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

    注意

    • 如果计算出的目标 pod 数量超过设置的 Maximum Pod Count(例如 4),平台只会扩容到 4 个 pod。如果在修改最大 pod 数量后指标仍持续偏高,您可能需要使用其他扩缩容方式,例如提高命名空间的 pod 配额或增加硬件资源。

    • 如果计算出的目标 pod 数量(前例中为 5)小于根据 Scale-Up Step 调整后的 pod 数量(例如 10),平台只会扩容到 5 个 pod。

  • 多策略目标 pod 数量:取各策略计算结果中的最大值。