提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
-
- 第一篇:基础概念篇
- 第二篇:调度与资源管理篇
- 第三篇:网络篇
- 第四篇:存储与持久化篇
- 第五篇:权限与安全篇
- [第六篇:CI/CD 与部署优化篇](#第六篇:CI/CD 与部署优化篇)
- 第七篇:实战与故障排查篇
- 第八篇:监控与优化篇
- 第九篇:面试思维与答题策略
- 总结
前言
最近在准备跳槽的事情,但是并不算太如意
复习的过程中我发现,虽然自己在实际项目中用过不少 K8s 组件,但要系统、完整地回答面试官的问题,却并不容易,很多概念理解是零散的,很多原理也只停留在"会用",没到"说清楚"的程度
于是我决定把这次复习过程系统化,整理成一个《Kubernetes面试题汇总系列》,一方面是为了巩固自己的知识体系,查漏补缺 ;另一方面也希望能帮到正在准备面试或学习云原生的朋友
我打算从基础概念到调度、网络、存储、权限、安全,再到 CI/CD 与实战优化,按模块拆解整理,不只是题和答,更重要的是背后的逻辑和原理
这个系列会持续更新,希望这个系列既能成为我复习的笔记,也能成为你准备面试的捷径
第一篇:基础概念篇
定位: 夯实 Kubernetes 的基础认知,弄清组件与对象的关系
主要内容:
- K8s 的核心组件与架构(API Server、ControllerManager、Scheduler、etcd、Kubelet、Kube-Proxy)
- Pod、ReplicaSet、Deployment、Namespace 基础
- ConfigMap、Secret 的区别与使用场景
- Pod 生命周期与状态流转
- 控制器工作机制与 Reconciliation Loop
示例面试题:
- 描述一下K8s各种组件的功能?
控制平面
kube-apiserver:中心控制组件,负责处理所有 REST 请求,并将结果状态持久化到 etcd 中,提供了 K8s 集群的 API,是与 K8s 集群进行交互的唯一入口,并负责验证请求、进行身份认证和授权
kube-controller-manager:负责管理 K8s 集群中的所有控制器,每个控制器都负责一种资源状态的调整,确保 K8s 集群处于预期状态
kube-scheduler:默认调度器,负责调度 Pod 到合适的节点上,根据调度策略(如资源请求、亲和性、反亲和性等)为 Pod 选择一个最优的节点,只做决策,不实际执行 Pod 的创建过程
etcd:强一致性的分布式键值数据库,持久化存储整个集群的所有配置数据和状态数据,保证集群的的高可用性、可靠性及一致性
工作节点kubelet:每个节点上运行的主要组件,负责管理节点上容器的生命周期,定期向 master 节点报告当前节点和 Pod 的状态,是 master 和 node 节点通信的桥梁,执行主节点下发的命令
kube-proxy:网络代理,负责实现 K8s 服务的网络抽象和负载均衡,它将对服务的访问转发到后端的一组 Pod 上,提供服务的网络访问能力,确保服务的可靠性和可扩展性
容器运行时:负责在节点上运行容器的运行时环境,支持 Docker、Containerd、CRI-O 等,是容器化应用运行的基础,提供容器的创建、运行和管理能力
- K8s常见控制器有哪些?
- Deployment:管理无状态应用的部署和生命周期,用户只需声明目标状态,Deployment 控制器会自动对 Replicaset 进行操作,确保集群达到期望状态,提供滚动更新和回滚、扩缩容等能力 ;适用于不需要持久化存储或稳定网络标识的应用
- StatefulSet:管理有状态应用,确保每个 Pod 有唯一的网络标识和持久化存储,支持有序部署和扩展 ;适用于需要持久化数据和稳定网络标识的应用
- DaemonSet:确保在所有节点上都运行一个 Pod 副本,当有新节点加入 K8s 集群时,会自动在该节点上新增一个 Pod,当节点被移除时,Pod 也会被回收 ;适用于日志收集器(如 Filebeat)、节点监控代理(如 Node Exporter)、网络插件(如 flannel)等
- Job:用于完成一次性任务,支持重试和并行处理,并确保 Pod 在完成工作后终止 ;适用于一次性任务或周期性任务,如数据处理和分析
- CronJob:基于时间表(Cron 格式)周期性地运行 Job ;适用于定期备份、报告生成等场景
- ReplicaSet:确保在任何时候都有指定数量的 Pod 副本在运行,是 Deployment 底层真正控制副本数的组件,通常不直接操作,通过 Deployment 来管理它
- Pod分为有状态和无状态两种类型,请问它们的区别是什么?
无状态Pod
不存储需要持久化的数据,或数据存储在外部集群,实例完全等同且可替代
通常使用 EmptyDir(随 Pod 销毁而销毁)或直连外部存储服务(MySQL、Redis 等)
Pod 重建后,名字和 IP 都会发生改变
使用 Deployment 控制器,Pod 的创建、销毁和扩缩容都是无序、随机的
典型应用场景比如 web 服务器、API 网关、微服务等
有状态Pod必须持久化存储数据,每个 Pod 都有唯一的身份标识和稳定的持久化存储,实例不可替代
必须使用 PV 和 PVC,确保 Pod 重启或重新调度时能挂载到同一个数据卷,确保数据不丢失
具有稳定的网络标识(如 DNS 名称),Pod 名称也是固定不变的
使用 StatefulSet 控制器,Pod 的创建、销毁等都遵循严格的顺序(如从 0 到 N-1 的顺序扩展)
典型应用场景比如数据库、消息队列、分布式缓存等
- Pod频繁重启是什么原因,如何排查?
根本原因是容器进程终止了,kubelet 会根据 Pod 的 RestartPolicy 策略(通常是 Always)尝试重启来恢复服务
常见原因
OOM:Pod 内存 requests / limits 设置过小,触发 OOM
应用本身 bug:代码存在未处理的异常(如空指针、内存泄漏等);依赖服务(数据库、API)不可用导致频繁重启
存活探针配置不当:检测路径、端口或超时时间错误 ;应用启动较慢,但 initalDelaySeconds 设置过短,导致探测过早触发
节点资源不足:节点 CPU、内存耗尽,网络故障或其他硬件故障
镜像问题:私有镜像未配置 imagePullSecrets 或镜像标签错误 ;镜像中未指定持久化进程,启动后立即退出
排查步骤检查 Pod 状态与事件:使用 kubectl describe pod 查看,结合 Events 和 Containers 部分内容,重点关注 Last State,能看到 Pod 重启原因(如 OOMKillerd、ERROR 等)、状态码等信息,非 0 状态码代表异常退出(应用进程崩溃、抛出未捕获的异常等)
检查 Pod 日志:使用 kubectl logs 查看日志,以及使用 --previous 参数查看 Pod 重启前的日志是否有异常信息
检查探针配置:如果前两步都没有发现明显错误,那么可能是存活探针失败导致的重启,检查 Pod 的 Yaml 文件定义中 livenessProbe 的配置,排查探测端点(path)是否设置错误 ;或者是初始延迟时间太短,应用启动较慢导致还没准备好接收请求,探针就开始检查并失败 ;超时时间(timeoutSeconds)或探测周期(periodSeconds)设置不合理
检查资源限制:如果看到 OOM,使用 kubectl top pod 查看 Pod 的资源使用情况,kubectl describe 查看资源限制,检查 limits.memory 是否小于 Pod 实际运行时的内存
深入排查:如果上面步骤都无法定位问题,使用 kubectl describe node 查看节点总体资源分配和剩余情况,可能是节点资源不足导致 Pod 被驱逐,查看 Conditions 部分是否存在磁盘压力、内存压力等问题 ;确认容器镜像的版本和标签是否正确 ;如果 Pod 挂载了 PVC,检查存储是否能成功挂载
- Pod创建的底层流程是什么?
- 集群管理员通过kubectl或者客户端等构建 REST 请求,经由 API Server 进行鉴权认证(使用 kubeconfig 文件),验证准入信息后将请求数据(metadata)写入 etcd 中
- 控制器组件通过 watch 机制发现创建 Pod 的信息,并将整合信息通过 API Server 写入 etcd 中,此时 Pod 处于可调度状态
- 调度器组件基于 watch 机制获取可调度 Pod 的列表信息,通过调度算法(过滤或打分)为待调度 Pod 选择最合适的节点,并将创建 Pod 信息写入 etcd 中,创建请求发送给节点上的 kubelet
- kubelet 收到 Pod 创建请求后,调用 CNI 接口为 Pod 创建网络环境,调用 CRI 接口创建 Pod 内部容器,调用 CSI 接口对 Pod 进行存储卷的挂载
- 等待 Pod 内部运行环境创建完成,基于探针或者监控检查监测业务运行容器启动状态,启动完成后 Pod 处于 running 状态,Pod 进入运行阶段
- Kubelet的功能、作用是什么?
- Pod生命周期管理
kubelet 会持续监听 API Server,一旦发现有分配给其所在节点的 Pod,会根据 Pod 定义文件中的描述,调用底层的容器运行时来拉取镜像并启动容器 ;kubelet 确保 Pod 中所有容器都健康运行,如果某个容器崩溃,kubelet 会根据 Pod 的重启策略决定是否重启 ;当 API Server 通知删除 Pod 时,kubelet 会先发送 SIGTERM 信号优雅终止 Pod,并清理相关资源- 节点状态报告
kubelet 定期向 API Server 发送节点状态,包括 CPU、内存、磁盘空间等,这些信息是 Master 做出调度决策的基础 ;通过 cAdvisor 收集本节点上所有 Pod 和容器的资源使用量- 与容器运行时交互
kubelet 通过 CRI 标准接口与容器运行时进行通信 ;kubelet 本身不直接操作容器,而是通过 CRI 来执行比如创建、启动、停止等操作 ;kubelet 支持多种容器运行时- 容器健康检查
kubelet 负责执行 Pod 中定义的三种探针,比如启动探针判断容器是否已启动完成 ;存活探针判断容器是否还在正常运行,如果检查失败,kubelet 会重启该容器 ;就绪探针判断容器是否已准备好接收流量,如果检查失败,kubelet 会将该 Pod 从关联的 Service 的负载均衡端点(Endpoints)中移除- 与网络和存储插件交互
kubelet 不直接提供网络,但它会调用 CNI 插件(如 flannel)为 Pod 配置网络 ;kubelet 会调用 CSI 插件来挂载 Pod 请求的持久化存储卷
- 描述一下Pod生命周期?
Pod生命周期状态
Pending(挂起):Pod 已经被 API Server 接受,但有一个或者多个容器尚未创建完成 ;通常处于拉取镜像、调度决策的阶段
Rrunning(运行):Pod 已经绑定到了某个节点,并且所有容器都已经被创建,至少有一个容器仍在运行或者正在启动或重启中
Succeeded(成功):Pod 中的所有容器都已成功终止,并且不会再重启 ;常见于 Job
Failed(失败):Pod 中的所有容器都已终止,并且至少有一个容器是因为失败而终止(非 0 状态码退出)
Unknown(未知):通常是因为与 Pod 所在节点的 kubelet 通信失联,无法获取 Pod 的状态
补充说明CrashLoopBackOff:
复合状态,本质上来讲是因为 Pod 不断崩溃,然后被 kubelet 不断重启导致的,K8s 为了应对这种故障,会使用指数退避策略来延迟重启的时间,这个阶段就是 CrashLoopBackOff ;常见触发原因比如应用自身错误(代码 bug、配置错误等)、资源配额不足(CPU 或内存设置过小导致 OOM)、探针配置不当(存活探针配置错误)、镜像问题(镜像不存在或无法拉取等)Terminating:
过渡状态,本质上来讲是因为执行 kubelet delete pod 后,Pod 不会立即消失,会进入 Terminating 状态,并执行优雅终止流程 ;常见触发原因比如节点失联(Node 节点宕机或与 Master 的网络中断等)
- K8s命名空间的作用是什么?
- 资源隔离
把集群内的资源(如 Pod、Service 等)进行资源隔离,避免不同业务的资源相互干扰 ;比如把生产环境和测试环境分别在 prod 和 test 命名空间运行,即使资源名字相同也不会冲突- 权限控制
RBAC(基于角色的访问控制)的作用域,可以针对某个命名空间设置用户的访问权限 ;比如开发人员只允许访问 dev,而运维人员可以访问所有- 资源配额管理
可以为命名空间配置资源配额,限制该命名空间内的 CPU、内存、Pod 数量等 ;比如创建 ResourceQuota 资源使用 hard 对命名空间 test 进行资源配额,避免测试环境占满整个集群资源- 便于管理和组织
命名空间相当于逻辑分组 ;比如使用 kubelet get pod -n 就能快速查看某个业务 Pod,避免全局混乱
第二篇:调度与资源管理篇
定位: 理解调度器如何决策 Pod 的归宿
主要内容:
- Scheduler 调度流程与调度算法
- NodeAffinity、PodAffinity、Taint/Toleration
- Requests、Limits、QoS Classes
- Pod Priority 与 Preemption
- 节点标签与调度约束
示例面试题:
- Pod是如何被调度到节点上的?
Pod 被调度到节点上的过程,核心是由 kube-scheduler 这个核心组件来驱动的,整个过程可以概括为过滤和评分两个核心阶段,当创建一个 Pod 时,API Server 会接收到这个请求,并将其持久化到 etcd 中,此时这个 Pod 在 API Server 中的记录是 pending 状态,并且 nodeName 字段是空的,kube-scheduler 作为一个控制器会持续监听 API Server,寻找那些 nodeName 为空且未被调度的 Pod,一旦发现这样的 Pod,调度器便会开始工作
过滤
这个阶段也称为 Predicate,调度器会基于一系列预定义的策略,对所有健康的节点进行筛选,过滤掉那些不满足要求的节点,目标是找出一个可以运行该 Pod 的节点候选集,常见的
过滤策略包括:
- PodFitsResources:检查节点的可分配资源(CPU、内存)是否满足 Pod 的requests 中声明的需求,如果一个节点剩余的可分配 CPU 不足 1 核,而 Pod 请求了 1 核,那么这个节点会被过滤掉
- PodFitsHostPorts:检查 Pod 声明的 hostPort 在节点上是否已经被占用
- MatchNodeSelector:检查节点标签是否匹配 Pod 规范中定义的 nodeselector 或 nodeAffinity 规则
- CheckNodeVolumeZone:检查持久卷的可用区是否与节点匹配,主要用于跨多可用区的集群
- CheckNodeMemoryPressure / CheckNodeDiskPressure:检查节点是否存在内存或磁盘压力,如果节点压力过大,则不会将 Pod 调度上去
- PodToleratesNodeTaints:检查 Pod 的 tolerations 是否能够容忍(Tolerate)节点的污点(Taint),这是实现 Pod
排斥机制的关键
评分这个阶段也称为 Priority,当有多个节点都满足基本要求时,调度器需要决定哪个是"最优"的,调度器会为每个候选节点进行打分,分数范围是 0~10 分,得分最高的节点就是最终被选中的节点,常见的
评分策略包括:
- LeastRequestedPriority:倾向于将 Pod 调度到资源请求需求更少的节点上,换句话说,优先选择资源更充裕的节点,计算公式大致是
得分=(节点可分配 CPU - Pod 请求 CPU) / 节点总 CPU * 10,内存同理,然后取平均值- BalancedResourceAllocation:在节点上平衡 CPU 和内存的使用率,它倾向于选择调度后 CPU 和内存使用率更均衡的节点,避免出现 CPU 用满而内存剩余很多或很少的情况
- ImageLocalityPriority:倾向于选择已经缓存了 Pod 所需容器镜像的节点,可以加速 Pod 启动过程
- NodeAffinityPriority:根据节点亲和性规则进行加权评分
- InterPodAffinity / Anti-Affinity:根据 Pod 亲和性或反亲和性规则进行评分,比如希望同一服务的多个 Pod 分散在不通节点上(使用反亲和性)以获得高可用
最终绑定选出最优节点后,调度器并不会直接去节点上创建 Pod,它会调用 API Server,执行一个
绑定操作,将这个 Pod 的 nodeName 字段更新为选中的节点名称,这个写操作被 API Server 接收后,Pod 在 Etcd 中的记录就被更新了,随后该节点上的 kubelet(它也会持续监听 API Server 中与自己节点相关的 Pod)会检测到这个属于它的、且尚未运行的 Pod,于是 kubelet 会负责拉取镜像、创建容器、启动 Pod 等一系列操作
- 什么是QoS Class?
QoS Class,全称是服务质量等级,它是 K8s 内部根据 Pod 中容器设置的资源请求和限制,自动为 Pod 分配的一个优先级分类,核心目的是在节点资源(主要是 CPU 和内存)不足时,帮助 K8s 做出决策,决定应该"牺牲"哪些 Pod 来保障更重要的 Pod 运行,从而确保整个系统的稳定性
K8s 将 Pod 的 Qos Class 分为三个等级,从高到底依次是:Guaranteed > Burstable > Best-Effort
- Guaranteed(保证级别)- 最高优先级
这类 Pod 获得所需要的资源的保证,当节点资源耗尽时,这类 Pod 是最后被考虑杀死的,因此服务质量最高
判定条件:Pod 中的每一个容器都必须设置资源请求和资源限制 ;对于 CPU 和内存这两种资源,请求值必须等于限制值
适用场景:核心业务,如数据库、关键应用服务,需要确保它们在任何情况下都能获得所需资源- Burstable(可突发级别)- 中等优先级
这类 Pod 被确保能获得它所请求的资源量,在节点充足时,它有可能突发使用超过请求值的资源(但不能超过限制值);当节点资源不足时,它的优先级低于 Guaranteed,但高于 Best-Effort
判定条件:Pod 不符合 Guaranteed 的标准 ;但 Pod 至少有一个容器设置了资源请求或限制
适用场景:大多数常规业务应用,平时资源需求稳定,但在高峰期可能需要更多资源- Best-Effort(尽力而为级别)- 最低优先级
这类 Pod 可以使用的资源没有下限(请求为 0),也没有上限(理论上可以使用节点所有空闲资源),但是当节点资源不足时,它们会是最先被系统杀死的对象
判定条件:Pod 中的所有容器都没有设置任何资源请求和限制
适用场景:非核心的、可随时重启的批处理任务等,对可用性要求不高的场景
- 如何让Pod优先调度到某台节点?
使用节点亲和性的"软偏好"规则,给目标节点打上一个独特标签,然后再 Pod 的配置中声明对该标签的偏好,并赋予较高权重
- 标记目标节点
使用 kubectl lable nodes 在那台希望优先调度的节点上打上一个独特的标签- 在Pod中声明偏好
在我们想要调度的 Pod 的配置中,声明一个节点软亲和性规则 preferredDuringSchedulingIgnoredDuringExecution- 设置偏好权重
配置 weight 权重值字段,取值范围是 1~100,这个权重值代表了这条偏好的重要性,权重越高,调度器在决策时就越倾向于满足这个条件
- 节点亲和性(Node Affinity)有哪几种类型,有什么区别?
节点亲和性类型
硬亲和性(requiredDuringSchedulingIgnoredDuringExecution):强制性规则,必须满足,如果集群中没有任何一个节点满足 Pod 所设置的硬亲和性规则,那么 K8s 调度器就不会把这个 Pod 分配到任何节点上,它将一直处于无法运行的 Pending 状态 ;通常用于有严格运行要求的场景,比如必须运行在带有 GPU 的节点上
软亲和性(preferredDuringSchedulingIgnoredDuringExecution):偏好型规则,尽量满足,它不会导致 Pod 无法调度,可以通过 weight 字段(取值范围 1~100)为多个软性规则设置优先级,权重越高优先级也就越高
共同点和配置无论是硬亲和性还是软亲和性,规则仅在
调度时刻起作用,一旦 Pod 被成功调度到某个节点上,即使该节点的标签后来发生了变化,变得不再符合亲和性规则,Pod 也不会被驱逐,它会继续在该节点上运行节点亲和性支持丰富的操作符,如 In、NotIn、Exists、DoesNotExist、Gt、Lt 等 ;如果 nodeSelectorTerms 下有多个 matchExpressions,则节点必须满足所有表达式(逻辑与关系),如果定义了多个 nodeSelectorTerms,则节点只需满足其中任意一个即可(逻辑或关系)
- 节点资源不足时K8s如何处理?
节点压力驱逐
- 资源监控与压力检测
kubelet 持续监控节点的资源使用情况,主要包括内存、磁盘空间、进程号等,当资源使用量超过阈值时,节点就报告相应的压力信号,比如 MemoryPressure、DiskPressure- 节点污点与调度阻止
一旦这些节点出现压力,kubelet 会自动给这些节点打上对应的污点,比如 node.kubernetes.io/memory-pressure,这个污点会阻止新的 Pod 被调度到本节点上(效果是 NoSchedule),避免雪上加霜- 主动驱逐 Pod
kubelet 会开始主动驱逐节点上的 Pod 以释放资源,kubelet 不是随机驱逐的,而是按照 Pod 的 QoS 等级和资源使用情况进行排序驱逐,首选驱逐 BestEffort 类型的 Pod,其次驱逐 Burstable 类型的 Pod,最后考虑驱逐 Guaranteed 类型的 Pod- 软驱逐与硬驱逐
软驱逐:当资源使用量超过"软阈值"时,kubelet 会有一个宽限期,只有在超过宽限期后才会开始驱逐
硬驱逐:当资源使用量超过"硬阈值"时,kubelet 会立即开始驱逐 Pod,没有宽限期
补充:软阈值可通过 kubelet 配置文件 /var/lib/kubelet/config.yaml 添加或修改evictionSoft和evictionSoftGracePeriod字段后重启 kubelet 生效,硬阈值可通过配置evictionHard字段后重启 kubelet 生效
系统OOM Killer如果 kubelet 的驱逐机制跟不上资源消耗的速度(比如某个进程突然疯狂申请内存),系统可能会触发无法响应的状态,并触发 Linux 内核的 OOM Killer,以释放内存恢复系统
第三篇:网络篇
定位: 掌握 K8s 网络通信模型与常见问题排查
主要内容:
- Kubernetes 网络模型原则
- CNI 插件(Flannel、Calico、Cilium)
- Service 类型(ClusterIP、NodePort、LoadBalancer、ExternalName)
- Ingress 控制器原理
- DNS 服务与内部解析机制
- NetworkPolicy 安全策略
示例面试题:
- 解释一下Service的四种类型?
- ClusterIP:默认类型,仅在 K8s 集群内部访问,不能被外部直接访问 ;适用于微服务内部通信
- NodePort:绑定一个固定端口,外部可以通过 NodeIP:NodePort 访问服务 ;适用于临时测试、内网访问
- LoadBalancer:云端负载均衡 ;适用于云环境,自动分配公网 IP,通过云负载均衡器(ELB、ALB)进行流量分发
- ExternalName:DNS 代理,用于将 K8s 内部服务映射到外部域名(如 MySQL),不会创建实际的负载均衡或代理,仅提供 DNS 解析
- Service是如何实现负载均衡的?
Service 的负载均衡机制是一个分布式的、基于内核网络规则的负载均衡,它依靠每个节点上的 kube-proxy 组件监听 API Server 中的 Service 与 Endpoints 变化,动态维护本机的转发规则,kube-proxy 通过 iptables 或 IPVS,将所有发往 Service 虚拟 IP(ClusterIP) 的流量,通过 DNAT 的方式,透明且随机的转发到后端健康的 Pod 上,从而实现集群内的负载均衡
- 定义服务:用户创建 Service,指定 selector
- 发现后端:Endpoints Controller 监控 Service 和 Pod,动态维护同名 Endpoints 对象,存储健康后端 Pod IP:Port 列表
- 分发规则:所有节点上的 kube-proxy 监听 Endpoints 变化,获取最新后端列表
- 配置规则:每个 kube-proxy 在本机内核配置负载均衡规则(iptables / IPVS),将 Service VIP 映射到动态后端列表
- 流量均衡:发往 Service VIP 的流量,在入节点被内核规则拦截,根据算法选择后端 Pod,执行 DNAT 后转发
- 动态更新:Pod 变化 -> Endpoints 更新 -> kube-proxy 更新规则 -> 后续流量使用新列表
- Service是怎么知道哪些Pod可以接收请求的?
Service 会根据自己的 selector 匹配符合标签的 Pod,然后把这些 Pod 的 IP 和端口记录在 Endpoints 对象中,如果 Pod 的就绪探针没有通过,就不会被加入到 Endpoints 中,探针通过自动加入 ;如果 Pod 被删除或探针失败,则会从 Endpoints 中移除
- Pod被删除或重建时,Service会发生什么变化?
Service 本身是通过 Endpoints 对象来维护 Pod 列表的,当 Pod 被删除或不再处于 Ready 状态时,kube-controller-manager 会立即从 Endpoints 中移除它 ;新的 Pod 创建后,一旦就绪探针通过,就会自动加入 Endpoints,整个过程 kube-proxy 会实时更新负载规则
当 Pod 被删除或重建时,K8s 会自动更新 Service 的 Endpoints 对象,旧的 Pod IP 会立即被移除,新 Pod 启动后通过就绪探针检查成功后才会被加回来,这样可以保证负载均衡只转发给健康的 Pod,从而避免请求中断
- Pod之间的通信是如何实现的?
- 同一Pod内:通过 localhost 直接通信
- 同一节点内:通过节点上的虚拟网桥直接转发
- 跨节点:由 CNI 插件(如 flannel)通过 Overlay 网络或路由模式实现互通
第四篇:存储与持久化篇
定位: 深入理解有状态服务的存储机制
主要内容:
- Volume、PersistentVolume、PersistentVolumeClaim、StorageClass
- PV 生命周期与绑定过程
- Volume 类型(EmptyDir、HostPath、NFS、CSI)
- StatefulSet 与持久化存储
- 数据恢复与回收策略
示例面试题:
- PV的回收策略有哪些?
- Retain(保留)
默认且最常用、最安全的策略,当绑定的 PVC 被删除后,PV 不会被自动删除,它的状态会变为 Released(已释放),但卷本身和存储在卷上的所有数据都会被完整的保留下来 ;处于 Released 状态的 PV 不能被新的 PVC 直接绑定,需要手动介入来处理这个卷
场景一:清理数据并重新使用 -> 删除 PV 对象(kubectl delete pv),但后端存储资产(如云磁盘、NFS 目录)依然存在 ;按照需求手动清理后端存储资产上的数据 ;创建一个新的 PV 对象来代表这个清理过的存储资产
场景二:直接恢复数据 -> 如果需要,可以从这个保留的卷中恢复误删的数据
场景三:直接销毁 -> 如果数据不再需要,可以手动删除 PV 对象,并同时在后端存储系统上删除对应的存储资产- Delete(删除)
当绑定的 PVC 被删除后,K8s 会自动执行删除集群内的 PV 对象,并在后端的存储设施(如 AWS EBS)中删除对应的存储资产,数据也会随之被永久销毁 ;适用于动态制备的存储场景
实现机制:依赖于 PV 所使用的 StorageClass(存储类)中配置的 provisioner(存储制备器),是制备器在 PVC 删除时,去调用云供应商的 API 执行了真正的删除操作- Recycle(回收)- 已废弃
K8s 早期提供的简单回收机制,当 PVC 被删除后,PV 上的数据会被简单擦除,然后 PV 状态变为 Available(可用),等待被新的 PVC 绑定
- NFS、HostPath、EmptyDir的区别?
- EmptyDir(空目录):临时工作空间
生命周期:与 Pod 完全绑定,当 Pod 被分配到某个节点上时,EmptyDir 被创建 ;当 Pod 从该节点上删除(无论何种原因),EmptyDir 和其中的数据会被永久清理
数据存储位置:默认存储在节点本地磁盘上,速度极快,但节点重启后数据即丢失
核心用途:同一个 Pod 内多个容器之间的共享存储 ;为计算密集型应用(如数据分析)提供临时缓存空间,加速处理 ;存放中间状态,以便在容器崩溃重启后能快速恢复- HostPath(主机路径):节点挂载
生命周期:与节点绑定,它将节点服务器上的一个实际目录直接挂载给 Pod 使用,Pod被删除后数据依然保留在节点的硬盘上,但如果 Pod 被调度到另一个节点,或者节点本身宕机、被销毁,数据将无法访问或永久丢失
数据共享性:可以被调度到同一节点上的多个 Pod 共享访问
核心用途:Pod 运行需要访问节点本身资源,如 Node Exporter 需要访问 /proc、/sys 来收集节点指标,Filebeat 需要访问节点的 /var/log 目录- NFS(网络文件系统):网络持久化存储
生命周期:独立持久化,数据存储在远程的 NFS 服务器上,Pod 和节点的生命周期与数据完全解耦,无论 Pod 如何重建、调度到哪个节点、甚至节点宕机,数据都安全的存在于远程 NFS 服务器上
数据共享性:支持跨节点、跨 Pod 的读写共享
核心用途:持久化应用数据如数据库文件、用户上传的内容 ;多个 Pod 需要读取同一套配置文件
第五篇:权限与安全篇
定位: 掌握 RBAC 模型与集群安全机制
主要内容:
- RBAC(Role、ClusterRole、RoleBinding、ClusterRoleBinding)
- ServiceAccount 与授权机制
- Secret 的安全存储与访问
- Admission Controller 与安全策略
- 网络安全与多租户隔离
示例面试题:
- RBAC权限模型的核心概念?
- 主体 - 权限的授予对象
主体是需要在 K8s 中执行操作的用户、用户组或服务,主要有两类
ServiceAccount:这是最常见的主体,它是 K8s 命名空间内的资源,为运行在集群中的 Pod 内部进程提供身份标识,比如一个监控组件的 Pod 需要一个 ServiceAccount 来获取读取集群指标的权限
User:通常指通过证书或外部系统验证的外部用户,通常是开发者或管理员通过 kubelet 访问集群- 资源与操作 - 权限的具体内容
权限始终围绕"能对什么资源做什么操作"来定义
资源:K8s 中的 API 对象,比如核心资源 Pod、services、configmaps、secrets、nodes 等,扩展资源 deployments.app、statefulsets.apps 等,可以通过 kubectl api-resources 命令查看所有资源列表
操作:对资源执行的动词,对应 HTTP API 的请求方法,包括查询资源 get、list、watch,增删改资源 create、update、patch、delete,特殊操作 use、bind 等,特殊的动词 * 代表所有操作- 角色 - 权限规则的集合
角色是一组权限规则的集合,它定义了"能做什么",K8s 中有两种角色,它们结构完全相同,但作用范围不通
Role:作用范围是单个命名空间内,资源类型 Role、RoleBinding,适用场景为定义特定项目或环境内的权限
ClusterRole:作用范围是整个集群,资源类型 ClusterRole、ClusterRoleBinding,定义集群级别资源(如 nodes,pv)的权限,或为所有命名空间提供通用权限- 角色绑定 - 将角色授予主体
角色绑定建立了主体和角色之间的桥梁,它决定了"谁"获得了"哪个角色"的权限,与角色对应,也有两种绑定
RoleBinding:绑定对象为一个 Role 或一个 ClusterRole,作用范围是单个命名空间
ClusterRoleBinding:绑定对象为一个 ClusterRole,作用范围是整个集群
第六篇:CI/CD 与部署优化篇
定位: 将 Kubernetes 与持续集成、持续部署体系融合
主要内容:
- Deployment 滚动更新与回滚
- StatefulSet、DaemonSet、Job、CronJob 应用场景
- startupProbe、livenessProbe、readlinessProbe Helm Chart 原理与模板化管理
- 与 Jenkins/GitLab CI 集成自动部署
- 灰度发布与蓝绿部署策略
示例面试题:
- K8s的探针有几种?
按类型划分
启动探针(startupProbe):检测应用程序是否已经成功启动,在成功之前,K8s 会禁用存活和就绪探针的检查,一旦启动成功一次,就永远不会再触发 ;作用是防止因为应用启动过慢,导致存货探针在应用还没准备好之前就连续探测失败,从而误杀容器
存活探针(livenessProbe):检测容器是否还在正常运行,如果存活探针检查连续失败,K8s 会认为容器已经不健康了,它会根据重启策略杀死并重启该容器 ;作用是修复由于内存溢出等导致应用进程还在但已经无法提供服务的故障状态,是保障高可用的核心机制
就绪探针(readlinessProbe):检测容器是否已经准备就绪可以开始接收外部流量,如果就绪探针检查失败,K8s 的 Service 会将该 Pod 从负载均衡器的端点列表中移除,这样新的流量就不会再被发送到这个 Pod,直到就绪探针再次成功,才会被重新加回列表 ;作用是保证流量只被发送到已经准备好处理请求的 Pod
按检查方式划分HTTP 探针:发送 HTTP 请求检查返回码 ;适合 web 服务
TCP 探针:检测端口是否能建立连接 ;适合非 HTTP 应用,比如数据库
Exec 探针:在容器内部执行命令检查结果 ;适合自定义逻辑,比如检测某个文件是否存在
HTTP 探针返回 200~399 被视为成功,Exec 探针 exit code 为 0 视为成功
第七篇:实战与故障排查篇
定位: 面试中最能体现经验的一环
主要内容:
- Pod Pending、CrashLoopBackOff、ImagePullBackOff 问题排查
- 节点宕机后的恢复机制
- kubelet 日志与事件分析
- etcd 备份与恢复
示例面试题:
- Pod一直Pending的可能原因?
遇到 Pending 的 Pod,第一个且最重要的命令时 kubectl describe pod,重点关注 Events 部分的最后几条信息,调度器会明确告知失败的原因
原因一:资源不足(最常见的原因)
CPU 或内存不足:调度器在过滤节点时,发现没有节点拥有足够的可分配资源来满足 Pod 的请求,根本原因是 Pod 配置中定义了 resoucres.requests,但集群中所有节点的剩余可分配资源都无法满足这个请求,可通过
kubectl describe nodes | grep -C5 "Allocatable"和kubectl top nodes查看实际资源使用情况。解决方案是扩容集群,增加新节点 ;调整已有 Pod 的 resoures.requests / limits,释放资源存储资源不足:Pod 使用了 PVC,但 PVC 无法绑定到合适的 PV,可通过
kubectl get pvc和kubectl describe pvc查看 PVC 状态
原因二:调度约束不满足节点选择器 / 节点亲和性不匹配:Pod 中配置了 nodeSelector 或 nodeAffinity 规则,但集群中没有节点拥有匹配的标签 ;检查 Pod 的 YAML 文件中的亲和性配置,并用
kubectl get nodes --show-lables查看节点标签Pod 亲和性 / 反亲和性过于严格:规则定义过于严格,导致找不到满足拓扑域约束的节点,比如要求必须和某个 Pod 在同一节点,但目标 Pod 还未调度成功 ;检查 Events 中的错误信息,并审查 Pod 的亲和性 / 反亲和性规则
节点污点于 Pod 容忍度不匹配:节点被打上了污点,而 Pod 没有配置相应的容忍度,导致 Pod 无法被调度到该节点 ;使用 kubectl describe node | grep Taints 排查,并在 Pod 的 YAML 文件中配置 spec.tolerations 添加对应的容忍策略
原因三:节点本身问题节点状态异常,导致其被调度器排除在候选列表之外
节点不可调度:节点状态为 NotReady(如 kubelet 进程异常、网络插件故障、机器宕机等),NotReady 的节点不会被调度 ;可使用
kubectl get nodes进行排查节点有磁盘或内存压力:节点磁盘空间已满或严重不足,节点会打赏 MemoryPressure 或 DiskPressure 污点,阻止新的 Pod 调度上来 ;可使用 kubectl describe node 查看 Conditions 部分
其他原因不满足端口请求:Pod 配置了 hostPort 或 hostNetwork,但所需端口在节点上已被占用
镜像拉取策略问题:在开始拉取镜像前,如果节点无法访问镜像仓库,也可能导致调度器在评估阶段就犹豫不决,但更常见的表现是 ImagePullBackOff
kube-scheduler 本身故障:极少数情况,调度器组件本身挂掉导致没有 Pod 能被调度
- 节点宕机后Pod如何恢复?
- 故障检测:控制平面发现节点异常
当一台工作节点宕机后,集群控制平面中的 kube-controller-manager 会持续检测节点的心跳(由 kubelet 定期上报),如果节点在预设的超时时间(默认 40 秒)内没有上报状态,控制平面就会将该节点的状态标记为 NotReady,此时该节点上所有 Pod 的状态会变为 Unknown 或 Terminating,但请注意,这只是一个状态标记,并不会立即触发任何操作- 触发驱逐:标记Pod为需重建状态
接下来,另一个重要的控制器 node-controller 会在一个更长的容忍时间(默认是 5 分钟)后,正式判定该节点为不可用(Unreachable),此时 node-controller 会为这些 Unknown 状态的 Pod 添加一个污点(Tanit),比如 node.kubernetes.io/unreachable- 核心恢复:控制器开始工作
情况一:Pod 由控制器管理
控制器(如 deployment-controller)会持续监控它应该管理的 Pod 数量(期望副本数),当它发现有一个 Pod 因为节点宕机而处于 Unknown 状态时,它会认为这个 Pod 已经丢失了,为了满足期望的副本数,控制器会立即在 K8s 集群中创建一个全新的 Pod 实例,这个新的 Pod 会进入正常的调度流程,由 kube-scheduler 将其分配到一个当前健康且资源充足的节点上,然后由该节点的 kubelet 拉取镜像并启动容器
情况二:Pod 是自主式 Pod(没有控制器管理)
如果是直接用 kubectl run 创建且没有绑定控制器的 Pod,那么它不会被自动恢复,这个 Pod 会一直处于 Unknown 状态,直到节点恢复或者管理员手动删除它- 调度与重建
新创建的 Pod 会被调度器分配到一个健康的节点上,一旦 Pod 被成功调度并启动,且通过就绪检查(如果有配置),它就可以开始接收流量提供服务了
- kubectl常用诊断命令?
- 资源查看类
查看当前命名空间下所有核心资源的基本状态:kubectl get all
查看 Pod 列表:kubectl get pods,可选参数 -o wide(显示 Pod IP 和所在节点)、-w(持续观察变化)、--show-labels(显示标签)
查看所有节点状态:kubectl get nodes,可选参数 -o wide(显示节点 IP 和资源容量)
查看集群级别的事件流:kubectl get events,可选参数 --sort-by=.metadata.creationTimestamp(按时间排序)、--field-selector involvedObject.name=pod-name(只看特定 Pod 的事件)- 深入诊断类
获取资源详细配置和状态:kubectl describe,重点关注 Events、Conditions、标签、镜像、IP 等详细信息
查看 Pod 标准输出日志:kubectl logs pod-name,可选参数 -c(指定多容器 Pod 中的某个容器)、-f(实时追踪日志)、--previous(查看上次崩溃的容器日志,用于诊断 CrashLoopBackOff)
进入正在运行的容器内部调试:kubectl exec -it pod-name -- /bin/sh,用于检查环境变量、配置文件、网络连通性等- 网络与服务诊断类
验证 Service 是否正确关联到后端 Pod:kubectl get endpoints service-name,诊断 Service 是否工作的关键命令,如果 Endpoints 为空,说明没有匹配标签的 Pod
查看 Service 的详细配置:kubectl describe service service-name,查看如 ClusterIP、端口、选择器等- 性能与资源诊断类
查看节点和 Pod 的实时资源使用率(CPU / 内存):kubectl top nodes / kubectl top pods,前提集群已部署 metrics-server
查看节点的详细资源分配情况:kubectl describe node node-name,输出中的 Allocatable和 Allocated resources 部分可以看到资源总量和已分配量,判断是否资源不足- 模拟与验证类
验证 YAML 文件语法是否正确:kubectl apply --dry-run=client -f file.yaml,干运行,不会实际创建资源
以 YAML 格式输出资源的当前实际运行配置:kubectl get -o {resoucre} {name}, 用于对比实际配置与期望配置是否一致
端口转发: kubectl port-forward {pod-name} {local-port}:{pod-port},将本地端口映射到 Pod 的端口,用于临时从本地网络访问集群内的 Pod 服务,进行调试和测试
第八篇:监控与优化篇
定位: 让面试官看到你有工程视角
主要内容:
- Metrics-server、Prometheus、Grafana
- EFK / Loki 日志采集体系
- Pod 资源优化与 HPA(水平自动伸缩)
- 集群容量规划与性能调优
示例面试题:
- 解释一下HPA的工作原理?
周期性的监控目标 Pod 的指标数据,并与用户定义的期望指标值进行比对,进而计算并调整 Pod 数量,以使实际指标值尽可能接近期望值
- 监控指标采集
HPA 工作的基础,K8s 通过 Metrics API 来获取资源指标数据,需要部署 Metrics Server 或 Prometheus + Prometheus Adapter,使用 kebectl top pod 命令快速验证基础资源指标是否正常- 指标查询与比对
HPA 控制器默认每 30 秒(可通过 --horizontal-pod-autoscaler-sync-period 调整)进行一次决策循环,在每次循环中,它会通过 Metrics Server 获取当前该 Deployment 下所有 Pod 的指定指标的平均值,根据当前指标值和目标值,使用算法计算出期望的 Pod 副本数,然后通过 API Server 直接修改目标资源的 spec.replicas 字段,最后 Deployment 控制器会感知到期望状态的变化,开始驱动创建或删除 Pod 的流程,使实际状态与期望状态一致
- 服务流量激增,但HPA并未及时扩容,导致部分请求失败,你会如何优化HPA策略已提升响应能力?
- 调整HPA触发阈值
修改 CPU 阈值,提前触发扩容
增加副本数上线(maxReplicas),防止因副本数限制而无法继续扩容- 调整扩缩容阈值
修改 kube-controller-manager 的启动参数,默认值是 10%,可以调整为 5%,这样系统会更快的触发扩容决策- 调整扩缩容速度参数
HPA 默认每次扩容 1~2 个 Pod,可以调整 HPA 的 behavior 字段中的 scaleUp 策略,允许每次扩容更多 Pod
- HPA没有根据指标扩容,但监控显示负载已超过阈值,为什么?
- 指标采集异常
Metrics API 无法提供正确的指标数据
使用 kubectl get pod 和 kubectl logs 查看 metrics-server 是否正常运行
使用 kubectl top 看是否能获取到数据
使用 kubectl get apiserver 检查 API 状态是否为 True- HPA配置错误
使用 kubectl describe hpa 重点检查 Reference 字段(指向 HPA 的目标资源)是否正确,Metrics 字段的 current(实时指标值)和 target(阈值)是否正确,还有 Conditions 字段能查看到是否能够扩缩容以及获取指标等信息- 资源限制未设置
确保 Pod 模板中有 resources.requests.cpu 定义,使用 kubectl describe pod 或 kubectl get deployment -o yaml 检查资源配置- 冷却周期干扰
HPA 有默认的扩缩容冷却时间,刚发生玩扩缩容后会等待一段时间才会再次执行操作(默认 5 分钟)- 达到副本数限制
HPA 配置的 maxReplicas 可能已经达到,无法继续扩容
- 如何排查K8s集群性能瓶颈?
- 控制平面监控检查
API Server 性能:使用 kubectl top pods -n kube-system 查看 API Server Pod 的资源使用情况
etcd 健康情况:执行 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key endpoint health 检查状态,etcd 性能问题通常与磁盘 I/O 延迟高或存储空间不足有关,需确保使用高性能 SSD 并监控磁盘指标- 节点资源分析
资源利用率:使用 kubectl top nodes 命令快速查看所有节点的 CPU 和内存使用概况,对于疑似瓶颈的节点,使用 kubectl describe node 命令查看详细资源分配情况,关注 Allocatable(可分配资源)和 Allocated(已分配资源)部分,判断是否因资源不足导致 Pod 无法调度
深入系统指标:通过 Node Exporter 和 Prometheus 监控节点的详细指标,如 node_cpu_seconds_total(CPU 使用)、node_memory_MemAvailable_bytes(可用内存)、node_disk_io_time_seconds_total(磁盘 I/O 时间)- Pod与容器深入排查
Pod 状态与事件:对于异常 Pod(如 Pending、CrashLoopBackOff),使用 kubectl describe pod 查看 Events 部分,这些事件通常可以直接指出问题根源,如镜像拉取失败、资源不足、调度失败等 ;使用 kubectl logs {pod-name} --previous 查看容器上次崩溃的日志,对于诊断 CrashLoopBackOff 非常有用
资源限制与 OOKM:在 kubectl describe pod 的输出中关注容器是否被标记为 OOMKillerd(Exit Code 137),这表示容器内存不足,确保为容器设置合理的 resources.requests 和 resources.limits,尤其是内存限制
CPU 限流(Throttling):通过 Prometheus 查询容器 CPU 使用情况,如果容器频繁达到 CPU 限制,会导致应用性能下降,需要考虑调整 CPU limit 或优化应用代码- 网络与存储性能诊断
网络性能:使用 ping 或 mtr 测试 Pod 之间或节点之间的网络延迟和丢包率,监控 CoreDNS 相关指标,DNS 解析延迟高会直接影响应用响应,检查 CNI 插件(如 Calicao、Flannel)的状态和配置
存储性能:很多慢请求的根源是磁盘 I/O 瓶颈,通过 Node Exporter 的 node_disk_io_time_seconds_total 等指标监控磁盘 I/O 使用率,对于使用网络存储(如 NFS、Ceph)的 PVC,需检查存储后端的网络带宽和延迟
第九篇:面试思维与答题策略
定位: 总结答题套路与现场思考框架
内容方向:
- 如何"讲出深度":从使用 → 原理 → 场景 → 优化
- 面试常见陷阱与误区
- 简历中如何体现 K8s 项目经验
- 技术面到 HR 面的衔接建议
总结
先更新到这里,后续会将剩下的内容补充完整
如果这篇文章对你有帮助,欢迎点赞关注支持一下~