Kubernetes容器编排中的HPA(Horizontal Pod Autoscaler)是DevOps实践里保障服务稳定性的关键机制。HPA根据CPU、内存或自定义指标自动调整Pod副本数量,实现流量高峰自动扩容、低谷自动缩容。本文演示配置标准HPA与基于Prometheus自定义指标的弹性伸缩方案。
HPA工作原理与扩缩容算法
HPA控制器每隔15秒(默认–horizontal-pod-autoscaler-sync-period)从metrics-server或自定义指标API获取Pod指标值,计算期望副本数:
期望副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))
例如当前4个Pod平均CPU使用率80%,目标值50%:期望副本数 = ceil(4 × 80/50) = ceil(6.4) = 7。HPA会平滑扩容到7个Pod。
缩容默认有5分钟冷却期(–horizontal-pod-autoscaler-downscale-stabilization),避免指标波动导致频繁缩容。扩容无冷却期但受Pod启动时间制约。此机制在故障应急响应场景中能有效缓解服务过载。
安装Metrics Server
HPA依赖metrics-server获取CPU和内存指标。在Kubernetes集群中部署:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证安装
kubectl get pods -n kube-system -l k8s-app=metrics-server
kubectl top nodes
kubectl top pods -A
生产环境需注意metrics-server默认使用kubelet自签证书,需添加–kubelet-insecure-tls参数(仅测试环境)或正确配置kubelet证书。EKS/GKE/AKS等托管集群通常已预装metrics-server。
基于CPU利用率的HPA配置
先部署一个测试应用并设置资源请求:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-api
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: web-api
template:
metadata:
labels:
app: web-api
spec:
containers:
- name: api
image: registry.example.com/web-api:v2.1
resources:
requests:
cpu: 250m # 0.25核
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: web-api
namespace: production
spec:
selector:
app: web-api
ports:
- port: 80
targetPort: 8080
resources.requests.cpu是HPA计算CPU利用率的基准。HPA的CPU利用率 = 实际CPU使用量 / requests.cpu。必须设置requests才能使用CPU指标扩缩容。
创建HPA资源:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-api-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-api
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
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
averageUtilization: 60表示目标CPU利用率60%。behavior字段是autoscaling/v2新增的关键特性,允许精细控制扩缩容速率,避免流量突增时扩容不足或抖动时频繁缩容。
压测验证HPA扩容效果
# 部署压测工具
kubectl run load-tester --image=busybox:1.36 -it --rm -- /bin/sh
# 持续发送请求制造CPU负载
while true; do wget -q -O- http://web-api.production.svc.cluster.local/; done
在另一个终端监控HPA状态:
kubectl get hpa web-api-hpa -n production -w
# 输出示例:
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# web-api-hpa Deployment/web-api 80%/60% 2 20 4
kubectl get pods -n production -l app=web-api -w
# 观察Pod从2个逐步扩容
基于Prometheus自定义指标的HPA
CPU和内存指标无法覆盖所有场景。对于处理消息队列、QPS驱动的服务,需要基于业务自定义指标扩缩容。方案使用Prometheus Adapter将Prometheus指标暴露为Kubernetes自定义指标API。
安装Prometheus Adapter:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://prometheus-server.monitoring.svc.cluster.local \
--set prometheus.port=80
配置Adapter规则,将Prometheus中的http_requests_per_second指标映射为Kubernetes自定义指标:
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-adapter
namespace: monitoring
data:
config.yaml: |
rules:
- seriesQuery: 'http_requests_per_second{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_per_second"
as: "${1}_tps"
metricsQuery: 'avg(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)'
验证自定义指标API是否可用:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/production/pods/*/http_requests_tps"
# 应返回Pod级别的TPS指标值
创建基于自定义指标的HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-api-custom-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-api
minReplicas: 3
maxReplicas: 30
metrics:
- type: Pods
pods:
metric:
name: http_requests_tps
target:
type: AverageValue
averageValue: 500
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 200
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 60
averageValue: 500表示每个Pod目标处理500 TPS。当总QPS达到3000时,HPA会扩容到6个Pod(3000/500=6)。这种基于业务指标扩缩容的方式比CPU指标更精准,直接反映服务水平。
HPA调试与常见问题
# 查看HPA详细事件
kubectl describe hpa web-api-hpa -n production
# 检查指标是否可用
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/production/pods" | jq .
# 常见错误排查
kubectl get hpa -n production
# TARGETS显示unknown的原因:
# 1. Pod未设置resources.requests
# 2. metrics-server未正常运行
# 3. custom.metrics.k8s.io API未注册
多指标HPA取各指标计算出的最大副本数。例如CPU要求6个Pod,内存要求4个Pod,则扩容到6个。这是autoscaling/v2的设计决策,确保所有指标约束都被满足。
HPA与VPA及集群自动扩缩容协同
HPA调整Pod副本数(水平扩缩容),VPA调整Pod资源请求(垂直扩缩容),Cluster Autoscaler调整节点数。三者配合构成Kubernetes完整的弹性体系。混用HPA和VPA需注意:基于相同指标(CPU/内存)的HPA与VPA会冲突,VPA修改requests会干扰HPA利用率计算。推荐HPA用CPU指标,VPA仅用于内存调优。
集群层面配合Cluster Autoscaler或Karpenter,在HPA扩容但节点资源不足时自动添加新节点:
# 检查节点自动扩容日志
kubectl logs -n kube-system -l app=cluster-autoscaler --tail=50
# 节点扩容事件
kubectl get events -A --field-selector reason=ScaleUp
HPA自动扩缩容是Kubernetes容器编排体系中的弹性基石。合理设置指标阈值、扩缩容速率和冷却时间,结合CI/CD流水线中的资源基线配置,能在保障SRE稳定性工程要求的同时优化资源利用率,实现DevOps实践中弹性伸缩的闭环管理。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-zi-dong-kuo-suo-rong-pei-zhi-yu-prometheus-zi/