Kubernetes面试核心考点解析:从容器到Pod调度与集群排错
2026/9/16 3:53:15 网站建设 项目流程

前两年面试我还总听人抱怨:“K8s这东西太重了,面试用得着考这么细吗?”

今年再听到的版本已经变成了:“k8s面试题网上找了十几份,怎么每份都像在背八股文,考完自己心里还是没底。”这个转变其实很正常——容器化已经是很多团队的默认部署方式,Docker和Kubernetes不再是“加分项”,而是“基础项”,面试自然就越问越深、越问越偏实战。

我自己既做过候选人,也坐在面试官对面问过不少人。一个比较明显的感觉是:K8s面试的考察重点已经从“知不知道概念”转向了“能不能解释清为什么这么设计、出问题怎么排查”。比如很多人都知道Pod是K8s的最小调度单元,但一问“为什么不是容器直接调度”,立刻卡住。这类问题靠死记硬背没法答好,得真正理解K8s的设计思路。

这篇文章我把这些年面试和被面试过程中遇到的高频题目做了下整理,按容器基础、Pod与调度、网络与服务发现、存储与配置、高可用与排错几个维度拆开讲。不是为了让你背答案,而是帮你梳理清楚每类问题背后的核心逻辑和答题框架,顺带把我的排查经验和踩坑经历也放进去。

1. 面试官到底在考什么:K8s面试的层级划分与出题逻辑

先说个规律:面试官的题目看似随机,其实背后有比较清晰的层级逻辑。理解这个逻辑,比盲目刷题重要得多。

1.1 基础概念层:考察知识面的广度

这个层面的题主要是筛掉完全没接触过的候选人。常见问题包括:“Docker和虚拟机有什么区别”“镜像和容器有什么关系”“Pod和Deployment有什么区别”“Service有什么用”等。

这一层题目特点是直来直去,答案基本是固定的。但它真正的考察目的不是看你背得多熟,而是看你能不能用简洁清晰的语言把概念讲明白。我见过不少候选人,简历上写着“熟悉Kubernetes”,但要他说清楚镜像和容器的区别,支吾半天说不利索。这种情况在面试官眼里很减分,因为概念说不清楚往往意味着实际动手也够呛。

我的建议是:基础概念题别只背定义,尝试用“一句话解释 + 一个类比 + 一个实际场景”的结构来组织答案。比如“镜像和容器的区别”可以这么说:“镜像是一个只读的模板,容器是镜像运行时的实例,就像程序和进程的关系一样。我经常用docker run启动多个容器,它们共享同一个镜像,但各自有独立的文件系统和进程空间。”

1.2 原理机制层:考察对K8s设计思想的理解

这一层是区分“背过”和“理解”的关键。典型问题如:“为什么K8s不直接调度容器而是用Pod”“kube-proxy的iptables和IPVS模式有什么区别”“etcd在K8s里扮演什么角色”“Pod的探针有哪些,分别适用什么场景”。

这类题目没有标准答案,面试官想听的是你的推理过程。比如问“为什么用Pod”,最好的回答方式是先讲Pod的设计目的——一组需要共享网络和存储的容器被封装在一起,然后举一个实际场景,比如sidecar模式和日志收集容器为什么要和业务容器放在同一个Pod里。

我之前辅导过一个小伙伴,他说自己面试时被问到“配置探针的时候initialDelaySeconds一般设置多少”,直接懵了。后来我告诉他,这类题看似考参数,实际上考的是你有没有真正部署过有状态服务——initialDelaySeconds要根据应用启动时间来判断,而不是网上随便抄一个“30”。

1.3 实操排错层:考察真实运维能力

这是目前面试比重逐渐变大的一个层级。K8s运维场景中经常需要面对的问题,例如Pod一直Pending、镜像拉取失败、Service无法访问、节点处于NotReady状态等,都是面试官爱问的。

答好这类题的关键是要有清晰的排查链路,而不是上来就想“是不是网络问题”。以Pod卡在Pending为例,正确顺序是:先看Event描述——用kubectl describe pod命令查看具体的调度失败原因,可能是资源不足、节点亲和性限制或存储卷挂载失败,然后针对具体原因逐步排查,是节点资源不足就检查节点可用资源,是污点无法容忍就检查节点污点配置,最后再考虑分配或扩容等解决方案。

