K8s 弹性伸缩:Metrics-Server、HPA 与 VPA 全面解析

K8s 弹性伸缩:Metrics-Server、HPA 与 VPA 全面解析

Kubernetes Metric Server

摘要:本文全面介绍了 Kubernetes 中的资源监控与自动扩缩容机制。首先详细讲解了 Metrics-Server 的部署与使用,它是 Kubernetes 内置的容器资源指标来源,为 HPA 和 VPA 提供数据支持。接着深入探讨了 HPA(Horizontal Pod Autoscaler)的扩容与缩容控制机制,包括时间参数配置、稳定窗口期、限速策略等核心概念,并通过实际案例展示了基于 CPU 和内存使用率的自动扩缩容实践。最后对比了 HPA 横向扩缩容与 VPA(Vertical Pod Autoscaler)纵向扩缩容的差异、适用场景及核心特点,为生产环境中的自动扩缩容配置提供了完整参考。
学习参考:Metric Server

环境准备

bash 复制代码
#创建名为 metric 的命名空间
root@master30:~# kubectl create ns metric
#后续执行所有 kubectl 命令,不再需要手动加 -n metric,默认操作 metric 命名空间资源。
root@master30:~# kubectl config set-context --current --namespace metric
bash 复制代码
# 查看当前默认命名空间
kubectl config view --minify | grep namespace
#或者
kubectl config get-contexts
# 查看所有命名空间
kubectl get ns

Metrics-Server 概述

我们在使用 Kubernetes 中过程中面临的问题:

  • 如何监控 node 计算资源使用情况?

  • 如何监控 pod 计算资源使用情况?

  • 如何根据 pod 计算资源使用情况,自动扩展?

我们可以使用 Metrics-Server监控:

  1. node 和 pod 计算资源使用情况。
  2. Metrics Server 是 Kubernetes 内置自动缩放管道的可扩展、高效的容器资源指标来源。
  3. Metrics Server 通过 Kubelet 收集资源指标,并通过 Metrics API 将它们公开在 Kubernetes apiserver 中,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。
  4. Metrics API 还可以通过 kubectl top 访问,从而更轻松地调试自动缩放管道。

Metrics Server 不适用于非自动缩放目的。 请勿将其用于将指标转发到监控解决方案,或作为监控解决方案指标的来源。 在这种情况下,请直接从 Kubelet /metrics/resource 端点收集指标。

指标服务器提供:

  • 适用于大多数集群的单一部署(请参阅要求)。
  • 快速自动缩放,每 15 秒收集一次指标。
  • 资源效率,集群中每个节点使用 1 mili 核心 CPU 和 2 MB 内存。
  • 可扩展支持多达 5,000 个节点集群。

Metrics-Server 部署

项目地址 kubernetes-sigs/metrics-server

bash 复制代码
# 下载 Metrics-Server
root@master30:~# wget -O components.yaml http://192.168.46.200/class/course-materials/softwares/stage03/metrics-server-components-v0.7.1.yaml

# 修改 Metrics-Server,不校验tls
# 上面的yaml文件已经修改完成了
# root@master30:~# sed -i '/metric-resolution/a\        - --kubelet-insecure-tls' components.yaml

# 修改镜像
root@master30:~# grep image: components.yaml
        image: registry.k8s.io/metrics-server/metrics-server:v0.7.1
root@master30:~# sed -i 's/registry.k8s.io/hub.laoma.cloud/g' components.yaml
# 部署 Metrics-Server
root@master30:~# kubectl apply -f components.yaml
bash 复制代码
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
bash 复制代码
# 查看 Metrics-Server 状态
root@master30:~# kubectl get pods -n kube-system |grep metrics
metrics-server-6556f8cb6c-78mhq             1/1     Running   0          45s

Metrics-Server 使用

查看node状态

