Kubernetes HPA自动扩缩容配置与Prometheus自定义指标实战

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/

(0)
小编小编
上一篇 12小时前
下一篇 12小时前

相关推荐