配置 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 的 replicas。对于 deployment configuration,这种扩缩会直接对应到 deployment configuration 的 replica 数量。请注意,自动扩缩仅适用于 Complete 阶段中的最新 deployment。

平台会自动考虑资源情况,并在资源突增期间(例如启动时)防止不必要的自动扩缩。处于未就绪状态的 pod 在扩容时 CPU 使用率按 0 计算,自动扩缩器在缩容时会忽略这些 pod。对于没有已知指标的 pod,扩容时 CPU 使用率按 0% 计算,缩容时按 100% CPU 计算。这有助于在 HPA 决策过程中提高稳定性。要使用此功能,您必须配置就绪检查,以确定新 pod 是否已准备好可供使用。

HPA 如何工作?

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

HPA 作为一个控制循环工作,默认同步周期为 15 秒。在此期间,controller manager 会根据 HPA 配置中定义的内容,查询 CPU、内存利用率,或两者。controller manager 会从资源指标 API 获取每个 pod 的资源利用率指标,例如 CPU 或内存,这些 pod 都是 HPA 所针对的对象。

如果设置了利用率目标值,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 计量。

重要:对于基于内存的自动扩缩,内存使用量必须与副本数成比例增减。平均而言:

  • 副本数增加必须导致每个 pod 的总内存(working set)使用量整体下降。
  • 副本数减少必须导致每个 pod 的内存使用量整体上升。
  • 在使用基于内存的自动扩缩之前,请使用平台检查您的应用内存行为,并确保应用满足这些要求。

前提条件

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

创建 Horizontal Pod Autoscaler

使用 CLI

您可以通过定义一个 YAML 文件并使用 kubectl create 命令,使用命令行界面创建 horizontal pod autoscaler。以下示例展示了对 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 名称

  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 数量。
    注意:指标类型包括内置指标和自定义指标。自定义指标仅适用于原生应用中的 deployments,且您必须先添加自定义指标。
    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、memory)或 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 数量:取每个策略计算结果中的最大值。