我在实际排查中遇到过很多次“Pod一直ContainerCreating”的情况,后来养成了习惯——先kubectl describe pod,再看kubelet日志,最后看容器运行时日志。这个顺序基本能覆盖大部分问题。

2. 容器与镜像篇:Docker基础题的高频考点与答题套路

容器是K8s的基石,面试官通常会先从Docker相关的问题开始热身,同时也是为了考察你到底是在K8s上层敲命令,还是真对容器运行时有所理解。这一层问得深了,很容易拉开差距。

2.1 Docker与虚拟机:面试官最爱的“一题三连问”

“Docker和虚拟机有什么区别?”这道题几乎逢面必问,但很多人答得流于表面——说Docker更轻量、启动更快、资源占用更少。这些是结果,不是原因。

我一般建议从三个层面回答:

  • 隔离级别不同:虚拟机通过Hypervisor虚拟化硬件,每个VM有自己的完整操作系统,硬件级隔离;容器共享宿主机内核,通过Namespace做资源隔离,通过Cgroup做资源限制,是进程级隔离。
  • 启动速度与资源密度不同:虚拟机启动要引导整个OS,秒级到分钟级;容器启动本质上是启动一个进程,毫秒级到秒级。同样一台机器,跑虚拟机可能只能撑几十个,但容器可以跑几百个。
  • 安全边界不同:虚拟机隔离更彻底,一个VM被攻破不容易直接影响宿主机;容器共享内核,一旦内核漏洞被利用,逃逸风险相对更高。

答完之后,有经验的面试官通常会追问:“那你觉得什么场景下适合用虚拟机,什么场景适合用容器?”这个问题才真正考验认知。我一般会答:如果追求强隔离、需要运行不同内核版本或操作系统、有合规要求,虚拟机更合适;如果追求部署密度、弹性伸缩、CI/CD流水线效率,容器更合适。很多团队实际是两者混合使用,比如在虚拟机里跑K8s集群,Pod再跑在容器里。

2.2 镜像分层与Dockerfile:考的是对OCI规范的底层理解

“Docker镜像为什么可以分层?”这个问题也常见。核心要答出来:**镜像是由多个只读层叠加组成的,每一层对应Dockerfile中的一条指令,层与层之间有依赖关系,构建时会复用已有的缓存层。**容器运行的时候,在镜像层之上加一个可写层,叫容器层。

这个设计带来的两个直接好处是:镜像可以复用和增量传输,以及多个容器可以从同一镜像启动但各自拥有独立可写层。这也是为什么Docker Hub上拉镜像时,已经存在的层会显示为“Already exists”。

关于Dockerfile,面试官经常让候选人说说“你写Dockerfile时有哪些优化技巧”。这里有几个高频点:

  • 尽量减少层数:每条RUN指令会新增一层,多个RUN尽量用&&合并,但别为了合并而牺牲缓存命中率。
  • 利用构建缓存:把不常变的依赖安装放在前面,把经常变的源码复制放在后面,这样可以最大化利用缓存层。
  • 使用.dockerignore:避免把node_modules.git等不必要文件打进构建上下文,既加快传输,又减少镜像体积。
  • 多阶段构建:例如Golang应用先在golang:1.20镜像里编译,再把二进制拷贝到alpine镜像里运行,最终镜像可以控制在几十MB。
  • 注意基础镜像选择alpine体积小但部分C库兼容有问题,slim版本是另一个常用选择。

2.3 容器生命周期和信号处理:进程模型才是真正的分水岭

很多面试官会在这一层设置一个“陷阱题”,问你“容器里PID 1是什么进程?为什么重要?”如果你没踩过这个坑,很容易答不出来。

常规Docker命令未特殊处理时,直接运行一个应用,应用本身就是容器里的PID 1。PID 1和普通进程不同,它负责处理孤儿进程的收养,还会接收系统发给容器的信号,比如SIGTERM。如果应用没有正确捕获和处理SIGTERM,那么你执行docker stop时可能等很久(默认等待10秒,之后直接SIGKILL),甚至出现容器无法优雅退出的情况。

