Kubernetes HPA与VPA自动伸缩策略是集群资源管理的核心机制,前者根据负载动态调整Pod副本数,后者根据历史用量优化资源请求和限制。HPA与VPA协同配置的难点在于避免伸缩抖动、控制资源浪费率,同时保障服务在流量突增时的弹性扩容能力。
HPA自动伸缩机制与指标选择策略
HPA(Horizontal Pod Autoscaler)通过周期性查询指标并计算期望副本数来驱动水平伸缩。期望副本数的计算公式为:desiredReplicas = ceil(currentReplicas * currentMetricValue / targetMetricValue)。当当前指标值超过目标值时触发扩容,低于目标值时触发缩容。
HPA支持三种指标源:Resource指标(CPU/内存)、Pod自定义指标和外部指标。CPU指标适用于计算密集型服务,但存在滞后性——CPU饱和时请求已经在排队。对于Web服务,基于QPS或并发数的自定义指标能更早捕获负载变化。以下是同时基于CPU和内存的HPA配置:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
多指标配置下,HPA分别计算每个指标的期望副本数,取最大值作为最终目标。这种策略确保任何一个维度达到瓶颈都能触发扩容,但也可能导致副本数过度增长,需要结合behavior配置进行约束。
HPA behavior配置与伸缩抖动抑制
HPA默认的伸缩策略会因指标短期波动导致频繁扩缩容,给集群调度器带来压力并影响服务稳定性。Kubernetes 1.18引入的behavior字段允许精细控制扩缩容速率和冷却时间,是生产环境必须配置的参数。
扩容策略通常允许快速响应,缩容策略需要保守谨慎。以下配置实现秒级扩容、分钟级缩容的平滑策略:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # 扩容立即响应
policies:
- type: Percent
value: 100 # 每次最多扩容100%
periodSeconds: 15
- type: Pods
value: 4 # 或最多扩容4个Pod
periodSeconds: 15
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300 # 缩容观察5分钟
policies:
- type: Percent
value: 10 # 每次最多缩容10%
periodSeconds: 60
selectPolicy: Min
stabilizationWindowSeconds是抖动抑制的核心参数。扩容窗口设为0秒表示指标一超阈值立即扩容;缩容窗口设为300秒表示指标必须连续5分钟低于目标值才触发缩容,避免因瞬时流量回落而过早释放资源。selectPolicy设为Max时取所有策略中扩容幅度最大的,设为Min时取缩容幅度最小的。
Metrics Server部署与资源指标采集
HPA依赖Metrics Server提供CPU和内存指标,Metrics Server通过每个节点的Kubelet Summary API采集容器资源使用数据。部署前需确认集群启用了聚合层(API Aggregation),并配置正确的请求超时参数。
# 部署Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 生产环境建议调整参数以适配大规模集群
# 修改metrics-server Deployment添加启动参数
kubectl edit deployment metrics-server -n kube-system
# 关键启动参数:
# --kubelet-preferred-address-types=InternalIP # 避免DNS解析延迟
# --metric-resolution=60s # 采集间隔
# --requestheader-client-ca-file # 证书配置
# --max-requests=0 # 取消并发限制
# 验证Metrics Server工作状态
kubectl top nodes
kubectl top pods -n production
# 输出示例:
# NAME CPU(cores) MEMORY(bytes)
# node-worker-1 2450m 8234Mi
# node-worker-2 1890m 6532Mi
# 排查Metrics Server采集异常
kubectl logs -n kube-system -l k8s-app=metrics-server --tail=50
# 常见错误:x509 certificate signed by unknown authority
# 解决方案:添加 --kubelet-insecure-tls 参数(仅测试环境)
Metrics Server的数据存在1-60秒的采集延迟,HPA默认每15秒轮询一次指标,实际响应延迟约30-75秒。对于需要更快响应的场景,可缩短metric-resolution为15秒,但会增加API Server和etcd的负载。
自定义指标与Prometheus Adapter集成
Resource指标仅覆盖CPU和内存,无法满足基于业务指标的精细化伸缩需求。Prometheus Adapter将Prometheus中的自定义指标注册为Kubernetes API资源,HPA即可基于QPS、消息队列深度、连接数等业务指标进行伸缩决策。
# Prometheus Adapter配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-adapter-config
namespace: monitoring
data:
config.yaml: |
rules:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
seriesFilters:
- is: .*_total
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total"
as: "${1}_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
- seriesQuery: 'redis_queue_length{namespace!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
name:
matches: "^(.*)"
as: "redis_queue_length"
metricsQuery: 'max(<<.Series>>{<<.LabelMatchers>>})'
resourceRules:
cpu:
containerQuery: 'sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[3m])) by (<<.GroupBy>>)'
nodeQuery: 'sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id="/"}[3m])) by (<<.GroupBy>>)'
resources:
overrides:
namespace: {resource: "namespace"}
node: {resource: "node"}
memory:
containerQuery: 'sum(container_memory_working_set_bytes{<<.LabelMatchers>>}) by (<<.GroupBy>>)'
nodeQuery: 'sum(container_memory_working_set_bytes{<<.LabelMatchers>>,id="/"}) by (<<.GroupBy>>)'
resources:
overrides:
namespace: {resource: "namespace"}
node: {resource: "node"}
rules部分定义了如何将Prometheus指标转换为Kubernetes自定义指标。seriesQuery匹配Prometheus中的时间序列,metricsQuery定义聚合查询语句,name定义转换后的指标名称。配置完成后,HPA即可引用这些自定义指标:
# 基于redis队列长度伸缩的HPA(外部指标)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-worker
minReplicas: 2
maxReplicas: 30
metrics:
- type: External
external:
metric:
name: redis_queue_length
selector:
matchLabels:
queue: "task_queue"
target:
type: AverageValue
averageValue: "500" # 每500条消息扩容一个Pod
VPA资源推荐模式与配置详解
VPA(Vertical Pod Autoscaler)分析容器的历史资源使用数据,自动推荐和调整资源请求值。VPA有三种运行模式:Auto模式自动应用推荐值,在Pod重建时生效;Recreate模式立即重建Pod以应用推荐值;Off模式仅生成推荐值不自动应用,适合观察阶段。
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
namespace: production
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Auto" # Auto | Recreate | Off
resourcePolicy:
containerPolicies:
- containerName: '*'
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 4
memory: 8Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsAndLimits
minAllowed和maxAllowed约束VPA的推荐范围,防止推荐值过低导致OOM或过高导致资源浪费。controlledValues设为RequestsOnly时仅调整请求值,Limits保持不变,适合需要严格限制资源上限的场景。
Off模式是VPA上线初期的推荐配置,通过kubectl describe vpa查看推荐值而不自动应用,人工评估后逐步切换为Auto模式:
# 查看VPA推荐值
$ kubectl describe vpa api-server-vpa -n production
Recommendation:
Container Recommendation:
Container Name: api-server
Lower Bound:
Cpu: 250m
Memory: 512Mi
Target:
Cpu: 500m
Memory: 1Gi
Uncapped Target:
Cpu: 480m
Memory: 980Mi
Upper Bound:
Cpu: 800m
Memory: 2Gi
# Target是推荐值,Lower Bound和Upper Bound是95%置信区间
# Uncapped Target是忽略minAllowed/maxAllowed约束的原始推荐值
HPA与VPA冲突规避与协同配置方案
HPA和VPA同时管理同一Deployment时存在冲突风险。如果HPA基于CPU利用率伸缩,VPA同时调整CPU请求值,两者会形成反馈循环——VPA提高CPU请求导致CPU利用率下降,HPA触发缩容,实际负载未变但副本数减少,可能导致过载。Kubernetes官方明确建议:HPA和VPA不应同时管理同一资源维度的指标。
正确的协同方案是职责分离。HPA管理水平伸缩(基于QPS等业务指标),VPA管理垂直伸缩(基于CPU/内存资源指标但HPA不使用CPU指标),或者VPA仅运行在Off模式提供推荐值。以下是生产环境的推荐配置模板:
# 方案一:HPA基于CPU,VPA仅Off模式推荐
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Off" # 仅推荐不自动应用
---
# 方案二:HPA基于自定义指标,VPA自动调整CPU/内存
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second # 仅用业务指标,不用CPU
target:
type: AverageValue
averageValue: "500"
方案一中VPA的推荐值可用于人工调整Deployment的resources字段,配合定期Review优化资源配置。方案二中HPA完全脱离CPU指标,VPA可安全地自动调整资源请求值和限制值。两种方案都规避了HPA与VPA的冲突循环,同时实现水平和垂直两个维度的弹性伸缩。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-yu-vpa-zi-dong-shen-suo-ce-lyue-pei-zhi-yu/