Kubernetes

K8s 完整扩缩容体系详解

·10 分钟阅读·3666 字
📋 目录

K8s 完整扩缩容体系详解

核心概念 K8s 扩缩容分为 VPA 垂直扩缩、HPA 水平扩缩、CA 集群自动扩缩三层完整弹性体系。

1. 整体分类

K8s 扩缩容分为两大维度:垂直扩缩容 VPA水平扩缩容 HPA,外加集群节点层面集群自动扩缩容 Cluster Autoscaler(CA),三层完整弹性体系:

  1. Pod 垂直扩缩 VPA:不增减Pod数量,调整单个Pod CPU/内存配额
  2. Pod 水平扩缩 HPA:增减Pod副本数(业务最常用)
  3. 节点集群扩缩 CA:节点资源不足时自动新增/删除宿主机节点

三者配合形成完整弹性闭环:
流量上涨 → HPA扩容Pod → 节点资源打满 → CA新增节点;
流量低谷 → HPA缩容Pod → 节点大量空闲 → CA缩容删除空闲节点。

2. 水平扩缩容:HPA HorizontalPodAutoscaler(业务核心)

2.1. 基础定位

自动调整 Deployment/StatefulSet/ReplicaSet 的 replicas 副本数量,多实例分担流量,无状态/有状态业务通用。
不支持 DaemonSet(节点固定单Pod)、Job一次性任务。

2.2. 依赖组件

  1. Metrics Server(必备):采集Pod CPU、内存,提供标准资源指标;无Metrics Server HPA无法采集基础指标。
  2. Custom Metrics Adapter(可选):暴露业务自定义指标(QPS、并发、MQ堆积),典型:prometheus-adapter。
  3. kube-controller-manager 内置 HPA Controller,15s 一轮循环调谐。

2.3. 支持三类伸缩指标

  1. **资源指标(CPU/内存 Utilization)**基于容器 requests 计算利用率,最基础、开箱即用。
    计算公式:期望副本 = ceil(当前副本 × 当前利用率 / 目标利用率)
    示例:3副本,CPU当前140%,阈值70% → 扩容至6副本。
  2. Pod自定义指标
    业务埋点QPS、连接数,单Pod平均指标触发伸缩。
  3. 外部External指标
    和Pod资源无关,如Kafka/RocketMQ队列堆积消息数,消费Worker自动扩容。

2.4. 核心防抖动机制:behavior 冷却窗口

解决指标瞬时毛刺导致频繁反复扩缩:

  • scaleDown.stabilizationWindowSeconds:缩容稳定窗口(推荐300s),流量持续低位5分钟才删Pod;
  • scaleUp.stabilizationWindowSeconds:扩容窗口(推荐60s),流量上涨快速扩容。

2.5. 约束配置

minReplicas 最小保底副本(防止缩容到0断服);maxReplicas 最大副本上限(避免无限扩容耗尽集群资源)。

2.6. 手动水平扩缩(静态,无自动感知指标)

无需HPA,人工执行:

kubectl scale deploy web --replicas=5

仅临时调整,无法根据流量自动变化。

3. 垂直扩缩容:VPA VerticalPodAutoscaler

3.1. 定位

不改变Pod数量,动态调整单个Pod的 requests/limits CPU内存,提升/降低单实例算力。
适合:流量平稳、不方便多副本水平扩容的单体应用、数据库单实例。

3.2. VPA 三种工作模式

  1. Auto(自动模式):自动更新Pod资源配额,重建Pod生效;
  2. Recreate:资源不足时重启Pod调整配额;
  3. Off:仅采集推荐值,不自动修改,用于观测评估。

3.3. 优缺点

优点:无需多副本,单实例提升性能;
缺点:调整资源会重启Pod,产生短暂业务中断;生产微服务优先HPA。

4. 集群节点自动扩缩容:Cluster Autoscaler(CA)

4.1. 定位

HPA扩容Pod后,现有节点CPU/内存不足以调度新Pod(Pod处于Pending),CA自动调用云厂商API新增节点;
业务低峰,多个节点全空闲,CA自动下线销毁空闲节点,节约服务器成本。

4.2. 触发扩容逻辑

  1. 存在大量 Pending Pod,调度失败,原因:节点CPU/内存不足;
  2. CA检测对应节点池,自动创建新节点加入集群;
  3. 新节点calico/组件就绪后,Pending Pod自动调度上去。