实操中我建议养成几个习惯:用tini或用--init参数作为PID 1来托管信号,Dockerfile里显式设置STOPSIGNAL,脚本启动类应用时用exec方式而不是开一个子进程。这些细节K8s的terminationGracePeriodSeconds配置也有关联——Pod删除时,kubelet向容器发送SIGTERM,如果应用不响应或处理时间太长,最终会被强制杀掉,导致请求中断。

我自己的经验是,很多人写完容器应用只测了“能启动”,没测“能不能优雅退出”。有一次我把一个Java服务容器化之后,明明代码里有addShutdownHook,但docker stop还是会等满10秒,最后排查发现是启动脚本的问题——我用了java -jar xx.jar &方式启动,导致JVM变成了子进程,PID 1是脚本,信号根本没传给JVM。改成exec java -jar xx.jar之后,问题就没了。

3. Pod与调度篇:搞懂这几个问题,Pod相关面试题就通了一半

Pod是K8s的世界观里最基本的一个概念,面试题基本都绕不开。这个部分我挑几个最关键的问题展开讲,答好了,调度相关的题目基本就通了一半。

3.1 为什么Pod是最小调度单元而不是容器

这道题看起来很基础,但我几乎每次面试都会问。很多人答“因为K8s设计如此”,等于没答。

比较好的回答思路是:

  • Pod是一组容器的集合,这些容器共享同一个网络命名空间(共享IP和端口空间)、共享存储卷、共享主机名,可以在本地通过localhost互相通信。
  • 有些场景天然需要多个容器协同工作,比如边车模式——日志收集容器在Pod的另一个容器里读取日志文件,又比如代理容器和业务容器共享网络栈,业务流量先经过代理容器处理。
  • K8s需要以Pod为单位进行统一的资源分配、调度、健康检查和生命周期管理。如果以容器为调度单位,容器之间的相关性就无法表达,调度器也无从下手。

一个比较形象的类比是:Pod就像一栋楼的公用设施,楼里的多个房间共享水电网络和楼道;容器就是房间,各自做自己的事,但依赖Pod提供的公共设施。这样回答基本能把面试官说服。

3.2 探针、重启策略与Pod生命周期

探针是高频考点,主要三种:livenessProbe(存活探针,检测应用是否存活,失败会重启容器)、readinessProbe(就绪探针,检测应用是否准备好接收流量,失败会摘除Endpoint)、startupProbe(启动探针,用于慢启动应用,保护livenessProbe不被误杀)。

面试官常挖的一个细节是:“livenessProbe失败时What happens?”很多人会马上回答“容器会被重启”,但再追问“是谁执行的重启,重启的是Pod还是容器”,就有人答错了。正确的链路是:kubelet通过容器运行时执行探测,连续失败超过failureThreshold次后,kubelet会根据restartPolicy决定是否重启容器——注意K8s重启的对象是容器而非Pod,同一个Pod内的其他容器不受影响。

实操中同样遇到过不少坑:探针配置得太激进(如periodSeconds设置为1秒),导致宿主机负载升高,应用被频繁误杀;又或者在K8s 1.16版本之前没有startupProbe,慢启动应用必须把initialDelaySeconds调大;还有一次是readinessProbe里配置了依赖数据库的接口,导致数据库抖动时整个应用实例被摘除,流量全部打到另一台机器上——这就是探针路径设计不合理带来的连锁故障。

这里给几条实战建议:

  • 存活探针不要依赖外部服务,探针本身应只检查应用自身存活状态。
  • 就绪探针可以依赖关键依赖项的检查,但建议超时和失败阈值都设宽松些,避免依赖抖动导致大规模摘除。
  • 慢启动应用优先使用startupProbe,而不是无限调大initialDelaySeconds

3.3 从调度器视角理解节点亲和性、污点与容忍

调度相关的高频题基本集中在“如何把Pod调度到指定节点”这个问题上。一般来说有三种方式:nodeSelector、节点亲和性(nodeAffinity)、污点和容忍(tainttoleration),此外还有nodeName直接指定节点。

