经典面试题:K8S的自动缩扩容和崩溃恢复

一、先总述核心定位

K8s 的自动缩扩容 是为了弹性适配业务流量 ,避免资源浪费或过载;崩溃恢复 是为了保证应用高可用 ,核心都是基于 「期望状态 vs 实际状态」的调和机制------ 控制器持续监控状态差异,自动触发调整。

二、自动缩扩容(面试重点:HPA)

K8s 自动缩扩容分 3 类,但面试只需要重点讲 水平 Pod 自动伸缩(HPA),另外两类简单带过即可。

1. 三类伸缩对比(答题时一句话概括)

类型 核心作用 关键依赖
水平 Pod 伸缩(HPA) 调整 Pod 的副本数量(比如 2 个扩到 5 个),无状态应用首选 Metrics Server(指标采集)
垂直 Pod 伸缩(VPA) 调整单个 Pod 的 CPU / 内存规格(比如 1 核扩到 2 核) VPA 控制器
集群级伸缩(CA) 节点资源不足时新增节点,闲置时删节点(云厂商场景) 云厂商节点池 + CA 控制器

2. HPA 核心工作流程(面试必背,分 4 步讲)

HPA 是最常用的伸缩方式,分**「配置→采集→判断→执行」** 四步:

  1. 配置伸缩规则:通过 HPA 资源对象,绑定目标 Deployment/RS,设置「最小 / 最大副本数」「伸缩指标阈值」(比如 CPU 使用率 80%、内存使用率 70%)。
  2. 指标采集 :依赖Metrics Server(必须部署,K8s 默认没有),定期采集 Pod 的 CPU、内存等核心指标。
  3. 阈值对比计算 :HPA 控制器默认每 15 秒 查询一次指标,对比实际指标和预设阈值,计算需要的目标副本数。
    • 计算公式(可提可不提,加分项):目标副本数 = 当前副本数 × (当前指标值 / 目标指标值)
  4. 执行伸缩 :HPA 直接修改 Deployment/RS 的replicas字段 ------ 指标超标就扩容,指标过低就缩容,由 RS 控制器负责创建 / 删除 Pod。

3. HPA 面试高频考点(踩中得分点)

  • 必问 1 :为什么 HPA 必须设置 Pod 的resources.requests?答:因为 HPA 计算资源使用率的分母是requests(不是实际使用量),没有requests,HPA 无法计算使用率,会直接失效。
  • 必问 2 :HPA 伸缩有什么限制?答:① 只支持无状态应用(有状态用 StatefulSet + 自定义伸缩);② 避免短时间内频繁伸缩(可通过--horizontal-pod-autoscaler-stabilization-window设置稳定窗口)。

在 Pod 的 YAML 里,requests和limits写在containersresources字段下,比如:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.24
    resources:
      requests:  # 核心:声明最低保障
        cpu: 100m    # 申请0.1核CPU
        memory: 128Mi # 申请128MB内存
      limits:      # 可选:声明最大上限
        cpu: 500m    # 最多用0.5核CPU
        memory: 256Mi # 最多用256MB内存

用表格记最清晰:

特性 resources.requests(资源请求) resources.limits(资源限制)
核心含义 Pod 运行的「最低资源保障」 Pod 运行的「最大资源上限」
调度依据 调度器必须参考,决定 Pod 放哪个节点 调度器不参考,只在 Pod 运行时生效
超量后果 不会被限制,可使用节点空闲资源 超 CPU:被限流(throttle);超内存:被 OOM 杀死(crash)
和 HPA 的关系 是 HPA 计算使用率的分母(必须设) 和 HPA 无直接关系

面试示例话术(HPA 部分)

我们线上主要用 HPA 做水平伸缩,首先部署 Metrics Server 采集指标,然后定义 HPA 绑定 Deployment,设置最小 2 副本、最大 10 副本,CPU 阈值 80%。HPA 控制器每 15 秒查一次指标,比如流量高峰时 Pod CPU 使用率到了 90%,就自动把副本数从 2 扩到 5;流量下降后再缩回去。这里要注意,Pod 必须配置 resources.requests,否则 HPA 无法工作。

HPA 的核心决策依据是 「计算后的目标副本数是否和当前副本数一致」,而不是 "使用率是否严格等于 80%"。公式:目标副本数=当前副本数*(实际平均使用率/目标阈值)