bash 复制代码
root@master30:~# kubectl top node
NAME                  CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master30.laoma.cloud   97m          4%     1328Mi          35%       
worker31.laoma.cloud   49m          2%     912Mi           24%       
worker32.laoma.cloud   45m          2%     926Mi           24% 

查看 pod 状态

bash 复制代码
root@master30:~# kubectl top pods -n kube-system 
NAME                                        CPU(cores)   MEMORY(bytes)   
calico-kube-controllers-6dfcd885bf-8rhg2    2m           11Mi           
calico-node-crfr7                           27m          57Mi           
calico-node-sbmjt                           22m          57Mi           
calico-node-z9dvd                           24m          56Mi           
coredns-6d56c8448f-nhjpg                    3m           12Mi           
coredns-6d56c8448f-w2f48                    2m           10Mi           
etcd-master.laoma.cloud                      16m          54Mi           
kube-apiserver-master.laoma.cloud            46m          355Mi           
kube-controller-manager-master.laoma.cloud   11m          50Mi           
kube-proxy-hx566                            1m           18Mi           
kube-proxy-t2r4x                            1m           18Mi           
kube-proxy-x6k8h                            1m           18Mi           
kube-scheduler-master.laoma.cloud            4m           22Mi           
metrics-server-6556f8cb6c-78mhq             1m           11Mi    

单位:1cpu=1000m

Horizontal Pod Autoscaler

环境准备

bash 复制代码
root@master30:~# kubectl create ns hpa
root@master30:~# kubectl config set-context --current --namespace hpa

Horizontal Pod Autoscaler

学习参考:hpa

HPA 介绍

控制器将从Metrics Server中获取度量值。根据 HPA 中定义的指标动态实现控制器中pod伸缩,支持deployment、replication controller和replicaset。

适用场景:

  • 流量波动大的无状态服务(nginx、api、网关、微服务)
  • 需要提高并发削峰填谷

核心特点:

  • 不修改 Pod 配置,只改副本数
  • 实时、秒级扩缩
  • 最常用、最稳定

支持指标:

  • CPU 使用率
  • 内存使用率
  • 自定义指标(Prometheus 对接)
  • QPS、延迟等

HPA 配置

pod 数量扩容和缩容由kube-controller-manager管理,核心参数包括:

  • HPA 指标采样周期:--horizontal-pod-autoscaler-sync-period duration默认15s,kube-controller-manager 控制器每 15s 执行一轮循环:拉取指标 → 计算期望副本 → 判断是否扩容。

  • 启动就绪窗口期:--horizontal-pod-autoscaler-initial-readiness-delay duration默认:30s,Pod 刚启动前 30 秒,视为 "启动中",不参与 HPA 计算。

  • 缩容稳定窗口期:--horizontal-pod-autoscaler-downscale-stabilization duration默认:300s(5 分钟),缩容冷却时间。

实验环境为了演示快速扩容和缩容,设置参数如下:

bash 复制代码
root@master30:~# vim /etc/kubernetes/manifests/kube-controller-manager.yaml 
yaml 复制代码
spec:
  containers:
  - command:
    - kube-controller-manager
    - --allocate-node-cidrs=true
......
    # 增加下面三行参数
    - --horizontal-pod-autoscaler-sync-period=10s
    - --horizontal-pod-autoscaler-initial-readiness-delay=20s
    - --horizontal-pod-autoscaler-downscale-stabilization=30s

保存退出,静态 Pod 会自动重启生效

实际扩容冷却时间范围:20s-30s。

  • 最短时间20s:如果pod启动20秒后,此时正好拉取到 Metric 指标,判断需要扩容,则立刻进行扩容。
  • 最长时间30s:如果pod启动20秒后,10秒后拉取到 Metric 指标,判断需要扩容,再进行扩容。

基于 CPU 使用率伸缩

准备资源
bash 复制代码
root@master30:~# kubectl create deployment web --image=docker.io/library/nginx
root@master30:~# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-68b95c775c-xksf4   1/1     Running   0          4s
创建 hpa
bash 复制代码
Usage:  kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS]--max=MAXPODS [--cpu-percent=CPU] [options]