4.3. 触发缩容逻辑

  1. 节点上所有Pod副本数等于minReplicas、无本地存储PVC(LocalPV)、无不可驱逐Pod;
  2. 节点整体资源利用率长期低于阈值(默认50%);
  3. 等待冷却窗口期,确认持续空闲后驱逐Pod、删除节点。

4.4. 缩容关键限制(生产避坑)

  1. 节点存在 LocalPV 本地盘PVC:CA不会删除该节点,防止数据丢失;
  2. Pod 设置 cluster-autoscaler.kubernetes.io/safe-to-evict: false 禁止驱逐,节点无法缩容;
  3. StatefulSet PVC不删除,缩容时Pod被驱逐后PVC残留,CA不会轻易下线节点。

5. 三层扩缩容完整联动流程(流量暴涨场景)

  1. 前端流量突增,Pod CPU利用率超过HPA阈值;
  2. HPA控制器计算出新副本数,扩容Deployment副本;
  3. 新增Pod因节点资源不足,状态变为Pending;
  4. Cluster Autoscaler监测到Pending Pod,调用云API新增节点;
  5. 新节点calico、kubelet就绪,Pending Pod调度至新节点;
  6. 流量回落,HPA缩容减少Pod;
  7. 部分节点无业务Pod,资源利用率极低,CA等待冷却后删除空闲节点。

6. 各类负载扩缩容差异

6.1. Deployment(无状态)

  • HPA水平扩容:新建Pod,共用PVC(如有);滚动更新无影响;
  • 缩容随机删除Pod,无数据残留。

6.2. StatefulSet(有状态 MySQL/Kafka/ES)

  • HPA扩容:自动创建新独立PVC(volumeClaimTemplates),每个实例独享存储;
  • HPA缩容:仅删除Pod,PVC保留,防止数据丢失,需人工清理僵尸PVC;
  • 扩容有序:0→1→2;缩容倒序:2→1→0。

6.3. DaemonSet

不支持HPA,每个节点固定一个Pod,仅随CA新增/删除节点自动增减。

6.4. Job/CronJob

一次性任务,无长期副本扩缩逻辑。

7. 静态手动扩缩 vs 自动弹性体系对比

  1. 手动scale
    人工调整replicas,无指标感知,无法应对突发流量,仅测试/临时变更使用。
  2. HPA自动水平
    业务标准方案,根据CPU/内存/QPS自动增减Pod,零人工干预。
  3. VPA垂直
    单实例场景,调整Pod资源配额,会重启Pod。
  4. CA节点集群扩缩
    底层资源弹性,解决节点容量瓶颈,配合HPA形成闭环。

8. 生产常见问题与最佳实践

8.1. HPA不伸缩

  • Pod未配置 requests,利用率无法计算;
  • Metrics Server异常,无指标返回;
  • 冷却窗口未结束,延迟执行扩缩;
  • maxReplicas达到上限,无法继续扩容。

8.2. CA节点无法扩容

云厂商AK/密钥权限不足,无法创建节点;节点池机型资源不足以容纳Pending Pod。

8.3. CA节点无法缩容

节点存在LocalPV;Pod禁止驱逐;节点有不可中断业务Pod。

8.4. 最佳实践

  1. 微服务统一使用HPA水平弹性,配置min保底副本、缩容冷却窗口;
  2. 开启Cluster Autoscaler实现节点自动弹性,节约云服务器成本;
  3. 有状态STS关注缩容后残留PVC,定时清理;
  4. 单体单实例搭配VPA观测资源推荐值,优化requests/limits;
  5. 分层监控:HPA副本变化、节点数量、Pending Pod告警,及时发现弹性失效。

9. 面试精简总结框架

  1. K8s三层弹性体系:HPA Pod水平扩缩、VPA Pod垂直扩缩、CA集群节点扩缩;
  2. HPA增减副本,依赖Metrics Server,支持CPU/内存/QPS/MQ多指标伸缩,业务主流;
  3. VPA不改变副本数,调整单个Pod资源配额,调整会重启容器;
  4. Cluster Autoscaler解决节点资源瓶颈,Pod pending自动加节点,空闲节点自动删除;
  5. 联动逻辑:流量上涨→HPA扩容Pod→节点不足→CA新增节点;低峰HPA缩容→CA删除空闲节点;
  6. STS扩容自动生成独立PVC,缩容PVC保留;DaemonSet不支持HPA;
  7. 冷却窗口、副本上下限、节点驱逐限制是弹性体系稳定运行关键。

关联文档