HPA 水平自动扩缩容
核心问题:流量高峰时怎样自动增加副本,低谷时自动缩减节省成本?
自动扩缩容三种维度
| 类型 | 缩写 | 扩什么 | 触发条件 |
|---|---|---|---|
| Horizontal Pod Autoscaler | HPA | 增减 Pod 副本数 | CPU / 内存 / 自定义指标 |
| Vertical Pod Autoscaler | VPA | 调整单个 Pod 的 CPU/内存 Request | 历史使用率 |
| Cluster Autoscaler | CA | 增减节点数 | Pod Pending(资源不足) |
本节重点介绍 HPA,实际生产中三者配合使用。
HPA 工作原理
graph LR
METRICS["Metrics Server
(收集 CPU/内存指标)"] HPA["HPA Controller
(每 15 秒计算一次)"] DEP["Deployment
(调整 replicas)"] POD["Pod 副本"] METRICS -->|指标数据| HPA HPA -->|scale| DEP DEP -->|创建/删除| POD
(收集 CPU/内存指标)"] HPA["HPA Controller
(每 15 秒计算一次)"] DEP["Deployment
(调整 replicas)"] POD["Pod 副本"] METRICS -->|指标数据| HPA HPA -->|scale| DEP DEP -->|创建/删除| POD
扩缩容计算公式:
目标副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))
例:当前 2 个副本,CPU 平均 80%,目标 50%
目标副本数 = ceil(2 × 80/50) = ceil(3.2) = 4
安装 Metrics Server
HPA 基于 CPU/内存的扩缩容需要 Metrics Server:
# EKS(AWS 推荐方式)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Helm 安装
helm upgrade --install metrics-server metrics-server/metrics-server \
--namespace kube-system \
--set args[0]=--kubelet-insecure-tls # 自签证书环境(仅开发)
# 验证
kubectl top nodes
kubectl top pods -n production
基于 CPU 的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2 # 最小副本数(保证 HA)
maxReplicas: 20 # 最大副本数(防止无限扩容)
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # 目标 CPU 使用率 60%
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # 立即扩容(流量高峰响应快)
policies:
- type: Pods
value: 4
periodSeconds: 60 # 每分钟最多增加 4 个副本
scaleDown:
stabilizationWindowSeconds: 300 # 缩容等待 5 分钟(防止抖动)
policies:
- type: Percent
value: 20
periodSeconds: 60 # 每分钟最多缩减 20%
基于自定义指标的 HPA
# 基于队列长度扩缩容(需要 KEDA 或 Prometheus Adapter)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-worker
minReplicas: 1
maxReplicas: 50
metrics:
# CPU 保底
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# 自定义指标:SQS 队列消息数
- type: External
external:
metric:
name: sqs_messages_visible
selector:
matchLabels:
queue: order-processing
target:
type: AverageValue
averageValue: "30" # 每个 worker 处理 30 条消息时达到目标
KEDA:事件驱动自动扩缩容
KEDA(Kubernetes Event-Driven Autoscaling)支持更丰富的触发器,包括 SQS、Kafka、Redis、Cron 等:
# 安装 KEDA
helm repo add kedacore https://kedacore.github.io/charts
helm upgrade --install keda kedacore/keda \
--namespace keda \
--create-namespace
# ScaledObject(KEDA 的 HPA 替代)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: order-worker-scaler
namespace: production
spec:
scaleTargetRef:
name: order-worker
minReplicaCount: 0 # KEDA 支持缩到 0!(HPA 最少 1)
maxReplicaCount: 100
cooldownPeriod: 300 # 缩容冷却时间(秒)
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.ap-southeast-1.amazonaws.com/123456789/orders
awsRegion: ap-southeast-1
queueLength: "10" # 每个 worker 对应 10 条消息
authenticationRef:
name: keda-aws-creds
PodDisruptionBudget (PDB):保证可用性
PDB 防止节点维护或滚动更新时同时删除过多 Pod:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
namespace: production
spec:
selector:
matchLabels:
app: api-server
# 选择其一:
minAvailable: 2 # 任何时候至少保证 2 个 Pod 运行
# maxUnavailable: 1 # 任何时候最多 1 个 Pod 不可用
VPA(垂直扩缩容)
VPA 自动调整 Pod 的 CPU/内存 Request,适合资源需求不规律的应用:
# 安装 VPA
kubectl apply -f https://github.com/kubernetes/autoscaler/raw/master/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Off" # Off=只推荐,不自动修改 | Auto=自动更新(会重启 Pod)
resourcePolicy:
containerPolicies:
- containerName: api
minAllowed:
cpu: 50m
memory: 64Mi
maxAllowed:
cpu: 2
memory: 2Gi
# 查看 VPA 推荐值
kubectl describe vpa api-vpa -n production
# Recommendation:
# Container Recommendations:
# Container Name: api
# Lower Bound: cpu: 100m, memory: 128Mi
# Target: cpu: 250m, memory: 256Mi
# Upper Bound: cpu: 1000m, memory: 1Gi
三种扩缩容协同工作
graph TB
LOAD["流量增加
CPU 上升"] HPA["HPA
增加 Pod 数"] CA["Cluster Autoscaler
增加节点"] VPA["VPA
调整 Resource 推荐值"] LOAD -->|触发| HPA HPA -->|Pod Pending
(节点资源不足)| CA LOAD -->|长期分析| VPA VPA -->|更新下次部署的
requests 参数| HPA
CPU 上升"] HPA["HPA
增加 Pod 数"] CA["Cluster Autoscaler
增加节点"] VPA["VPA
调整 Resource 推荐值"] LOAD -->|触发| HPA HPA -->|Pod Pending
(节点资源不足)| CA LOAD -->|长期分析| VPA VPA -->|更新下次部署的
requests 参数| HPA
注意:HPA 和 VPA 不能同时自动修改同一个指标(CPU/内存),会冲突。常见做法:
- VPA 设 updateMode: "Off",只看推荐值,手动更新 requests
- 或 VPA 只管理内存,HPA 管理 CPU
下一章:Helm 应用包管理