# 示例
root@master30:~# kubectl autoscale deployment web --max=5 --min=2 --cpu-percent=80 -o yaml
yaml 复制代码
# 省略部分不重要配置
# 注意这里版本是v1
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: web
  namespace: metric
spec:
  maxReplicas: 5
  minReplicas: 2
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  targetCPUUtilizationPercentage: 80
bash 复制代码
# 稍等片刻,hpa会自动创建一个新的pod
root@master30:~# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-68b95c775c-48ngs   1/1     Running   0          13s
web-68b95c775c-xksf4   1/1     Running   0          41s

root@master30:~# kubectl get hpa
NAME   REFERENCE        TARGETS              MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: <unknown>/80%   2         5         2          34s
# CPU 目标为unknown

要想看到 HPA 的 TARGETS 值必须满足2个条件:

  1. 安装 metric server。
  2. 为 pod 设定资源限制。
bash 复制代码
root@master30:~# kubectl edit deployments.apps web
# 修改spec.template.spec.containers.[N].resources属性,添加limit属性,如下:
        resources:
          limits: 
            cpu: 100m
            memory: 200Mi

# 再次查看hpa
root@master30:~# kubectl get hpa
NAME   REFERENCE        TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 0%/80%   2         5         2          83s

root@master30:~# kubectl expose deployment web --port=80 --target-port=80
root@master30:~# kubectl get svc
NAME   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
web    ClusterIP   10.100.255.92   <none>        80/TCP    6s
压力测试
bash 复制代码
# 打开一个监控窗口
root@master30:~# \
while true
do
  clear;
  date;echo
  kubectl get hpa;echo
  kubectl get pod;echo
  kubectl top pods
  sleep 1
done | tee hpa.log

# 上 CPU 压力
root@master30:~# apt install -y apache2-utils
root@master30:~# while true ;do ab -n 300000 -c 100 http://10.100.255.92/;sleep 1;done
#  -n 300000,总请求数
#  -c 100,每次并发数

CPU负载 cpu: 98%

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:57:22 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 100%/80%   2         5         2          8m32s

NAME                   CPU(cores)   MEMORY(bytes)   
web-6dcdc45c94-6gwd2   101m         3Mi             
web-6dcdc45c94-dvd2m   100m         3Mi 

超过目标值后,稍等片刻(20s左右),HPA 新建了一个pod

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:58:04 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 95%/80%   2         5         3          9m14s

NAME                   CPU(cores)   MEMORY(bytes)   
web-6dcdc45c94-2zbmb   93m          3Mi             
web-6dcdc45c94-6gwd2   100m         3Mi             
web-6dcdc45c94-dvd2m   90m          3Mi 

稍等片刻(20s左右),HPA又新建了一个pod

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:58:59 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 99%/80%   2         5         4          11m

NAME                   CPU(cores)   MEMORY(bytes)   
web-6dcdc45c94-2zbmb   100m         3Mi             
web-6dcdc45c94-6gwd2   100m         3Mi             
web-6dcdc45c94-dvd2m   97m          3Mi             
web-6dcdc45c94-tsjkr   99m          3Mi

稍等片刻(20s左右),HPA又新建了一个pod

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:59:59 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 100%/80%   2         5         5          11m

NAME                   CPU(cores)   MEMORY(bytes)   
web-6dcdc45c94-2zbmb   101m         3Mi             
web-6dcdc45c94-6gwd2   100m         3Mi             
web-6dcdc45c94-dvd2m   100m         3Mi             
web-6dcdc45c94-hpg45   98m          3Mi             
web-6dcdc45c94-tsjkr   101m         3Mi 