HPA 会对计算结果取整 ,只要取整后的值和当前副本数一致 ,就不扩也不缩

举个例子:当前副本数 = 2,阈值 80%

实际使用率 目标副本数计算 实际决策 原因
84% 2×(84%/80%)=2.1 不扩容 目标副本数 2.1 只比当前多 0.1,差值太小,属于正常波动,不操作
90% 2×(90%/80%)=2.25 不扩容 2.25 比 2 多 0.25,依然是小幅波动,不满足 "新增 1 个 Pod" 的需求
120% 2×(120%/80%)=3 扩容到 3 3 比 2 多 1,差值足够大,说明流量确实上涨,需要新增 Pod
75% 2×(75%/80%)=1.875 不缩容 1.875 比 2 少 0.125,波动太小;且 minReplicas=2,也不能再缩
50% 2×(50%/80%)=1.25 缩容到 2 虽然计算值 1.25<2,但 minReplicas=2,最低保留 2 个副本

三、崩溃恢复(面试重点:控制器 + 重启策略)

崩溃恢复的核心是 「控制器兜底 + 容器重启优先」

核心原理前置(一句话点明)

所有恢复操作的本质:控制器持续监控实际状态,当实际状态≠期望状态时,自动触发修正

1. Pod 级崩溃恢复(最常见,分 2 种情况)

Pod 崩溃的原因:容器进程退出、OOM 被杀、配置错误等,恢复分两步:

(1)第一步:容器级重启(优先策略)

由 Pod 的restartPolicy决定,这是恢复的第一道防线,面试必问 3 种策略的区别:

对比维度 Always(默认策略) OnFailure Never
重启触发条件 容器任何原因退出(正常 / 异常),立即重启 仅容器异常退出(非 0 退出码) 时重启;正常退出(0 退出码)不重启 容器任何原因退出(正常 / 异常),永不重启
退出码依赖 不依赖退出码,0 / 非 0 码都触发重启 仅非 0 退出码触发重启,0 码不触发 不依赖退出码,任何码都不触发重启
核心目标 保证容器长期持续运行,不中断服务 任务失败重试,成功停止,避免空跑 容器退出后依赖控制器重建新 Pod,不复用原容器环境
适用场景 无状态长期运行服务 批处理 / 周期性任务(失败可重试,成功即停) 一次性初始化任务(失败后需全新环境重试)
典型业务案例(Java 后端) Nginx 网关、Spring Boot 微服务 API、Redis 代理 MySQL 定时备份、跨库数据同步、日志批量清理 Flyway/MyBatis 表结构初始化、Redis 集群搭建、临时诊断任务
推荐搭配 K8s 资源 Deployment/ReplicaSet(保证副本数) CronJob(定时任务)/Job(批处理任务) Job(一次性任务),配合backoffLimit设置重试次数
正常退出(0 码)后 Pod 状态 容器立即重启,Pod 状态保持 Running 容器不重启,Pod 状态变为 Completed 容器不重启,Pod 状态变为 Completed
异常退出(非 0 码)后 Pod 状态 容器立即重启,Pod 状态保持 Running;反复失败触发CrashLoopBackOff 容器立即重启,Pod 状态保持 Running;反复失败持续重试 容器不重启,Pod 状态变为 Error;控制器重建新 Pod
面试关键备注 1. 适配 K8s 核心场景(长期服务);2. 反复崩溃触发退避策略(暂停重启) 1. 任务需满足幂等性(重试不重复造数据);2. 成功后容器自动停止,节省资源 1. 失败后原容器有环境残留(如临时文件),需重建 Pod;2. 完全依赖控制器兜底,无容器级重启

记忆口诀

  1. Always:长期服务必选,任何退出都续命;
  2. OnFailure:批处理任务专用,失败重试成功停;
  3. Never:初始化任务专属,死活不重启,重建新 Pod。
(2)第二步:控制器重建(兜底保障)