我经常问的一个题目是:“nodeSelector和nodeAffinity有什么区别?”答得好的候选人会说:nodeSelector是一个简单的精确匹配,只能根据标签的key和value做等值匹配;nodeAffinity则表达能力更强,支持InNotInExistsGtLt等操作符,还区分requiredDuringSchedulingIgnoredDuringExecution(硬性要求)和preferredDuringSchedulingIgnoredDuringExecution(软性偏好)。

污点和容忍的逻辑则完全不同。污点是打在节点上的“排斥标签”,默认情况下Pod不会调度到带污点的节点上,只有Pod声明了对应的容忍(toleration)才可以被调度上去。比如控制面节点通常有node-role.kubernetes.io/control-plane:NoSchedule污点,所以你自定义的Pod不会跑到控制面上去。同时污点还有NoExecute效果——不仅影响新Pod的调度,还会驱逐节点上已运行的Pod。

实操中常用的场景是:给专用GPU节点打污点,只有声明了容忍的GPU任务Pod能调度上去。再比如给网络有特殊要求的节点打污点,防止普通业务Pod占用。这套逻辑答清楚了,说明你对调度器的约束模型有系统理解。

3.4 控制器大观:Deployment/StatefulSet/DaemonSet怎么选

控制器类问题在面试中基本都是送分题,但也是很多人说不利索的题。你需要把每个控制器的核心职责和应用场景讲清楚:

  • Deployment:无状态应用。管理的Pod可替换、可水平扩展,支持滚动更新和回滚。Pod名称带随机后缀,任意一个挂了,副本控制器都会重新拉起一个新的。
  • StatefulSet:有状态应用。Pod有稳定且唯一的网络标识(如pod-0pod-1),有稳定的持久化存储,有顺序的部署、扩容、升级和删除行为。常用于数据库、ZooKeeper、Kafka等。
  • DaemonSet:每个匹配的节点上运行一个Pod。典型场景包括日志收集(Fluentd)、监控采集(Prometheus Node Exporter)、网络插件(Calico)等。
  • Job/CronJob:执行一次性任务或定时任务。

面试官在这里通常追加一问:“Deployment的滚动更新策略是怎么实现的?”这就要提到maxUnavailablemaxSurge这两个参数。简单说,滚动更新通过ReplicaSet逐渐增加新版本Pod数量、减少旧版本Pod数量来完成。maxUnavailable决定更新过程中允许最多有多少个Pod不可用,maxSurge决定最多允许超出期望副本数多少个Pod。理解这两个参数,你才能解释“为什么更新过程中服务不中断”。

4. 网络与服务发现篇:Service、Ingress和CNI的底层逻辑

网络是K8s里最抽象、也最容易把候选人问倒的部分,因为平时直接用kubectl expose创建Service很容易,但内部数据链路是什么样的,很多人没有细细捋过。

4.1 ClusterIP、kube-proxy与iptables/IPVS工作链路

面试官很爱问“Service的ClusterIP是怎么生效的”。回答这个问题,要把组件串联起来:

  • Service是一个API对象,创建后会被写入etcd,同时API Server会为它分配一个ClusterIP(虚拟IP)。
  • kube-proxy监听Service和Endpoints(或EndpointSlice)的变化,在节点上生成对应的负载均衡规则。
  • 默认模式是iptables,通过NAT规则把发往ClusterIP的流量转发到后端的Pod IP;IPVS模式则是利用内核的IPVS模块做负载均衡,支持更丰富的调度算法(如rr、lc、sh),在Service数量大的时候性能更好。

一个值得展开的细节是:**ClusterIP是虚拟的,它不绑定任何物理网卡,真正发起转发的是节点上的kube-proxy规则。**所以我们常说ClusterIP只能在集群内部访问,因为它本质上是节点上的DNAT规则,外部流量不经过这套规则。

我还见过一个挺隐蔽的面试追问:“Service创建了,但Pod没有就绪,curl ClusterIP会怎样?”很多人会答“超时”。其实如果是只定义了selector但Pod没就绪,ClusterIP会存在,但iptables规则里没有后端,流量会直接DROP——表现就是请求卡住直到超时,而不是立即失败。这个细节说明了对Endpoint更新机制的理解深度。

4.2 Service、Ingress、DNS:服务发现的完整路径

服务发现是面试常考的一个链路题。一般我会问:“一个前端Pod要访问后端Service,Pod里解析到的域名是什么?”