观察过程:

  1. 随着pod CPU使用率上升,自动扩展pod数量。

  2. 正常情况,20秒左右创建一个新pod,

  3. 即使pod CPU使用率超过阈值,但pod数量不会超过5。

  4. 停止压力测试,负载降低后,pod数量会立刻减少为2。

清理资源
bash 复制代码
# 删除 hpa
root@master30:~# kubectl delete hpa web 

# 删除 deployment
root@master30:~# kubectl delete deployment web

# 保留 svc,后续使用

基于 Mem 使用率伸缩

我们仍然以nginx应用实践。想要Nginx 内存涨,要访问会占用内存的页面 。最简单方法:让 Nginx 返回一个超大响应体

准备资源
bash 复制代码
# worker节点创建big.img
[root@worker31 ~]# mkdir /www
[root@worker31 ~]# dd if=/dev/zero of=/www/big.img bs=1M count=200
[root@worker32 ~]# mkdir /www
[root@worker32 ~]# dd if=/dev/zero of=/www/big.img bs=1M count=200

root@master30:~# vim deployment.yaml
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: big-file
          mountPath: /usr/share/nginx/html
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
      volumes:
      - name: big-file
        hostPath:
          path: /www
bash 复制代码
root@master30:~# kubectl apply -f deployment.yaml
创建 hpa
bash 复制代码
root@master30:~# vim hpa-mem.yaml
yaml 复制代码
# 注意这里版本为v2
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  minReplicas: 2
  maxReplicas: 5
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  metrics:
  - resource:
      name: memory
      target:
        type: Utilization
        # 使用20% 效果比较明显,这里实用60%
        averageUtilization: 60
    type: Resource
bash 复制代码
root@master30:~# kubectl apply -f hpa-mem.yaml

# 稍等片刻:目标值中内存才会正常显示
root@master30:~# kubectl get hpa
NAME   REFERENCE        TARGETS                 MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 2%/60%   2         5         1          13m

# 稍等片刻,创建一个新的pod
root@master30:~# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-6dcdc45c94-2zj8s   1/1     Running   0          13m
web-6dcdc45c94-w62pr   1/1     Running   0          13s
压力测试
bash 复制代码
# 打开一个监控窗口
root@master30:~# \
while true
do
  clear;
  date;echo
  kubectl get hpa;echo
  kubectl get pod;echo
  kubectl top pods
  sleep 1
done | tee hpa.log

# 上 MEM 压力
root@master30:~# while true ;do ab -n 300000 -c 100 http://10.99.129.137/big.img;sleep 1;done

本机作为压测客户端,向外大量发起 HTTP 请求,产生海量 TCP 收发数据包

如果master30节点硬件配置低,则导致master30节点自身CPU性能出现瓶颈。

通过top命令可以看到 si 指标偏高,特定cpu的si指标接近100%:压测产生巨量网络数据包,软中断全部堆积在 CPU1 核心处理

负载上来了

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:13:29 2026

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 86%/60%   2         5         2          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-76pg2   15m          171Mi

新建了一个pods

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:13:46 2026

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         3          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-4hcm5   5m           3Mi
web-88cff78bb-76pg2   15m          171Mi

又新建了一个pods

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:15:46 2026

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         4          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-4hcm5   5m           3Mi
web-88cff78bb-76pg2   15m          171Mi
web-88cff78bb-ws6t4   1m           3Mi  

又新建了一个pods

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:17:46 2026

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         5          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-4hcm5   5m           3Mi
web-88cff78bb-76pg2   15m          171Mi
web-88cff78bb-ws6t4   1m           3Mi  
web-88cff78bb-t4q2p   100m         3Mi

观察过程:

  1. 随着pod MEM使用率上升,自动扩展pod数量。
  2. 正常情况,20秒左右创建一个新pod,
  3. 即使pod MEM使用率超过阈值,但pod数量不会超过5。
  4. 停止压力测试,负载降低后,pod数量会立刻减少为2。
  5. 太高的负载可能会导致pod出现OOMKilled.
