跳到正文
复制成功
请遵守本站许可
报告
章节_文章 // 现场报告

文章编号: RL-HPA基于指标的

2026.08.09

HPA:基于指标的 Pod 水平扩缩容

Chavy
Chavy
#Kubernetes#HPA#自动扩缩容#指标
档案

摘要:从指标采集和副本计算理解 HPA,掌握资源请求、资源与自定义指标、多指标决策、扩缩容行为和稳定窗口的配置及排查。

本节学习 Kubernetes 自动伸缩机制中的核心组件:HPA(Horizontal Pod Autoscaler,水平 Pod 自动扩缩容器)。

Deployment 可以通过设置:

PRTCL // YAML
spec:
replicas: 3

让 Kubernetes 始终维持 3 个 Pod 副本。

但是生产环境中的业务流量并不是固定的。

例如:

一个电商系统可能出现以下情况:

时间CPU 使用率业务流量
凌晨 2 点10%很低
上午 9 点35%正常
下午 2 点75%较高
晚上 8 点95%高峰

如果始终运行 10 个 Pod,会造成资源浪费。

如果始终运行 2 个 Pod,又可能无法承受高峰流量。

因此,我们希望 Kubernetes 能够根据实际负载自动调整 Pod 数量。

这就是 HPA 要解决的问题。


一、什么是 HPA?#

1. HPA 的基本概念#

HPA 全称:

Horizontal Pod Autoscaler。

它是 Kubernetes 中负责自动调整工作负载副本数量的控制器。

核心作用:

根据 CPU、内存或其他指标的变化,自动增加或减少 Pod 副本数量。

例如:

flowchart TB
    N0["CPU 使用率较低"]
    N1["减少 Pod 副本"]
    N2["节约计算资源"]
    N3["CPU 使用率较高"]
    N4["增加 Pod 副本"]
    N5["提高业务处理能力"]
    N0 --> N1
    N1 --> N2
    N3 --> N4
    N4 --> N5

2. HPA 的工作架构#

理解这个架构:

flowchart TB
    N0["用户访问业务"]
    N1["Deployment"]
    N2["Pod"]
    N3["CPU / Memory"]
    N4["Metrics Server"]
    N5["Metrics API"]
    N6["HPA"]
    N7["调整 Deployment"]
    N8["ReplicaSet"]
    N9["增加或减少 Pod"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4
    N4 --> N5
    N5 --> N6
    N6 --> N7
    N7 --> N8
    N8 --> N9

涉及几个核心组件:

组件作用
HPA Controller根据指标计算副本数量
Metrics Server收集 CPU、内存使用指标
Metrics API向 HPA 提供资源指标
Deployment管理应用副本
ReplicaSet实际控制 Pod 数量

注意:

HPA 通常不会直接创建 Pod,而是调整 Deployment 或其他可扩缩工作负载的副本数量。


二、HPA 的核心工作原理#

1. HPA 如何知道需要增加多少 Pod?#

假设:

当前 Deployment:

PRTCL // YAML
replicas: 2

CPU 目标使用率:

PRTCL // TEXT
50%

当前 CPU 使用率:

PRTCL // TEXT
100%

那么 HPA 会认为当前 Pod 负载过高,需要增加副本。

HPA 使用的核心计算公式:

[ DesiredReplicas = \left\lceil CurrentReplicas \times \frac{CurrentMetric}{DesiredMetric} \right\rceil ]

其中:

  • CurrentReplicas:当前 Pod 副本数量。
  • CurrentMetric:当前指标值。
  • DesiredMetric:目标指标值。

2. 计算示例#

当前:

PRTCL // TEXT
Pod 数量:2
CPU 使用率:100%
目标 CPU 使用率:50%

代入:

[ \left\lceil 2\times\frac{100}{50}\right\rceil =4 ]

因此:

PRTCL // TEXT
当前副本:2
目标副本:4

HPA 会尝试将副本数量调整为 4。

3. 再看一个例子#

当前:

PRTCL // TEXT
Pod 数量:4
CPU 使用率:25%
目标 CPU 使用率:50%

计算:

[ \left\lceil 4\times\frac{25}{50}\right\rceil =2 ]

因此:

PRTCL // TEXT
当前副本:4
目标副本:2

HPA 会尝试减少副本。

4. 为什么使用向上取整?#

例如:

PRTCL // TEXT
当前 Pod:3
当前 CPU:60%
目标 CPU:50%

计算:

[ 3\times\frac{60}{50}=3.6 ]

实际副本不能是 3.6 个,因此需要向上取整:

PRTCL // TEXT
目标副本:4

这样才能满足扩容需求。

注意:这是理解 HPA 的基础计算公式。实际控制器还会考虑容差范围、指标采集误差、缺失指标、扩缩容稳定窗口和副本上下限等因素,并非每次都直接按照公式调整。


三、HPA 与 Requests 的关系#

这是本节最重要的知识点之一。

前面我们学习了:

PRTCL // YAML
resources:
requests:
cpu: "500m"
limits:
cpu: "1"

现在假设:

PRTCL // TEXT
CPU Requests:500m
CPU 实际使用:250m

CPU 使用率是多少?

[ \frac{250m}{500m}\times100%=50% ]

因此:

HPA 使用 CPU Utilization 时,通常是根据实际 CPU 使用量与 CPU Requests 的比例计算使用率。

不是简单根据 CPU Limits 计算。

1. CPU Utilization 计算#

假设:

PodCPU Requests实际 CPU 使用
Pod-1500m250m
Pod-2500m400m
Pod-3500m350m

平均 CPU 使用率:

[ \frac{250+400+350}{500\times3}\times100% ]

结果:

[ 66.67% ]

如果 HPA 目标是 50%,则当前平均使用率已经超过目标。

2. 为什么必须设置 Requests?#

假设没有设置 CPU Requests:

PRTCL // YAML
resources: {}

那么 HPA 就无法正常计算基于 CPU Utilization 的目标使用率。

此时可能出现:

PRTCL // TEXT
FailedGetResourceMetric

或者:

PRTCL // TEXT
missing request for cpu

因此:

如果使用基于 CPU 利用率的 HPA,必须合理设置容器 CPU Requests。

内存利用率同理,需要对应的 Memory Requests。


四、Metrics Server:指标采集组件#

HPA 需要知道 Pod 当前的 CPU 和内存使用情况。

这些数据从哪里来?

答案是 Metrics Server。

1. 什么是 Metrics Server?#

Metrics Server 是 Kubernetes 集群中的资源指标采集组件。

它主要负责:

  • 收集节点 CPU 使用情况。
  • 收集节点内存使用情况。
  • 收集 Pod CPU 使用情况。
  • 收集 Pod 内存使用情况。
  • 向 Metrics API 提供资源指标。

数据链路:

flowchart TB
    N0["Node"]
    N1["kubelet"]
    N2["容器运行时 / 容器资源统计"]
    N3["Metrics Server"]
    N4["Metrics API"]
    N5["HPA Controller"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4
    N4 --> N5

注意:

Metrics Server 主要提供短期资源使用指标,不是长期历史监控系统。

如果需要长期保存指标、查询历史趋势和构建复杂监控面板,通常使用 Prometheus。

2. 如何检查 Metrics Server?#

执行:

PRTCL // BASH
Terminal window
kubectl get pods -n kube-system

查看是否存在:

PRTCL // TEXT
metrics-server

检查 API:

PRTCL // BASH
Terminal window
kubectl get apiservices | grep metrics

正常情况下会看到:

PRTCL // TEXT
v1beta1.metrics.k8s.io

并且状态为:

PRTCL // TEXT
True

3. 查看节点资源使用#

PRTCL // BASH
Terminal window
kubectl top nodes

示例:

PRTCL // TEXT
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
worker-1 1200m 15% 4096Mi 25%
worker-2 800m 10% 2048Mi 12%

4. 查看 Pod 资源使用#

PRTCL // BASH
Terminal window
kubectl top pods

指定 Namespace:

PRTCL // BASH
Terminal window
kubectl top pods -n default

查看容器级别:

PRTCL // BASH
Terminal window
kubectl top pods --containers

如果执行:

PRTCL // BASH
Terminal window
kubectl top pods

出现:

PRTCL // TEXT
error: Metrics API not available

通常需要检查:

  1. Metrics Server 是否安装。
  2. Metrics Server 是否正常运行。
  3. kubelet 是否可以被 Metrics Server 访问。
  4. TLS 证书和网络连接是否正常。
  5. Metrics APIService 是否可用。

五、HPA 创建命令与状态字段#

1. 创建 HPA#

使用命令创建:

PRTCL // BASH
Terminal window
kubectl autoscale deployment nginx \
--cpu-percent=50 \
--min=2 \
--max=10

参数解释:

参数含义
--cpu-percent=50CPU 目标使用率 50%
--min=2最少 2 个 Pod
--max=10最多 10 个 Pod

2. 查看 HPA#

PRTCL // BASH
Terminal window
kubectl get hpa

示例:

PRTCL // TEXT
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
nginx Deployment/nginx 20%/50% 2 10 2

字段解释:

字段含义
NAMEHPA 名称
REFERENCE被控制的工作负载
TARGETS当前指标与目标指标
MINPODS最小副本
MAXPODS最大副本
REPLICAS当前副本

例如:

PRTCL // TEXT
20%/50%

表示:

PRTCL // TEXT
当前 CPU 使用率:20%
目标 CPU 使用率:50%

当前负载较低,因此没有扩容需求。

3. 查看详细信息#

PRTCL // BASH
Terminal window
kubectl describe hpa nginx

重点查看:

PRTCL // TEXT
Metrics:
Resource cpu on pods:
20% / 50%
Min replicas: 2
Max replicas: 10
Events:

Events 可以帮助排查扩缩容失败的原因。

六、使用 YAML 创建 HPA(推荐生产方式)#

实际生产环境通常使用 YAML 管理 HPA,而不是仅依赖命令行创建。

Kubernetes 推荐使用:

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

创建:

PRTCL // BASH
Terminal window
kubectl apply -f nginx-hpa.yaml

1. scaleTargetRef#

PRTCL // YAML
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx

表示 HPA 要控制哪个工作负载。

这里控制的是:

PRTCL // TEXT
Deployment/nginx

除了 Deployment,HPA 还可以控制其他实现 Scale 子资源的工作负载,例如 StatefulSet。

2. minReplicas#

PRTCL // YAML
minReplicas: 2

最少保留 2 个 Pod。

即使 CPU 使用率很低,也不会缩容到 2 个以下。

3. maxReplicas#

PRTCL // YAML
maxReplicas: 10

最多允许 10 个 Pod。

即使 CPU 使用率非常高,也不会超过 10 个。

4. metrics#

PRTCL // YAML
metrics:
- type: Resource

表示使用 Kubernetes 资源指标。

例如:

  • CPU。
  • Memory。

5. averageUtilization#

PRTCL // YAML
target:
type: Utilization
averageUtilization: 50

表示所有相关 Pod 的平均 CPU 使用率目标为 50%。

这里的百分比基于对应容器的 Requests 计算。


七、HPA 支持哪些指标类型?#

HPA 并不只支持 CPU。

在 autoscaling/v2 中,主要支持以下四类指标:

类型含义示例
ResourcePod 资源指标CPU、Memory
ContainerResource单个容器资源指标指定容器 CPU
PodsPod 自定义指标每个 Pod 的请求数
ObjectKubernetes 对象指标Ingress 请求速率
External外部指标消息队列长度、外部系统指标

注意:这里实际共有五种指标类型。

1. Resource:资源指标#

例如:

PRTCL // YAML
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60

表示:

根据 Pod 平均 CPU 使用率进行扩缩容。

也可以使用内存:

PRTCL // YAML
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70

表示:

平均内存使用率达到目标值时,HPA 根据指标计算期望副本数。

2. ContainerResource:容器资源指标#

假设一个 Pod 有两个容器:

flowchart TB
    N0["Pod"]
    N1["app"]
    N2["sidecar"]
    N0 --> N1
    N0 --> N2

如果只希望根据 app 容器的 CPU 使用率扩缩容,可以使用 ContainerResource。

示例:

PRTCL // YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: ContainerResource
containerResource:
name: cpu
container: app
target:
type: Utilization
averageUtilization: 60

这样就只关注:

PRTCL // TEXT
app 容器 CPU 使用率

而不是整个 Pod 所有容器的 CPU 使用情况。

3. Pods:Pod 自定义指标#

例如:

希望根据每个 Pod 平均处理的请求数扩缩容。

PRTCL // YAML
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"

含义:

希望每个 Pod 平均处理的 HTTP 请求速率为 100。

需要注意:

这里的指标并不是 Metrics Server 默认提供的,需要配置支持自定义指标的监控和适配组件。

4. Object:对象指标#

例如:

希望根据 Ingress 的请求数量进行扩缩容。

PRTCL // YAML
metrics:
- type: Object
object:
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: web-ingress
metric:
name: requests_per_second
target:
type: Value
value: "1000"

表示:

根据指定 Ingress 对象关联的指标进行扩缩容。

5. External:外部指标#

这是非常实用的一类。

例如:

系统使用 RabbitMQ 作为消息队列。

我们希望:

flowchart TB
    N0["消息积压数量越多"]
    N1["增加消费者 Pod"]
    N2["加快消息处理"]
    N0 --> N1
    N1 --> N2

可以使用 External 指标:

PRTCL // YAML
metrics:
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: order-queue
target:
type: AverageValue
averageValue: "30"

表示:

根据订单队列中待处理消息数量进行扩缩容。

注意:

外部指标需要对应的 Metrics Adapter 提供数据,HPA 不会直接访问 RabbitMQ。

6. 五种指标类型总结#

HPA 指标体系

Resource Pod CPU、Memory

ContainerResource 指定容器 CPU、Memory

Pods Pod 平均自定义指标

Object Kubernetes 对象指标

External 外部系统指标


八、HPA 多指标扩缩容#

生产环境中,单独使用 CPU 指标可能不够。

例如:

某个 Web 应用:

  • CPU 使用率只有 30%。
  • 内存使用率已经达到 85%。

如果只监控 CPU,可能无法及时扩容。

因此可以同时配置 CPU 和 Memory。

示例:

PRTCL // YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70

那么 HPA 如何决定副本数量?

它会分别计算每个指标需要的副本数,然后选择其中最大的结果。

例如:

PRTCL // TEXT
当前副本:4
CPU 指标计算:
需要 6 个 Pod
Memory 指标计算:
需要 9 个 Pod

最终:

PRTCL // TEXT
Desired Replicas = 9

为什么?

因为内存指标要求更多副本。

这种机制可以避免某一个指标已经过载,而其他指标正常时仍然不扩容。


九、HPA 扩缩容行为控制(behavior)#

前面我们已经知道:

HPA 可以根据指标自动增加或减少 Pod。

但生产环境还会遇到一个问题:

假设业务流量在短时间内不断变化:

PRTCL // TEXT
10:00 CPU 20%
10:01 CPU 90%
10:02 CPU 30%
10:03 CPU 85%
10:04 CPU 25%

如果 HPA 每次都立即调整副本数量,可能出现:

  • 短时间内频繁扩容。
  • 短时间内频繁缩容。
  • Pod 数量反复波动。
  • 业务资源不稳定。

这种现象叫作扩缩容抖动。

Kubernetes 提供了 behavior 来控制扩缩容行为。

1. behavior 的结构#

PRTCL // YAML
behavior:
scaleUp:
stabilizationWindowSeconds: 0
scaleDown:
stabilizationWindowSeconds: 300

其中:

  • scaleUp:控制扩容行为。
  • scaleDown:控制缩容行为。
  • stabilizationWindowSeconds:稳定窗口。

2. stabilizationWindowSeconds:稳定窗口#

这是一个非常重要的参数。

例如:

PRTCL // YAML
behavior:
scaleDown:
stabilizationWindowSeconds: 300

表示:

缩容时考虑最近 300 秒的指标建议,避免因为短时间指标下降就立即缩容。

例如:

PRTCL // TEXT
10:00 CPU 90%
10:01 CPU 30%
10:02 CPU 25%
10:03 CPU 20%

如果没有稳定窗口,HPA 可能很快缩容。

设置 300 秒稳定窗口后,HPA 会综合最近 5 分钟的推荐副本数,避免过快缩容。

注意:

稳定窗口不是简单地等待 300 秒后无条件执行缩容,而是通过历史推荐副本数进行稳定处理。

对于缩容,通常采用最近窗口内较大的推荐副本数,以避免过快减少副本。

3. scaleUp:控制扩容速度#

例如:

PRTCL // YAML
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 4
periodSeconds: 60
selectPolicy: Max

解释:

配置含义
Percent按当前副本比例扩容
Pods按 Pod 数量扩容
value扩容幅度
periodSeconds策略计算周期
selectPolicy如何选择策略

这里有两条扩容规则:

第一条:

PRTCL // YAML
type: Percent
value: 100
periodSeconds: 60

表示每 60 秒最多允许扩容当前副本数量的 100%。

第二条:

PRTCL // YAML
type: Pods
value: 4
periodSeconds: 60

表示每 60 秒最多增加 4 个 Pod。

4. selectPolicy:如何选择扩容策略?#

有三个常见取值:

取值含义
Max选择允许扩容幅度最大的策略
Min选择允许扩容幅度最小的策略
Disabled禁用对应方向的扩缩容

例如:

PRTCL // YAML
selectPolicy: Max

表示:

选择扩容速度较快的策略。

假设:

PRTCL // TEXT
当前 Pod:4
Percent:最多增加 4 个
Pods:最多增加 4 个

那么两种策略都允许增加 4 个。

如果当前 Pod 是 10 个:

PRTCL // TEXT
Percent:最多增加 10 个
Pods:最多增加 4 个

Max 会选择允许增加 10 个的策略。

5. scaleDown:控制缩容速度#

例如:

PRTCL // YAML
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Min

表示:

  • 缩容时观察最近 5 分钟的推荐值。
  • 每 60 秒最多减少当前副本数的 50%。
  • 每 60 秒最多减少 2 个 Pod。
  • 选择缩容幅度较小的策略。

这样可以避免业务流量突然下降时,Pod 被大量删除。

6. 完整 HPA behavior 示例#

PRTCL // YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 4
periodSeconds: 60
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Min

生产环境中常见的思路是:

  • 扩容要及时,避免业务过载。
  • 缩容要谨慎,避免流量短暂下降导致副本过早减少。

十、HPA 的容差机制(Tolerance)#

HPA 不会因为 CPU 使用率从 50% 变成 51%,就立即调整副本数量。

因为微小的指标波动不应该触发频繁扩缩容。

Kubernetes HPA 有容差机制(Tolerance)。

默认情况下,常见的全局容差为 10%。

例如:

PRTCL // TEXT
目标 CPU:50%
实际 CPU:48%

变化幅度很小,通常不会触发扩缩容。

再例如:

PRTCL // TEXT
目标 CPU:50%
实际 CPU:90%

明显超过目标,才会考虑扩容。

注意:

较新版本的 Kubernetes 支持通过 HPA 的 behavior 中的 tolerance 设置更细粒度的容差;具体能力需要结合集群版本。全局容差也可以由 kube-controller-manager 配置。


十一、HPA 与 Deployment 的关系#

这里有一个非常重要的生产实践问题。

假设:

Deployment YAML:

PRTCL // YAML
spec:
replicas: 3

同时存在 HPA:

PRTCL // YAML
minReplicas: 2
maxReplicas: 10

当前 HPA 已经将副本扩展到:

PRTCL // TEXT
replicas: 8

现在你重新执行:

PRTCL // BASH
Terminal window
kubectl apply -f deployment.yaml

Deployment 的 replicas 会不会被重新设置为 3?

这涉及声明式管理与 HPA 的控制权问题。

1. 为什么会出现冲突?#

Deployment 的 YAML 中声明:

PRTCL // YAML
replicas: 3

HPA 又在动态修改:

PRTCL // TEXT
replicas: 8

于是形成:

PRTCL // TEXT
Deployment YAML:3
HPA:动态调整

如果持续通过声明式配置覆盖副本数量,就可能干扰 HPA。

2. 生产环境如何处理?#

当 HPA 接管副本数量管理后,建议避免持续将固定 replicas 值作为部署配置的管理目标。

例如:

PRTCL // YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
resources:
requests:
cpu: 100m

然后单独使用 HPA 管理副本数量。

在使用 Helm、GitOps 等工具时,也需要专门配置副本字段的管理策略,避免它们与 HPA 发生控制权冲突。

核心原则:Deployment 管理 Pod 模板,HPA 管理动态副本数量。


十二、HPA 与 Prometheus 自定义指标#

现在进入生产环境中更加重要的内容。

前面我们学习了 Metrics Server。

但 Metrics Server 主要提供:

  • CPU。
  • Memory。

实际业务可能还需要根据其他指标进行扩缩容。

例如:

业务场景扩缩容指标
电商网站HTTP 请求速率
消息系统RabbitMQ 队列长度
视频处理待处理视频数量
AI 推理GPU 利用率
数据处理Kafka 消息积压量
数据库代理活跃连接数

这些指标如何提供给 HPA?

通常需要:

Prometheus + Prometheus Adapter + Kubernetes Custom Metrics API。

1. 整体架构#

工作流程:

flowchart TB
    N0["业务应用"]
    N1["暴露业务指标"]
    N2["Prometheus"]
    N3["Prometheus Adapter"]
    N4["Custom Metrics API"]
    N5["HPA"]
    N6["Deployment"]
    N7["增加或减少 Pod"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4
    N4 --> N5
    N5 --> N6
    N6 --> N7

各组件职责:

组件作用
Prometheus采集和存储指标
Prometheus Adapter将指标转换为 Kubernetes 可识别的 API
Custom Metrics API提供 Pod 自定义指标
HPA根据指标计算副本数

2. 实际业务示例:HTTP 请求数扩缩容#

假设一个 Web 应用:

PRTCL // TEXT
每个 Pod 平均处理 100 请求 / 秒

我们希望:

PRTCL // TEXT
每个 Pod 平均请求速率目标:100 RPS

HPA 配置:

PRTCL // YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"

假设:

PRTCL // TEXT
当前 Pod:2
每个 Pod 平均请求:250 RPS
目标:100 RPS

计算:

[ \left\lceil 2\times\frac{250}{100}\right\rceil=5 ]

HPA 会尝试扩容到 5 个 Pod。

注意:

这里的 Prometheus Adapter 必须正确暴露 http_requests_per_second 这一指标,并且指标的采集、聚合及标签映射都要与 HPA 查询要求一致。


十三、HPA、VPA 与 Cluster Autoscaler 的区别#

Kubernetes 自动伸缩体系中,除了 HPA,还有两个重要组件:

  • VPA:Vertical Pod Autoscaler。
  • Cluster Autoscaler:集群节点自动伸缩。

三者解决的问题不同。

1. HPA:水平扩缩容#

HPA 通过增加或减少 Pod 副本数量来扩缩容。

例如:

flowchart TB
    subgraph G0["扩容前"]
        direction TB
        N0["Node-1"]
        N1["Web-1"]
        N2["Web-2"]
    end
    subgraph G1["扩容后"]
        direction TB
        N3["Node-1"]
        N4["Web-1"]
        N5["Web-2"]
        N6["Node-2"]
        N7["Web-3"]
        N8["Web-4"]
    end
    N0 --> N1
    N0 --> N2
    N3 --> N4
    N3 --> N5
    N6 --> N7
    N6 --> N8

特点:

  • 增加 Pod 数量。
  • 减少 Pod 数量。
  • 适合无状态应用。
  • 可以根据 CPU、Memory 和自定义指标扩缩容。

2. VPA:垂直扩缩容#

VPA 全称 Vertical Pod Autoscaler。

它不是增加 Pod 数量,而是调整 Pod 的资源请求和限制建议。

例如:

原来:

PRTCL // YAML
resources:
requests:
cpu: 500m
memory: 512Mi

VPA 根据历史使用情况发现应用需要更多资源,建议调整为:

PRTCL // YAML
resources:
requests:
cpu: "1"
memory: "1Gi"

特点:

  • 调整单个 Pod 的资源配置。
  • 适合资源需求不容易预估的应用。
  • 某些更新模式可能需要重新创建 Pod。
  • 需要部署 VPA 组件。

3. Cluster Autoscaler:节点自动扩缩容#

Cluster Autoscaler 负责调整 Kubernetes 集群的 Node 数量。

例如:

当前集群:

PRTCL // TEXT
Node-1
Node-2

现在 HPA 将 Pod 从 4 个增加到 20 个。

但是节点资源不足:

flowchart TB
    N0["Pod Pending"]
    N1["Cluster Autoscaler 检查"]
    N2["发现新增节点可以解决资源不足"]
    N3["向底层云平台申请节点"]
    N4["新增 Node-3"]
    N5["Pod 被重新调度"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4
    N4 --> N5

注意:

Cluster Autoscaler 通常需要对接云平台的节点组或自动伸缩组,不能仅凭 Kubernetes 自身就凭空创建物理服务器。

4. 三者对比#

组件扩缩容对象调整方式
HPAPod 副本横向增加或减少
VPAPod 资源纵向调整 CPU、Memory
Cluster AutoscalerNode增加或减少节点

Kubernetes 自动伸缩体系

HPA 增加 Pod

VPA 调整资源

CA 增加 Node

5. HPA 与 VPA 可以同时使用吗?#

可以,但需要注意资源管理冲突。

例如:

HPA 根据 CPU Utilization 扩缩容。

VPA 同时调整 CPU Requests。

而 CPU Utilization 的计算依赖 Requests:

[ CPU 利用率 =\frac{实际 CPU 使用量}{CPU Requests} ]

如果 VPA 不断调整 Requests,HPA 计算出的 CPU 利用率也会发生变化。

可能导致扩缩容行为不稳定。

生产环境常见做法:

  • HPA 负责副本数量。
  • VPA 负责资源推荐。
  • 避免同时让两者争夺同一个 CPU 或内存指标的控制权。

可以根据具体场景使用 VPA 的推荐模式,或者明确区分两者管理的资源维度。


十四、HPA 故障排查#

实际工作中,HPA 可能出现以下问题。

1. HPA 显示 unknown#

执行:

PRTCL // BASH
Terminal window
kubectl get hpa

可能看到:

PRTCL // TEXT
NAME TARGETS
nginx <unknown>/50%

常见原因:

  • Metrics Server 没有正常运行。
  • Metrics API 不可用。
  • Pod 没有设置 CPU Requests。
  • Pod 尚未产生有效指标。
  • 指标采集失败。

排查:

PRTCL // BASH
Terminal window
kubectl top pods

如果这个命令也失败,首先检查 Metrics Server。

2. HPA 没有扩容#

查看:

PRTCL // BASH
Terminal window
kubectl describe hpa nginx-hpa

重点关注:

PRTCL // TEXT
Conditions:
Events:

常见原因:

  1. CPU 使用率没有达到扩容条件。
  2. 已达到 maxReplicas。
  3. 缺少 Requests。
  4. Metrics API 不可用。
  5. HPA 的指标配置错误。
  6. 扩容行为策略限制了扩容速度。

3. HPA 已扩容,但是 Pod 一直 Pending#

例如:

PRTCL // TEXT
Deployment:10 个副本
Running:5 个
Pending:5 个

这说明:

HPA 已经成功增加了期望副本数量,但是集群可能没有足够的节点资源。

检查:

PRTCL // BASH
Terminal window
kubectl describe pod <pod-name>

如果看到:

PRTCL // TEXT
FailedScheduling
Insufficient cpu

说明节点 CPU 不足。

解决方向:

  • 增加节点。
  • 调整 Pod Requests。
  • 使用 Cluster Autoscaler。
  • 优化资源配置。
  • 检查节点亲和性和污点约束。

4. HPA 频繁扩缩容#

可能原因:

  • 指标波动较大。
  • 缩容稳定窗口设置过短。
  • 扩缩容策略不合理。
  • CPU Requests 配置不合理。
  • 业务流量存在明显周期性波动。

解决方式:

合理设置:

PRTCL // YAML
behavior:
scaleUp:
stabilizationWindowSeconds: 0
scaleDown:
stabilizationWindowSeconds: 300

必要时调整:

  • 扩容百分比。
  • 缩容数量。
  • 稳定窗口。
  • 容差。

5. HPA 常见故障总结#

故障排查方向
TARGETS 显示 unknownMetrics Server、Requests
无法获取 CPU 指标Metrics API
没有扩容目标值、maxReplicas
扩容后 Pod Pending节点资源
频繁扩缩容behavior、指标波动
自定义指标不可用Prometheus Adapter、APIService

十五、本节 CKA 必须掌握的命令#

操作命令
创建 HPAkubectl autoscale deployment nginx --cpu-percent=50 --min=2 --max=10
查看 HPAkubectl get hpa
查看详细信息kubectl describe hpa nginx-hpa
删除 HPAkubectl delete hpa nginx-hpa
查看 Pod 指标kubectl top pods
查看节点指标kubectl top nodes
查看 Metrics APIkubectl get apiservices
查看 Metrics Serverkubectl get pods -n kube-system
查看 Deployment 副本kubectl get deployment
查看实时扩缩容kubectl get hpa -w

十六、本节知识体系总结#

HPA 自动扩缩容体系

flowchart TB
    N0["业务负载变化<br/>CPU、Memory、HTTP 请求、消息队列"]
    N1["Metrics Server / Metrics Adapter<br/>采集和提供指标"]
    N2["HPA Controller<br/>计算期望副本数量"]
    N3["Deployment / ReplicaSet<br/>调整副本数量"]
    N4["Pod 自动扩缩容"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4

核心参数

参数作用
minReplicas最小副本
maxReplicas最大副本
metrics扩缩容指标
averageUtilization平均资源利用率
averageValue平均指标目标值
scaleUp扩容策略
scaleDown缩容策略
stabilizationWindowSeconds稳定窗口
selectPolicy策略选择
归档于 2026.08.09
// 档案结束
Classified
章节_06
协议编号: CC-BY-NC-SA-4.0

HPA:基于指标的 Pod 水平扩缩容

作者:Chavy发布日期:2026.08.09

基于 CC BY-NC-SA 4.0

© 2026 Chavy
Powered by Astro