完整链路是:Pod内DNS解析使用CoreDNS,Pod中配置的resolv.conf指向集群的DNS服务地址。当你访问backend.default.svc.cluster.local时,CoreDNS解析出ClusterIP,然后流量幸运到kube-proxy规则,被转发到后端的Pod IP。

这里面还有两个容易忽略的细节:

  • Service的端口名也会被解析成DNS SRV记录,可用于服务间按协议查找。
  • Headless Service(clusterIP: None)不会创建ClusterIP,DNS会直接返回后端Pod的IP列表,适合需要客户端自己做负载均衡的场景,比如StatefulSet集群内的节点间通信。

至于Ingress,它工作在七层,负责HTTP/HTTPS路由。Ingress Controller(比如Nginx Ingress、Traefik)才真正干活的组件,Ingress只是声明路由规则。很多人在这里犯糊涂,把Ingress和Ingress Controller混为一谈。

4.3 CNI网络模型:每个Pod都有独立IP是怎么做到的

面试官如果问“Pod是怎么拿到IP的”,就是在考察CNI。K8s本身不实现网络,它通过CNI接口调用网络插件(Calico、Flannel、Cilium等)。

Pod网络的核心要求是:每个Pod都拥有一个集群内可路由的唯一IP,Pod之间可以不通过NAT直接通信。为满足这个模型,常见实现:

  • Overlay网络:如Flannel的VXLAN模式,Pod流量被封装在UDP包里传输,配置简单但性能略有损耗。
  • BGP路由方案:如Calico的BGP模式,每个节点作为路由器,通过BGP协议扩散Pod网段路由,性能高,但底层网络需要支持BGP路由传播。
  • eBPF方案:如Cilium,用内核eBPF技术实现网络策略和转发,性能和可观测性都更好,是目前比较推荐的新方向。

这一节在面试时不用讲得太深,把“CNI是接口、插件是实现、每种方案各有取舍”这个逻辑讲清楚就够了。如果面试官继续追问“你在生产环境选型怎么选”,可以从团队技术栈、网络策略需求、是否用ServiceMesh、性能要求几个维度去拆。

5. 存储、配置与安全篇:容易被问倒但必须答上的基础知识

存储和安全这块是很多人复习时的盲区,觉得“反正我天天用emptyDir,PV/PVC用得少”。但一旦被问起来,答不上又显得项目经验不够扎实。

5.1 PV/PVC/StorageClass:从静态供给到动态供给

“PV和PVC的区别是什么?”是这类的必问题。

简短版答案是:PV是集群级别的存储资源,由管理员预先创建或由StorageClass动态创建;PVC是用户申请存储资源的请求,声明需要的容量和访问模式;Pod通过PVC引用存储,PVC绑定到满足条件的PV。

一般我会建议考生再补充一下生命周期与绑定逻辑:PVC和PV通过storageClassNameaccessModes、容量等条件匹配绑定。如果没有符合的PV,PVC会一直处于Pending状态,K8s有一个叫WaitForFirstConsumer的延迟绑定机制——可以先创建PVC,等Pod调度到某个节点后,再根据该节点的可用区动态创建卷,这对云环境比较友好。

访问模式也是考点:ReadWriteOnce(RWO)允许单节点读写、ReadOnlyMany(ROX)允许多节点只读、ReadWriteMany(RWX)允许多节点读写。不同存储支持的模式不同,比如云盘一般只支持RWO,NFS支持RWX。用错访问模式会出现Pod调度成功但挂载失败的情况。

这类问题最能打开话匣子的展开方向,是我之前帮一个团队排查过的一个问题:所有Pod都卡在ContainerCreating,kubectl describe显示failed to mount volume,排查半天发现是云盘的diskId写错了,挂载点指向了一个不存在的云盘。所以碰到挂载失败且网络、存储插件都没问题时,先检查存储资源的ID和可用区。

5.2 ConfigMap与Secret:配置注入的边界与权限问题