清理资源
bash 复制代码
# 删除 hpa
root@master30:~# kubectl delete hpa web 

# 删除 deployment
root@master30:~# kubectl delete deployment web

# 删除 svc
root@master30:~# kubectl delete svc web 

HPA 精细管控

持续高负载 → 扩容

从 K8s 1.18 起,HPA 通过 spec.behavior.scaleUp 精细管控缩容速度、冷却、单次扩容幅度。

核心参数
yaml 复制代码
scaleUp:
  # 扩容稳定窗口:负载突增后等待多久再扩容
  stabilizationWindowSeconds: 0
  # 扩容限速策略:控制每个周期最多新增多少Pod
  policies:
  - type: Percent
    value: 数值
    periodSeconds: 周期时长
  - type: Pods
    value: 数值
    periodSeconds: 周期时长
  # 多策略选择逻辑
  selectPolicy: Max / Min / Disabled
1. stabilizationWindowSeconds

扩容稳定窗口时间用来过滤瞬时突刺流量,避免瞬间飙升立刻扩容。

  • 扩容逻辑:窗口内取指标计算的最小副本数作为目标,只有持续高负载才会扩容;
  • 扩容默认值:0(无等待,负载一超标立刻扩容);
2. policies

策略用于控制单次扩容幅度。每条策略包含三要素:

  1. type:两种模式
    • Percent:周期内最多新增当前副本百分比
    • Pods:周期内最多新增固定数量Pod
  2. value:阈值(百分比/固定Pod数)
  3. periodSeconds:策略生效周期(单位秒,最大1800)
3. selectPolicy
  • Max:取新增Pod更多的策略(激进缩容,默认)
  • Min:取新增Pod更少的策略(保守缩容,生产推荐)
  • Disabled:完全禁止缩容
默认扩容策略
yaml 复制代码
scaleUp:
  stabilizationWindowSeconds: 0
  policies:
  - type: Percent
    value: 100
    periodSeconds: 15
  - type: Pods
    value: 4
    periodSeconds: 15
  selectPolicy: Max

策略解读:

  1. stabilizationWindowSeconds:0无扩容稳定窗口,指标达标立刻尝试扩容。

    窗口取值规则:取窗口内最小期望副本

  2. 两条限速策略(15s 滑动窗口):

    • Percent:每 15s 最多新增当前副本 100%(翻倍)
    • Pods:每 15s 最多新增 4 个 Pod
  3. selectPolicy:Max:两条策略取允许扩容更多的值作为本轮扩容上限;

⚠️ policy 是上限,最终扩容数量由指标计算公式决定,不是强制每次扩多少。

扩容执行流程
  1. Metrics Server 15s 采集一次指标;
  2. HPA计算目标副本数;
  3. 读取稳定窗口内历史推荐值,取最小值作为候选副本;
  4. 判断需要扩容,进入限速策略计算本周期允许新增Pod上限;
  5. 按限速分步扩容,不会一次性拉满maxReplicas;
  6. 下个周期重新采集指标,逐步扩容。
典型场景配置案例
案例1:禁止扩容
yaml 复制代码
scaleUp:
  policies:
  - type: Percent
    value: 0
    periodSeconds: 3600
  selectPolicy: Max
案例2:激进扩容(无等待)
yaml 复制代码
scaleUp:
  stabilizationWindowSeconds: 0
  policies:
  - type: Percent
    value: 50
    periodSeconds: 15
  selectPolicy: Max
案例3:平缓扩容(等待长)
  1. 扩容稳定窗口60秒,过滤瞬时流量毛刺;
  2. 每30秒最多扩容当前副本20%,或单次最多新增4个Pod;
  3. 保守模式,两种策略取扩容更少的值,放缓扩容节奏。
