摘要:从指标采集和副本计算理解 HPA,掌握资源请求、资源与自定义指标、多指标决策、扩缩容行为和稳定窗口的配置及排查。
本节学习 Kubernetes 自动伸缩机制中的核心组件:HPA(Horizontal Pod Autoscaler,水平 Pod 自动扩缩容器)。
Deployment 可以通过设置:
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:
replicas: 2CPU 目标使用率:
50%当前 CPU 使用率:
100%那么 HPA 会认为当前 Pod 负载过高,需要增加副本。
HPA 使用的核心计算公式:
[ DesiredReplicas = \left\lceil CurrentReplicas \times \frac{CurrentMetric}{DesiredMetric} \right\rceil ]
其中:
- CurrentReplicas:当前 Pod 副本数量。
- CurrentMetric:当前指标值。
- DesiredMetric:目标指标值。
2. 计算示例
当前:
Pod 数量:2CPU 使用率:100%目标 CPU 使用率:50%代入:
[ \left\lceil 2\times\frac{100}{50}\right\rceil =4 ]
因此:
当前副本:2目标副本:4HPA 会尝试将副本数量调整为 4。
3. 再看一个例子
当前:
Pod 数量:4CPU 使用率:25%目标 CPU 使用率:50%计算:
[ \left\lceil 4\times\frac{25}{50}\right\rceil =2 ]
因此:
当前副本:4目标副本:2HPA 会尝试减少副本。
4. 为什么使用向上取整?
例如:
当前 Pod:3当前 CPU:60%目标 CPU:50%计算:
[ 3\times\frac{60}{50}=3.6 ]
实际副本不能是 3.6 个,因此需要向上取整:
目标副本:4这样才能满足扩容需求。
注意:这是理解 HPA 的基础计算公式。实际控制器还会考虑容差范围、指标采集误差、缺失指标、扩缩容稳定窗口和副本上下限等因素,并非每次都直接按照公式调整。
三、HPA 与 Requests 的关系
这是本节最重要的知识点之一。
前面我们学习了:
resources: requests: cpu: "500m"
limits: cpu: "1"现在假设:
CPU Requests:500mCPU 实际使用:250mCPU 使用率是多少?
[ \frac{250m}{500m}\times100%=50% ]
因此:
HPA 使用 CPU Utilization 时,通常是根据实际 CPU 使用量与 CPU Requests 的比例计算使用率。
不是简单根据 CPU Limits 计算。
1. CPU Utilization 计算
假设:
| Pod | CPU Requests | 实际 CPU 使用 |
|---|---|---|
| Pod-1 | 500m | 250m |
| Pod-2 | 500m | 400m |
| Pod-3 | 500m | 350m |
平均 CPU 使用率:
[ \frac{250+400+350}{500\times3}\times100% ]
结果:
[ 66.67% ]
如果 HPA 目标是 50%,则当前平均使用率已经超过目标。
2. 为什么必须设置 Requests?
假设没有设置 CPU Requests:
resources: {}那么 HPA 就无法正常计算基于 CPU Utilization 的目标使用率。
此时可能出现:
FailedGetResourceMetric或者:
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?
执行:
kubectl get pods -n kube-system查看是否存在:
metrics-server检查 API:
kubectl get apiservices | grep metrics正常情况下会看到:
v1beta1.metrics.k8s.io并且状态为:
True3. 查看节点资源使用
kubectl top nodes示例:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%worker-1 1200m 15% 4096Mi 25%worker-2 800m 10% 2048Mi 12%4. 查看 Pod 资源使用
kubectl top pods指定 Namespace:
kubectl top pods -n default查看容器级别:
kubectl top pods --containers如果执行:
kubectl top pods出现:
error: Metrics API not available通常需要检查:
- Metrics Server 是否安装。
- Metrics Server 是否正常运行。
- kubelet 是否可以被 Metrics Server 访问。
- TLS 证书和网络连接是否正常。
- Metrics APIService 是否可用。
五、HPA 创建命令与状态字段
1. 创建 HPA
使用命令创建:
kubectl autoscale deployment nginx \ --cpu-percent=50 \ --min=2 \ --max=10参数解释:
| 参数 | 含义 |
|---|---|
--cpu-percent=50 | CPU 目标使用率 50% |
--min=2 | 最少 2 个 Pod |
--max=10 | 最多 10 个 Pod |
2. 查看 HPA
kubectl get hpa示例:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICASnginx Deployment/nginx 20%/50% 2 10 2字段解释:
| 字段 | 含义 |
|---|---|
| NAME | HPA 名称 |
| REFERENCE | 被控制的工作负载 |
| TARGETS | 当前指标与目标指标 |
| MINPODS | 最小副本 |
| MAXPODS | 最大副本 |
| REPLICAS | 当前副本 |
例如:
20%/50%表示:
当前 CPU 使用率:20%目标 CPU 使用率:50%当前负载较低,因此没有扩容需求。
3. 查看详细信息
kubectl describe hpa nginx重点查看:
Metrics: Resource cpu on pods: 20% / 50%
Min replicas: 2Max replicas: 10
Events:Events 可以帮助排查扩缩容失败的原因。
六、使用 YAML 创建 HPA(推荐生产方式)
实际生产环境通常使用 YAML 管理 HPA,而不是仅依赖命令行创建。
Kubernetes 推荐使用:
apiVersion: autoscaling/v2kind: 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创建:
kubectl apply -f nginx-hpa.yaml1. scaleTargetRef
scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx表示 HPA 要控制哪个工作负载。
这里控制的是:
Deployment/nginx除了 Deployment,HPA 还可以控制其他实现 Scale 子资源的工作负载,例如 StatefulSet。
2. minReplicas
minReplicas: 2最少保留 2 个 Pod。
即使 CPU 使用率很低,也不会缩容到 2 个以下。
3. maxReplicas
maxReplicas: 10最多允许 10 个 Pod。
即使 CPU 使用率非常高,也不会超过 10 个。
4. metrics
metrics: - type: Resource表示使用 Kubernetes 资源指标。
例如:
- CPU。
- Memory。
5. averageUtilization
target: type: Utilization averageUtilization: 50表示所有相关 Pod 的平均 CPU 使用率目标为 50%。
这里的百分比基于对应容器的 Requests 计算。
七、HPA 支持哪些指标类型?
HPA 并不只支持 CPU。
在 autoscaling/v2 中,主要支持以下四类指标:
| 类型 | 含义 | 示例 |
|---|---|---|
| Resource | Pod 资源指标 | CPU、Memory |
| ContainerResource | 单个容器资源指标 | 指定容器 CPU |
| Pods | Pod 自定义指标 | 每个 Pod 的请求数 |
| Object | Kubernetes 对象指标 | Ingress 请求速率 |
| External | 外部指标 | 消息队列长度、外部系统指标 |
注意:这里实际共有五种指标类型。
1. Resource:资源指标
例如:
metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60表示:
根据 Pod 平均 CPU 使用率进行扩缩容。
也可以使用内存:
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。
示例:
apiVersion: autoscaling/v2kind: 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这样就只关注:
app 容器 CPU 使用率而不是整个 Pod 所有容器的 CPU 使用情况。
3. Pods:Pod 自定义指标
例如:
希望根据每个 Pod 平均处理的请求数扩缩容。
metrics: - type: Pods
pods: metric: name: http_requests_per_second
target: type: AverageValue averageValue: "100"含义:
希望每个 Pod 平均处理的 HTTP 请求速率为 100。
需要注意:
这里的指标并不是 Metrics Server 默认提供的,需要配置支持自定义指标的监控和适配组件。
4. Object:对象指标
例如:
希望根据 Ingress 的请求数量进行扩缩容。
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 指标:
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。
示例:
apiVersion: autoscaling/v2kind: 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 如何决定副本数量?
它会分别计算每个指标需要的副本数,然后选择其中最大的结果。
例如:
当前副本:4
CPU 指标计算:需要 6 个 Pod
Memory 指标计算:需要 9 个 Pod最终:
Desired Replicas = 9为什么?
因为内存指标要求更多副本。
这种机制可以避免某一个指标已经过载,而其他指标正常时仍然不扩容。
九、HPA 扩缩容行为控制(behavior)
前面我们已经知道:
HPA 可以根据指标自动增加或减少 Pod。
但生产环境还会遇到一个问题:
假设业务流量在短时间内不断变化:
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 的结构
behavior: scaleUp: stabilizationWindowSeconds: 0
scaleDown: stabilizationWindowSeconds: 300其中:
- scaleUp:控制扩容行为。
- scaleDown:控制缩容行为。
- stabilizationWindowSeconds:稳定窗口。
2. stabilizationWindowSeconds:稳定窗口
这是一个非常重要的参数。
例如:
behavior: scaleDown: stabilizationWindowSeconds: 300表示:
缩容时考虑最近 300 秒的指标建议,避免因为短时间指标下降就立即缩容。
例如:
10:00 CPU 90%10:01 CPU 30%10:02 CPU 25%10:03 CPU 20%如果没有稳定窗口,HPA 可能很快缩容。
设置 300 秒稳定窗口后,HPA 会综合最近 5 分钟的推荐副本数,避免过快缩容。
注意:
稳定窗口不是简单地等待 300 秒后无条件执行缩容,而是通过历史推荐副本数进行稳定处理。
对于缩容,通常采用最近窗口内较大的推荐副本数,以避免过快减少副本。
3. scaleUp:控制扩容速度
例如:
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 | 如何选择策略 |
这里有两条扩容规则:
第一条:
type: Percentvalue: 100periodSeconds: 60表示每 60 秒最多允许扩容当前副本数量的 100%。
第二条:
type: Podsvalue: 4periodSeconds: 60表示每 60 秒最多增加 4 个 Pod。
4. selectPolicy:如何选择扩容策略?
有三个常见取值:
| 取值 | 含义 |
|---|---|
| Max | 选择允许扩容幅度最大的策略 |
| Min | 选择允许扩容幅度最小的策略 |
| Disabled | 禁用对应方向的扩缩容 |
例如:
selectPolicy: Max表示:
选择扩容速度较快的策略。
假设:
当前 Pod:4
Percent:最多增加 4 个Pods:最多增加 4 个那么两种策略都允许增加 4 个。
如果当前 Pod 是 10 个:
Percent:最多增加 10 个Pods:最多增加 4 个Max 会选择允许增加 10 个的策略。
5. scaleDown:控制缩容速度
例如:
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 示例
apiVersion: autoscaling/v2kind: 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%。
例如:
目标 CPU:50%
实际 CPU:48%变化幅度很小,通常不会触发扩缩容。
再例如:
目标 CPU:50%
实际 CPU:90%明显超过目标,才会考虑扩容。
注意:
较新版本的 Kubernetes 支持通过 HPA 的 behavior 中的 tolerance 设置更细粒度的容差;具体能力需要结合集群版本。全局容差也可以由 kube-controller-manager 配置。
十一、HPA 与 Deployment 的关系
这里有一个非常重要的生产实践问题。
假设:
Deployment YAML:
spec: replicas: 3同时存在 HPA:
minReplicas: 2maxReplicas: 10当前 HPA 已经将副本扩展到:
replicas: 8现在你重新执行:
kubectl apply -f deployment.yamlDeployment 的 replicas 会不会被重新设置为 3?
这涉及声明式管理与 HPA 的控制权问题。
1. 为什么会出现冲突?
Deployment 的 YAML 中声明:
replicas: 3HPA 又在动态修改:
replicas: 8于是形成:
Deployment YAML:3HPA:动态调整如果持续通过声明式配置覆盖副本数量,就可能干扰 HPA。
2. 生产环境如何处理?
当 HPA 接管副本数量管理后,建议避免持续将固定 replicas 值作为部署配置的管理目标。
例如:
apiVersion: apps/v1kind: 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 应用:
每个 Pod 平均处理 100 请求 / 秒我们希望:
每个 Pod 平均请求速率目标:100 RPSHPA 配置:
apiVersion: autoscaling/v2kind: 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"假设:
当前 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 的资源请求和限制建议。
例如:
原来:
resources: requests: cpu: 500m memory: 512MiVPA 根据历史使用情况发现应用需要更多资源,建议调整为:
resources: requests: cpu: "1" memory: "1Gi"特点:
- 调整单个 Pod 的资源配置。
- 适合资源需求不容易预估的应用。
- 某些更新模式可能需要重新创建 Pod。
- 需要部署 VPA 组件。
3. Cluster Autoscaler:节点自动扩缩容
Cluster Autoscaler 负责调整 Kubernetes 集群的 Node 数量。
例如:
当前集群:
Node-1Node-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. 三者对比
| 组件 | 扩缩容对象 | 调整方式 |
|---|---|---|
| HPA | Pod 副本 | 横向增加或减少 |
| VPA | Pod 资源 | 纵向调整 CPU、Memory |
| Cluster Autoscaler | Node | 增加或减少节点 |
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
执行:
kubectl get hpa可能看到:
NAME TARGETSnginx <unknown>/50%常见原因:
- Metrics Server 没有正常运行。
- Metrics API 不可用。
- Pod 没有设置 CPU Requests。
- Pod 尚未产生有效指标。
- 指标采集失败。
排查:
kubectl top pods如果这个命令也失败,首先检查 Metrics Server。
2. HPA 没有扩容
查看:
kubectl describe hpa nginx-hpa重点关注:
Conditions:Events:常见原因:
- CPU 使用率没有达到扩容条件。
- 已达到 maxReplicas。
- 缺少 Requests。
- Metrics API 不可用。
- HPA 的指标配置错误。
- 扩容行为策略限制了扩容速度。
3. HPA 已扩容,但是 Pod 一直 Pending
例如:
Deployment:10 个副本Running:5 个Pending:5 个这说明:
HPA 已经成功增加了期望副本数量,但是集群可能没有足够的节点资源。
检查:
kubectl describe pod <pod-name>如果看到:
FailedSchedulingInsufficient cpu说明节点 CPU 不足。
解决方向:
- 增加节点。
- 调整 Pod Requests。
- 使用 Cluster Autoscaler。
- 优化资源配置。
- 检查节点亲和性和污点约束。
4. HPA 频繁扩缩容
可能原因:
- 指标波动较大。
- 缩容稳定窗口设置过短。
- 扩缩容策略不合理。
- CPU Requests 配置不合理。
- 业务流量存在明显周期性波动。
解决方式:
合理设置:
behavior: scaleUp: stabilizationWindowSeconds: 0
scaleDown: stabilizationWindowSeconds: 300必要时调整:
- 扩容百分比。
- 缩容数量。
- 稳定窗口。
- 容差。
5. HPA 常见故障总结
| 故障 | 排查方向 |
|---|---|
| TARGETS 显示 unknown | Metrics Server、Requests |
| 无法获取 CPU 指标 | Metrics API |
| 没有扩容 | 目标值、maxReplicas |
| 扩容后 Pod Pending | 节点资源 |
| 频繁扩缩容 | behavior、指标波动 |
| 自定义指标不可用 | Prometheus Adapter、APIService |
十五、本节 CKA 必须掌握的命令
| 操作 | 命令 |
|---|---|
| 创建 HPA | kubectl autoscale deployment nginx --cpu-percent=50 --min=2 --max=10 |
| 查看 HPA | kubectl get hpa |
| 查看详细信息 | kubectl describe hpa nginx-hpa |
| 删除 HPA | kubectl delete hpa nginx-hpa |
| 查看 Pod 指标 | kubectl top pods |
| 查看节点指标 | kubectl top nodes |
| 查看 Metrics API | kubectl get apiservices |
| 查看 Metrics Server | kubectl 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 | 策略选择 |