“ConfigMap和Secret有什么区别?”这个问题看起来简单,但答案里有几个关键点:

  • 存储形式不同:ConfigMap明文存储,适合非敏感配置;Secret用Base64编码存储,但对敏感数据来说Base64不算加密,只是编码,所以生产环境建议开启etcd加密或使用外部密钥管理方案(如Vault、KMS)。
  • 使用方式相同:两者都能通过环境变量注入或挂载为文件。
  • 更新机制不同:通过环境变量方式注入的配置,Pod运行期间不会动态更新;通过volume方式注入的配置,K8s会定期同步到挂载卷,应用需要监听文件变化才能生效。

我补充一个踩坑经历:之前我用ConfigMap挂载Nginx配置,修改ConfigMap后发现Nginx容器里文件已经更新了,但Nginx进程并没有重新加载配置,最后还得靠reload容器进程或重启Pod来实现。所以面试时可以提一句“如果应用不支持动态加载配置,修改ConfigMap后需要滚动重启Pod”,这比单纯背概念更有说服力。

5.3 RBAC与服务账户:最小权限原则在K8s里的落地

安全类的常见题目是“RBAC是什么,如何给一个Pod配置只读权限”。答案是K8s通过RBAC做权限控制,核心有Role/ClusterRole、RoleBinding/ClusterRoleBinding、ServiceAccount三个概念。

以“Pod访问K8s API”为例,流程是:

  • 创建ServiceAccount;
  • 创建Role或ClusterRole,声明权限规则(比如对Pod资源只读);
  • 通过RoleBinding将Role绑定到ServiceAccount;
  • 在Pod的spec中设置serviceAccountName

提一个值得记住的话题:默认情况下,Pod会挂载一个ServiceAccount的token文件,API请求会自动带上身份信息。这个token实际上是JWT格式,默认有效期比较长。现在K8s新版本推荐使用TokenRequest API,提供短时间有效期的token,权限更收敛,更适合外部系统对接。

“最小权限原则”不是一句空话,在K8s里的落地就是——能不给cluster-admin就不给,能用一个独立ServiceAccount就别用default。面试时如果能主动提到自己曾用RBAC收紧过线上权限、回收过长期token,会是一个很好的加分细节。

6. 集群高可用与排错篇:面试官拿来区分“会用”和“会养”的分水岭

前几年面试,能把Service和Deployment说清楚就可以过关了。现在不行了,面试官更倾向于通过高可用和排错类问题,看你有没有“养过”集群的经验。这类题目很开放,答得好不好,全看平时积累。

6.1 etcd与控制面组件:面试官深挖高可用时在挖什么

“K8s集群的etcd挂了会怎样?”这是高可用题里我能想到的最经典问题之一。

etcd存储了集群全部的期望状态,比如Pod、Service、ConfigMap等对象数据。如果etcd挂了,kube-apiserver无法读写数据,整个集群的管理平面就瘫痪了——但注意,已经运行中的Pod和kubelet不受影响,它们还在照常跑。这就是“控制面和数据面分离”设计的好处。

真正的高可用问题是:etcd的raft协议怎么工作?这里要答出来etcd集群至少需要3个节点才能容错1个节点,5个节点能容错2个,数据会通过raft日志在节点间复制。如果集群节点间网络分区,少数派节点会失去领导人选举能力,表现为只能读不能写。

控制面组件的职责也要能说清楚:kube-apiserver是无状态网关,负责提供API、鉴权、准入控制;kube-scheduler负责把Pod调度到合适的节点;kube-controller-manager运行各种controller(节点控制器、副本控制器等),负责把当前状态调整为目标状态。一个常见面试题是“kube-apiserver挂了,kubelet还会正常工作吗”,答案分两层:kubelet会继续维护本节点的Pod运行,但如果Pod需要重新调度或创建新Pod,这部分逻辑依赖apiserver和scheduler,就会出不来。

6.2 一个Pod卡在Pending,排查链路是什么

这类排错题答案没有唯一标准,但基本要符合以下排查链路:

  1. 看事件kubectl describe pod <pod-name>,重点看Events列表。
  2. 看调度器日志:如果事件提示0/3 nodes available,原因可能是资源不足、节点有污点、nodeSelector不匹配等。
  3. 看节点资源kubectl top nodes,确认节点资源是否充足。
  4. 看StorageClass和PVC:如果事件里面提到waiting for a volume to be created,去排查StorageClass的Provisioner是否正常工作。
  5. 如果事件里没有任何内容:考虑是不是需要检查调度器本身,比如自定义调度器或者调度器Pod挂了。