yaml 复制代码
scaleUp:
  # 扩容稳定窗口,等待60秒确认持续高负载
  stabilizationWindowSeconds: 60
  policies:
  # 策略1:每30s最多扩容20%
  - type: Percent
    value: 20
    periodSeconds: 30
  # 策略2:每30s最多新增4个Pod
  - type: Pods
    value: 4
    periodSeconds: 30
  # 保守扩容,取新增Pod更少的方案
  selectPolicy: Min
持续低负载 →缩容

从 K8s 1.18 起,HPA 通过 spec.behavior.scaleDown 精细管控缩容速度、冷却、单次缩容幅度。

核心参数
yaml 复制代码
scaleDown:
  # 缩容稳定窗口:负载突降后等待多久再缩容
  stabilizationWindowSeconds: 0
  # 缩容限速策略:控制每个周期最多减少多少Pod
  policies:
  - type: Percent
    value: 数值
    periodSeconds: 周期时长
  - type: Pods
    value: 数值
    periodSeconds: 周期时长
  # 多策略选择逻辑
  selectPolicy: Max / Min / Disabled
1. stabilizationWindowSeconds

HPA 稳定窗口周期内计算出的期望副本,缩容时取窗口内最大值作为目标副本;只有持续低负载超过窗口时长,才会真正缩容,避免瞬时流量下跌立刻删Pod导致反弹。

  • 默认值:300(5分钟)
  • 取值范围:0~3600(1小时)
  • 逻辑举例:当前副本10,指标瞬时建议缩到6,窗口5分钟内历史最大值仍为10 → 不缩容;5分钟后高值过期,才按更低副本缩容。
2. policies

缩容限速规则用于控制单次缩容幅度。每条策略包含三要素:

  1. type:两种模式
    • Percent:周期内最多删除当前副本百分比
    • Pods:周期内最多删除固定数量Pod
  2. value:阈值(百分比/固定Pod数)
  3. periodSeconds:策略生效周期(单位秒,最大1800)
3. selectPolicy
  • Max:取删Pod更多的策略(激进缩容,默认)
  • Min:取删Pod更少的策略(保守缩容,生产推荐)
  • Disabled:完全禁止缩容
默认缩容策略
yaml 复制代码
scaleDown:
  stabilizationWindowSeconds: 300
  policies:
  - type: Percent
    value: 100
    periodSeconds: 15
  selectPolicy: Max
# 只有单条策略,selectPolicy字段存在但不产生取舍效果

策略解读:

  1. stabilizationWindowSeconds:300:5 分钟稳定窗口。

    窗口取值规则:取窗口内最大期望副本,防止流量抖动反复扩缩。

  2. 一条策略:每 15s 滑动窗口内最多删除当前副本 100%,理论上可以一次性缩到最小副本数。

  3. 缩容只有一条 policy ,不存在多条策略对比,所以selectPolicy默认值 Max 在此场景没有实际作用;

缩容执行流程
  1. Metrics Server每15s采集CPU/指标;
  2. HPA计算理论期望副本;
  3. 查询稳定窗口历史推荐值,取最大值作为候选目标;
  4. 对比当前副本,判断需要缩容;
  5. 执行policies限速规则,计算本周期允许删除的最大Pod数;
  6. 按限速值缩减副本,不会一次性缩到最低;
  7. 下一个周期重复计算,分步缓慢下降。
典型场景配置案例
案例1:禁止缩容(活动高峰)
yaml 复制代码
scaleDown:
  stabilizationWindowSeconds: 300
  policies:
  - type: Percent
    value: 0
    periodSeconds: 3600
  selectPolicy: Max
案例2:激进缩容(无等待、快速缩容)
yaml 复制代码
scaleDown:
  stabilizationWindowSeconds: 30
  policies:
  - type: Percent
    value: 100
    periodSeconds: 15
  selectPolicy: Max
案例3:平缓缩容(等待长,慢速缩容)
  1. 稳定窗口10分钟,避免毛刺缩容;

  2. 每60秒最多缩容当前副本10% 或 最多删2个Pod;

  3. 保守模式,两种策略取删得更少的方案。