如果容器重启后还是崩溃(比如镜像错误、代码 bug),或者 Pod 被删除,由 Deployment/RS/StatefulSet 控制器兜底:

  • 无状态应用(Deployment/RS):控制器监控到「实际 Pod 数 < 期望副本数」,直接在健康节点上重建新 Pod,不保留任何状态。
  • 有状态应用(StatefulSet) :针对数据库、中间件等,恢复时会保留两个核心状态:
    • 网络标识:Pod 名称固定(比如 mysql-0、mysql-1),通过 Headless Service 保证 DNS 解析不变;
    • 存储状态:绑定的 PVC 不会随 Pod 删除而删除,新 Pod 重建后直接挂载原有数据。

2. 节点级崩溃恢复(面试加分项)

当整个节点宕机(比如服务器断电、网络失联),由 Node Controller 负责恢复:

  1. Node Controller 默认每 5 秒 检查一次节点状态,节点失联超过5 分钟 (可配置),标记为NotReady
  2. 控制器将该节点上的所有 Pod 标记为Terminating
  3. 触发 Deployment/RS 在其他健康节点上重建这些 Pod,保证整体副本数符合期望。

崩溃恢复面试高频考点

  • 必问 1:Deployment 和 StatefulSet 的崩溃恢复有什么区别?答:Deployment 是无状态的,恢复的 Pod 是全新的,没有固定名称和存储;StatefulSet 是有状态的,恢复的 Pod 名称固定,会挂载原有 PVC,保证数据不丢失。
  • 必问 2 :Pod 崩溃后,重启和重建的区别是什么?答:重启 是在原 Pod 内重启容器,Pod 的 IP、名称等信息不变;重建是删除原 Pod,创建新 Pod,IP 和名称可能变化(StatefulSet 除外)。

四、面试答题总结模板(直接背)

K8s 的自动缩扩容和崩溃恢复,核心都是「期望状态 vs 实际状态」的调和机制。

  1. 自动缩扩容:重点是 HPA,通过 Metrics Server 采集 Pod 指标,对比阈值后自动调整 Deployment 的副本数,实现水平伸缩,关键是要配置 Pod 的 resources.requests。
  2. 崩溃恢复:分两层 ------ 第一层是 Pod 的 restartPolicy,优先重启容器;第二层是控制器兜底,Deployment/RS 保证无状态应用的副本数,StatefulSet 保证有状态应用的网络和存储不变;节点级故障则由 Node Controller 触发跨节点重建。

五、面试避坑提醒

  1. 不要只讲概念,一定要结合实际使用场景(比如无状态用 HPA+Deployment,有状态用 StatefulSet)。
  2. 遇到追问(比如 HPA 为什么失效?),优先答「没部署 Metrics Server」「没设置 requests」这两个最常见原因。

相关名词解释:

一、自动缩扩容相关组件

缩写 全称 中文翻译 核心作用(面试必答) 面试关联考点
HPA Horizontal Pod Autoscaler 水平 Pod 自动伸缩器 最常用的缩扩容组件:调整 Pod 的副本数量(比如 2 个扩到 5 个),适配流量变化 1. 依赖 Metrics Server 采集指标;2. 必须给 Pod 设置 resources.requests(否则无法计算资源使用率);3. 只适合无状态应用
VPA Vertical Pod Autoscaler 垂直 Pod 自动伸缩器 调整单个 Pod 的 CPU / 内存规格(比如 1 核扩到 2 核),解决单 Pod 资源不足问题 1. 和 HPA 的区别:HPA 调数量 ,VPA 调单 Pod 资源;2. 生产中一般不与 HPA 同时启用(避免冲突)
CA Cluster Autoscaler 集群自动伸缩器 集群节点层的伸缩:节点资源不足时自动新增节点 ,资源闲置时删除节点 1. 依赖云厂商的节点池(如 AWS EKS、阿里云 ACK);2. 伸缩层级:HPA(Pod 层)→ VPA(Pod 资源层)→ CA(节点层)
Metrics Server 无(本身是组件名) 指标服务器 K8s 集群的核心指标采集组件:采集 Pod / 节点的 CPU、内存使用率等基础指标 1. HPA 的必备依赖,K8s 默认不安装,需手动部署;2. 面试高频问:HPA 失效的常见原因?答:没装 Metrics Server 或 Pod 没设 requests

二、崩溃恢复相关组件