我实际遇到过最“隐蔽”的一次Pending问题,是节点上有GPU资源,但Pod没声明申请GPU,调度器认为没有任何节点满足“包含GPU资源”的条件,于是一直Pending。最后通过看事件的FailedScheduling消息才定位到是资源名写错了——nvidia.com/gpu写成了nvidia/gpu。这些小细节面试时不一定问到,但实际操作中真的会碰见。

6.3 资源请求/限制与HPA:为什么节点会异常

“Pod内存超限会怎样”是考查资源机制的一个好问题。这个问题我觉得可以说一下K8s里两类资源超限的不同表现:

  • CPU是可压缩资源:超限时会产生CPU Throttling,Pod还在运行,但变慢了,一般不会被杀掉。
  • 内存是不可压缩资源:超限时,容器内的进程如果继续申请内存,内核OOM Killer会根据oom_score杀掉进程,进而导致容器重启。

面试官继续抠细节时可以问“为什么有时候还没超limit也会被杀”,这实际上和节点整体内存有关。如果节点本身可用内存偏低,内核OS的cgroup OOM和系统OOM的边界会变得比较复杂,需要结合eviction机制来理解——kubelet为了稳住节点,会设置--eviction-hard,当节点MemoryPressure超过阈值时,开始驱逐Pod,而不是等容器自己超限。

HPA(HorizontalPodAutoscaler)也算高频题,重点答清楚:HPA通过Metrics API获取Pod资源指标(CPU、内存或自定义指标),根据当前指标和期望值计算需要的副本数,有一个--horizontal-pod-autoscaler-sync-period控制同步周期。扩展时以Pod数量为粒度,且受minReplicasmaxReplicas限制。要提一句:HPA的实现依赖metrics-server,没有安装metrics-server的话,CPU指标采集不到,HPA就没法正常工作。

7. 备战策略:二八法则与复习路线建议

内容聊到这里,题型的脉络基本就清楚了。最后一年总结下来,我建议按“二八法则”来准备K8s面试题——花80%精力掌握20%的高频考点,远比我见过很多人把时间耗在背诵冷门参数上有效得多。

对于准备时间有限的求职者,我的建议是这样的:

  • 先动手搭一个集群:别只看文档,至少要在自己电脑上用kind或minikube完整跑一遍“部署应用→创建Service→配置探针→滚动更新→回滚”的流程。有了亲手操作的经验,面试中很多概念题会自动串起来。
  • 把kubectl常用命令背熟,特别是describelogsexecgetapplytop这些排错命令。面试时如果能脱口而出排查命令,说服力会好很多,因为k8s是命令行工具的世界,大多数工作都在kubectl上面。
  • 深挖两三个真实场景:比如你曾经用StatefulSet部署过MySQL、用Ingress配置过HTTPS、用RBAC收过权限——挑两三个往深了准备,把涉及的技术细节都搞清楚,面试时每个都能讲5分钟,比蜻蜓点水地重复十个项目强。
  • 可以适当看看官方文档:Kubernetes官方文档概念部分写得非常清楚,特别是Pod Lifecycle、Service、RBAC这三块,比很多博客都靠谱。遇到有争议的细节,以官方文档为准。
  • 不要只啃面试题集合:面试题集合适合查漏补缺,不适合当教材。我见过太多人背诵了“200道真题”,结果面试官稍微换个角度,就陷入背过的题没听过、没背过的题答不上来的困境。

最后再分享一个我在准备面试时用到的比较有效的做法——把每个考点都写成“自己讲给自己听”的稿子,然后模拟面试官追问。比如写完“为什么用Pod”,就追问一句“Pod内多个容器如何共享网络”,再追问“那如果有两个容器都想监听80端口怎么办”——一个接一个地问下去,直到答不上来,然后去查资料、验证、补充。这个过程很枯燥,但坚持一个月,面试时能明显感到自己“有底气了”。

K8s的知识体系确实庞大,但面试考来考去,万变不离其宗——最终都在考察你是否理解这套系统“为什么这么设计”。把每个概念背后的动机和取舍想明白,比记住再多细节都值钱。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询