yaml 复制代码
scaleDown:
  # 稳定窗口:等待10分钟确认低负载再缩容
  stabilizationWindowSeconds: 600
  policies:
  # 策略1:每分钟最多缩容10%
  - type: Percent
    value: 10
    periodSeconds: 60
  # 策略2:每分钟最多删除2个Pod
  - type: Pods
    value: 2
    periodSeconds: 60
  # 缩容保守:两种策略选删除Pod更少的
  selectPolicy: Min
扩容、缩容对比
配置项 scaleUp(扩容) scaleDown(缩容)
stabilizationWindowSeconds 默认值 0 300(5 分钟)
稳定窗口取值逻辑 窗口内取最小期望副本 窗口内取最大期望副本
默认 policies 条数 2 条(Percent+Pods) 1 条(仅 Percent)
默认策略内容 15s 最多扩容 100% / 最多新增 4Pod 15s 最多删除 100% 副本
默认 selectPolicy Max Max(单策略无实际效果)
selectPolicy 支持选项 Max / Min / Disabled Max / Min / Disabled
触发阈值 利用率 > target × 1.1 利用率 < target × 0.9
设计思想 优先快速扩容保障业务 谨慎缩容,避免流量反弹

Vertical Pod Autoscaler

VPA 使用场景不多,这里不做实践演示。

VPA 作用

控制器将从一系列API(metrics.k8s.iocustom.metrics.k8s.ioexternal.metrics.k8s.io)中获取度量值,metrics.k8s.io API 通常由Metrics Server提供。根据 VPA 中定义的指标动态调整 Pod 的 requests 和 limits

VPA 适用场景

  • 资源配置不合理的服务
  • 长期运行、流量稳定的服务
  • Java、Go 等内存占用固定的应用
  • 不适合频繁扩缩的服务

VPA 核心特点

  • 不改变 Pod 数量
  • 自动给 Pod 推荐 / 设置 CPU / 内存
  • 生效需要重启 Pod(默认)
  • 比 HPA 少用,因为有侵入性

HPA 与 VPA 对比

项目 HPA 横向扩缩容 VPA 纵向扩缩容
全称 Horizontal Vertical
扩缩方式 增加 / 减少 Pod 数量 调整 CPU / 内存 request/limit
是否重启 Pod ❌ 不重启 ✅ 一般需要重启
适合负载 流量波动大 资源配置不合理
生效速度
稳定性
生产使用 非常普遍 较少
能否一起开 不能同时开(会冲突) -
支持资源 CPU、内存、自定义 CPU、内存

环境清理

bash 复制代码
root@master30:~# kubectl delete ns hpa
相关推荐
gs8014032 分钟前
告别 CI/CD 误伤与红条:Docker 镜像智能清理与优雅防冲突实战
ci/cd·docker·容器
wjcroom1 小时前
FileBrowser的docker运行了改变密码长度的做法
运维·docker·容器
码云数智-园园2 小时前
我为什么从微服务退回单体架构
微服务·云原生·架构
DevOps老兵3 小时前
AI Infra实战05:用Helm在K8s中部署vLLM,从安装到压测全流程
人工智能·kubernetes·helm·vllm·大模型推理·ai infra
Asum1ta3 小时前
生产环境 Kubernetes 高可用集群部署实战:外部 etcd + Keepalived + HAProxy + 多 Master 架构
架构·kubernetes·etcd
dazhong20123 小时前
Docker 进阶篇(一) CentOS 7 离线升级 Docker 完整实战
docker·容器·centos
源代码•宸4 小时前
前置准备:定时微服务有什么价值
经验分享·后端·微服务·云原生·架构
雾隐隐o4 小时前
Docker Compose 多容器编排实战
运维·docker·容器
IT大白鼠5 小时前
Kubernetes 核心资源ReplicaSet 控制器详解
云原生·容器·kubernetes