缩写 全称 中文翻译 核心作用(面试必答) 面试关联考点
Deployment 无(本身是资源对象名) 部署控制器 K8s 管理无状态应用 的核心控制器,底层依赖 RS 1. 核心能力:保证 Pod 副本数(崩溃后重建)+ 滚动更新 + 版本回滚;2. 崩溃恢复逻辑:监控实际 Pod 数 → 对比期望副本数 → 不足则通过 RS 重建;3. 面试必问:和 StatefulSet 的区别?
RS ReplicaSet 副本集 Deployment 的底层依赖组件 ,核心职责就是保证指定数量的 Pod 副本始终运行 1. 作用:Deployment 负责版本管理,RS 负责副本数兜底;2. 对比 Replication Controller(RC):RS 是 RC 的升级版,支持更灵活的标签选择器
StatefulSet 无(本身是资源对象名) 有状态集控制器 管理有状态应用(如 MySQL、Kafka)的控制器,崩溃恢复时保证状态不丢失 1. 恢复核心特性: - 固定 Pod 名称(如 mysql-0、mysql-1); - 绑定固定 PVC(数据持久化); - 通过 Headless Service 提供固定 DNS 解析;2. 面试必问:和 Deployment 的区别?(看下面表格)
Node Controller 无(本身是控制器名) 节点控制器 K8s 核心控制器之一,监控节点健康状态,处理节点级故障 1. 节点宕机处理流程:节点失联 5 分钟 → 标记为 NotReady → 触发 Pod 跨节点重建;2. 面试问:节点挂了,上面的 Pod 怎么办?答:Node Controller 标记节点异常,Deployment/RS 在其他节点重建 Pod

面试高频对比:Deployment vs StatefulSet

特性 Deployment(无状态) StatefulSet(有状态)
Pod 名称 随机生成(如 nginx-7f987f67c8-2xq5z) 固定有序(如 mysql-0、mysql-1)
存储 所有 Pod 共享一个 PVC(可选) 每个 Pod 绑定独立 PVC(数据隔离)
网络 通过普通 Service 访问(IP 不固定) 通过 Headless Service 访问(DNS 固定)
适用场景 Nginx、微服务 API、前端应用 MySQL 集群、Kafka 集群、Redis 集群

三、配套核心组件

缩写 全称 中文翻译 核心作用 面试关联点
PVC PersistentVolumeClaim 持久化卷声明 用户申请存储资源的接口,比如申请 10G 的 SSD 存储 1. StatefulSet 的核心依赖:每个 Pod 绑定独立 PVC,崩溃重建后数据不丢;2. 面试问:PVC 和 PV 的关系?答:PV 是集群的存储资源,PVC 是用户对 PV 的申请(类似租房:PV 是房子,PVC 是租房合同)
Headless Service 无(本身是 Service 类型) 无头服务 一种没有 ClusterIP 的 Service 1. 专为 StatefulSet 设计:给每个 Pod 分配固定的 DNS 域名(如 mysql-0.mysql-service.default.svc.cluster.local);2. 区别普通 Service:普通 Service 通过 ClusterIP 转发流量,Headless Service 直接解析 Pod IP
相关推荐
江湖有缘4 小时前
Fenrus + Docker 实战:构建简洁高效的浏览器新标签页
运维·docker·容器
Coder_Boy_4 小时前
Spring Boot 事务回滚异常 UnexpectedRollbackException 详解(常见问题集合)
java·spring boot·后端
青云交4 小时前
Java 大视界 -- 基于 Java+Redis Cluster 构建分布式缓存系统:实战与一致性保障(444)
java·redis·缓存·缓存穿透·分布式缓存·一致性保障·java+redis clus
不知疲倦的仄仄4 小时前
第五天:深度解密 Netty ByteBuf:高性能 IO 的基石
java·开源·github
xiaobaishuoAI4 小时前
后端工程化实战指南:从规范到自动化,打造高效协作体系
java·大数据·运维·人工智能·maven·devops·geo
期待のcode4 小时前
TransactionManager
java·开发语言·spring boot
Hello.Reader4 小时前
PyFlink JAR、Python 包、requirements、虚拟环境、模型文件,远程集群怎么一次搞定?
java·python·jar
计算机学姐4 小时前
基于SpringBoot的汽车租赁系统【个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·spring·汽车·推荐算法
七夜zippoe4 小时前
分布式事务解决方案 2PC 3PC与JTA深度解析
java·分布式事务·cap·2pc·3pc·jta