HPA 控制器

HPA(Horizontal Pod Autoscaler)是 Kubernetes 中用于自动水平扩缩 Pod 数量的控制器,它根据资源使用率或自定义指标自动调整 Deployment、ReplicaSet 或 StatefulSet 的副本数。

1. 工作原理

  • 基本工作流程
    • 指标采集:从 Metrics Server 或自定义指标 API 获取指标数据。
    • 指标计算:计算当前指标值与目标值的比率。
    • 决策算法:使用算法确定需要的副本数。
    • 执行扩缩:通过修改对应工作负载的 replicas 字段实现扩缩。
  • 扩缩容决策算法
期望副本数 = ceil[当前副本数 * (当前指标值 / 目标指标值)]
TeX

2. HPA 获取的指标类型

  • Pod 资源指标:Pod 级别的性能指标,通常是一个比率,例如 Pod 的 CPU、内存使用率等,通常由 Metrics-Server 提供。
    • Metrics-Server 的数据直接来源于集群中每个节点上的 Kubelet。Kubelet 会持续收集本节点上所有 Pod 和节点自身的资源使用情况(如 CPU、内存),并通过一个名为 Summary API 的接口暴露这些数据。
    • Metrics-Server 通过 Kubernetes API Server 获取所有节点的列表,然后直接向各节点的 Kubelet 发起请求,调用 Summary API 获取实时数据。
    • Metrics-Server 将拉取的原始数据聚合为标准的 Kubernetes 资源指标。
  • Container 资源指标:Container 级别的性能指标,该指标从 v1.20 开始引入,可以基于某个容器的性能指标实现自动扩缩容。也是由 Metrics-Server 提供的。
  • Pod 自定义指标:Pod 级别的性能指标,通常是一个值,例如接收的请求数量。
  • Object 自定义指标:自定义指标通常是从 Kubernetes 集群内部运行的应用程序中收集的。这些指标可以通过 Prometheus、Metrics Server 或其他监控工具采集,通常与特定应用程序或 Pod 的性能相关
  • 外部自定义指标:HPA 允许根据 Kubernetes 集群外部的服务指标来进行扩展。外部指标来自于 Kubernetes 集群外部的资源或服务,通常是由外部的监控系统或服务提供的。这些指标不依赖于 Kubernetes 内部的资源,可能包括外部服务的响应时间、消息队列的长度、数据库的请求数等。

3. 部署 Metrics Server

修改 kube-apiserver.yaml 配置:

# 修改每个节点 API Server 的 kube-apiserver.yaml ,修改后会自动重启生效
# /etc/kubernetes/manifests/kube-apiserver.yaml

# 添加启动参数
--enable-aggregator-routing=true
YAML

部署 Metrics Server:

# 下载官方部署文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 修改 components.yaml 配置
...
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
  	spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=10250
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        # 跳过证书验证
        - --kubelet-insecure-tls
        image: k8s.mirror.nju.edu.cn/metrics-server/metrics-server:v0.7.1 # 修改镜像地址
...


# 部署
kubectl apply -f components.yaml
Bash

Metrics Server 相关命令:

# 查看 top 命令的帮助
kubectl top --help
# 查看node节点的资源使用情况
kubectl top node
# 查看pod的资源使用情况
kubectl top pod
# 查看所有命名空间的pod资源使用情况
kubectl top pod -A
Bash

4. HPA 资源定义

HPA 当前有两个版本:

  • HPA v1 版,需要借助Heapster获取CPU和内存指标。
  • HPA v2 版,需要借助Metrics Server获取需要的指标。

4.1. 基本 YAML 结构

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
YAML

关键字段说明:

字段描述示例值
scaleTargetRef指定要扩缩的目标工作负载Deployment/myapp
minReplicas最小副本数1
maxReplicas最大副本数10
metrics扩缩依据的指标列表见下文

4.2. 指标类型示例

  • Pod 资源指标(Resource Metrics)
