跳到主要内容

Kubernetes 自动伸缩完整指南:HPA/VPA/CA 原理与实战

我们要达成什么

  • Pod 随负载自动扩缩(HPA)。
  • Pod 资源请求随历史负载自动调优(VPA)。
  • 集群节点随工作负载自动扩缩(CA)。

下面用一套可直接执行的步骤,让你在集群里跑通这三种伸缩机制,并知道它们如何搭配。

环境预设

  • Kubernetes >= 1.24。
  • Metrics Server 已安装(如果没有,参考下方安装)。
  • 具备 kubectl 管理权限;如需 CA,需要云提供商支持或模拟。

安装 Metrics Server(如未安装)

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl -n kube-system get deployment metrics-server

验证:

kubectl top nodes
kubectl top pods -A

top 无数据,检查 APIService 是否可用:kubectl get apiservice v1beta1.metrics.k8s.io -o yaml

部署一个可加压示例应用

kubectl create namespace autoscale-demo --dry-run=client -o yaml | kubectl apply -f -
kubectl -n autoscale-demo create deploy web --image=ghcr.io/kedacore/http-add-on-scaler:v1.1.2 --port=8080
kubectl -n autoscale-demo expose deploy web --port=8080

简单的 HTTP server,便于用 hey/ab 加压。

配置 HPA(基于 CPU 与自定义 QPS 指标)

  1. 基于 CPU 的 HPA:
kubectl -n autoscale-demo autoscale deploy web \
--min=1 --max=5 \
--cpu-percent=50

检查:

kubectl -n autoscale-demo get hpa web -w

加压:

hey -z 60s -c 30 http://<web-service-ip>:8080/

观察 HPA 是否将 web 副本扩容。

  1. 基于自定义指标(示例用 Prometheus Adapter 暴露 QPS——如已安装 Prometheus + Adapter):
  • 在 ServiceMonitor 中暴露 http_requests_total
  • 创建 HPA YAML:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-custom
namespace: autoscale-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "50"

需要 Prometheus Adapter 将 QPS 暴露为 Pods 级指标,名称请按实际适配器配置调整。

配置 VPA(自动调优资源请求)

  1. 安装 VPA 控制器(官方发布 YAML):
kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/vertical-pod-autoscaler.yaml
  1. 为示例 Deployment 启用 VPA(推荐 Auto 模式前先跑 Off 观测建议):
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-vpa
namespace: autoscale-demo
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web
updatePolicy:
updateMode: Off # 先观察建议

查看建议:

kubectl -n autoscale-demo describe vpa web-vpa | grep -A3 Recommendation

确认无误后改为:

  updatePolicy:
updateMode: Auto

VPA 与 HPA(基于 CPU/内存)存在冲突,建议仅在自定义指标 HPA 或低频调整场景使用,或把 HPA 设为基于外部指标以避免拉扯。

配置 Cluster Autoscaler(CA)

云厂商示例以 AWS EKS 为参考,其他平台请替换 provider 配置。

  1. 安装 CA(替换集群名称与节点组):
kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/cluster-autoscaler-autodiscover.yaml

编辑 Deployment,设置:

command:
- ./cluster-autoscaler
- --cloud-provider=aws
- --cluster-name=<your-eks-cluster>
- --balance-similar-node-groups
- --skip-nodes-with-local-storage=false
- --skip-nodes-with-system-pods=false

并添加 node group 标签:

        - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<your-eks-cluster>

确保 CA ServiceAccount 具有相应云 API 权限(IAM 角色/服务账号)。

  1. 验证:
  • 设置 HPA 上限高于当前容量,触发 Pod Pending。
  • 观察 CA 日志:kubectl -n kube-system logs deploy/cluster-autoscaler,确认它请求扩容节点。
  • 在云控制台查看节点组是否伸缩。

排障清单

  • HPA 不扩容:检查 Metrics Server 是否返回数据;HPA 目标指标名称/类型是否匹配;应用是否确实有负载。
  • VPA 无建议:等待采样时间;确认 VPA Admission Controller 与 Recommender/Updater Pod 正常;Deployment 是否使用了 VPA 支持的控制器(不支持 DaemonSet)。
  • CA 不动作:查看 CA 日志,常见为权限不足、节点组未打标签、Pending Pod 有本地盘或不可调度约束;确认 --skip-nodes-with-local-storage 配置。
  • HPA 与 VPA 打架:避免两者同时控制 CPU/内存;将 HPA 改用外部/自定义指标,或对不同工作负载分开使用。

生产落地要点

  • HPA:设置合理的 min/max,避免抖动;结合 PodDisruptionBudget 保障平滑扩缩。
  • VPA:先跑一段时间 Off 模式获取建议,再逐步开启 Auto 并设定 minAllowed/maxAllowed 限制。
  • CA:节点组必须支持自动扩缩(云 API 权限),并预留 buffer;对有状态或本地存储 workload 设好反亲和,避免不必要的 Pending。
  • 监控:关注 HPA 事件、CA 日志、VPA Recommender 指标;必要时对扩缩耗时设置告警。

总结

HPA 解决“多/少副本”,VPA 解决“每个副本该给多少资源”,CA 解决“有没有足够节点”。按上面的安装与验证步骤,你可以在集群里跑通这三种伸缩方式,再根据业务特点组合:例如服务层用 HPA+CA,批处理/低频服务用 VPA 建议,最后把这些配置纳入 GitOps,持续观测并收紧参数。