metrics:
- type: Resource
  resource:
    name: cpu  # 或 memory
    target:
      type: Utilization  # 或 AverageValue
      averageUtilization: 50  # 目标CPU利用率百分比
      # 或 averageValue: 200m
YAML
  • Container 资源指标(ContainerResource Metrics)
metrics:
- type: ContainerResource
  containerResource:
    name: cpu  # 或 memory
    container: applicatuon  # pod 中容器的名字
    target:
      type: Utilization  # 或 AverageValue
      averageUtilization: 50  # 目标CPU利用率百分比
      # 或 averageValue: 200m
YAML
  • Pod 指标(Pod Metrics)
metrics:
- type: Pods
  pods:
    metric:
      name: packets-per-second
    target:
      type: AverageValue
      averageValue: 1k
      
# 设置 Pod 的指标值名称为 packets-per-second ,在目标指标平均值为 1000 时触发扩容操作。
YAML
  • 对象指标(Object Metrics)
metrics:
- type: Object
  object:
    metric:
      name: requests-per-second
    describedObject:
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      name: main-route
    target:
      type: Value
      value: 2k
YAML
  • 外部指标(External Metrics)
metrics:
- type: External
  external:
    metric:
      name: queue_messages_ready
      selector:
        matchLabels:
          queue: "worker_tasks"
    target:
      type: AverageValue
      averageValue: 30
YAML

4.3. 自定义扩缩行为

我们可以通过 HorizontalPodAutoscaler 资源的 behavior 字段进行行为策略配置,系统默认的行为策略如下:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300  # 缩容稳定窗口
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selecPolicy: Max
YAML

关键字段说明:

  • scaleDown:缩容行为策略。
  • scaleUp:扩容行为策略。
  • stabilizationWindowSeconds:稳定窗口时间,单位为 s。HPA 控制器可能因为 Pod 目标副本数量的变化而不断创建和删除 Pod,为了减少不必要的数量调整,该参数提供了一个缓冲时间,HPA 控制器在此时间内不做频繁调整操作,而是取其中最安全的 Pod 期望副本数量,在到达窗口时间后,再进行调整。
  • policies:扩缩容策略,具体如下。
    • type:策略类型,例如 Pods 表示 Pod 数量,Percent 表示比例。
    • value:策略允许的修改量。
    • periodSeconds:策略应该保证为 true 的时间窗口,单位为 s。
    • selectPolicy:指定该方向使用哪种策略,默认为 Max,表示选择影响 Pod 副本数量最大的策略;将该参数设置为 Min,表示选择影响 Pod 副本数量最小的策略;将该参数设置为 Disabled,表示禁用当前方向的策略。

在上面的默认行为示例中,对于缩容行为设置的策略如下:

  • 每 15s 允许减少100%的 Pod 副本数量,缩容稳定窗口时间为 300s。

对于扩容行为设置的策略如下:

  • stabilizationWindowSeconds=0 表示没有稳定窗口时间。
  • 每15s允许增加最多4个Pod副本,或最多增加当前Pod副本数量的 100%。

5. 工作负载使用 HPA 的配置调整

在启用了 HPA 的集群中,建议在 Deployment 或者 StatefulSet 的定义中不要设置 spec.replicas 副本数量,对于已存在的资源可以通过 kubectl edit 命令删除该配置项。

6. 快速创建 HPA

除了基于 HorizontalPodAutoscaler 资源 yaml 配置文件创建 HPA 资源,还可以通过 kubectl autoscale 子命令一键创建 HPA 资源,如下所示:

# 或通过命令创建
kubectl autoscale deployment myapp --cpu-percent=50 --min=1 --max=10

# 为 Deployment“myapp”创建的HPA自动扩缩容控制器,副本数量可以在1和10之间变化,每个Pod副本的目标CPU使用率为90%。
Bash

7. 基于自定义指标的 HPA 示例

上一篇
下一篇