1. 第一关:Pod为什么是K8s所有面试题绕不开的起点
去年我集中准备过一段时间Kubernetes面试题,发现一个特别普遍的现象:很多人在“Pod是什么”这道题上直接翻车。明明也背过“Pod是K8s的最小调度单位,是一组容器的集合”,但面试官一追问“为什么不能直接用容器作为调度单位”“Pod里的容器到底共享什么”,立刻就卡壳。
这道题之所以被当成第一道送分题,是因为它考察的不是记忆力,而是你对容器协作机制的理解程度。面试官通常想要听到的,不是教科书式定义,而是你把“共享网络命名空间、共享存储卷、同生共死”这几个底层动因串起来讲清楚。这篇文章我不打算按网上常见的“面试题大全”罗列几百个问题和答案,而是把高频问题拆成几条主线,附上我踩过的坑和答题思路。目标是让正准备K8s相关岗位(开发、运维、SRE、云原生工程师)的朋友,拿到一套可以直接复用的思路。
1.1 面试官揪着Pod不放,到底在考什么
很多人背的答案是“Pod是最小调度单位”。这句话本身没错,但面试官想听的是“为什么在容器之上还要包一层Pod”。
一个容器本质上对应一个Linux进程。线上业务很少是单个进程能搞定的,你的主业务容器之外,通常还有日志采集、监控指标导出、本地缓存代理这类Sidecar容器。如果直接调度容器,这些逻辑上应该一起部署、一起伸缩、一起重启的进程,就可能被调度到不同节点,网络栈对不上、存储卷挂不见、生命周期也不一致,运维成本会高到不可接受。
Pod的本质就是把这一组进程打包成一个原子单位。它保证了三个点:一起调度、共享资源、同生命周期。在K8s中,最小调度单位不是单个容器,而是Pod这个“进程组”。这也是为什么Deployment的replicas说“几个Pod”而不是“几个容器”。
我建议面试回答时直接说:“Pod是K8s创建、调度、销毁的最小原子单位,Pod内的容器共享同一个网络命名空间和存储卷,它们被当作同一个整体来管理。”然后补一句“所以同一个Pod里的容器天然可以通过localhost通信,也可以同时读写同一个Volume”。这两句话比干巴巴的“是一组容器”有力得多。
1.2 Pod内共享与隔离的边界
这道题经常以追问的形式出现:“同一个Pod里的两个容器,网络层面是什么关系?文件系统呢?进程呢?它们能监听同一个端口吗?”
先说共享的部分:
- 网络命名空间:Pod内所有容器共享同一个IP、同一个端口空间。所以容器之间直接用localhost加端口就能访问,不需要走Service。
- 存储卷:同一个Pod的容器可以挂载同一个Volume,实现文件级共享。
- IPC命名空间:默认也共享,容器之间可以用System V IPC或POSIX消息队列通信。
- pause容器的作用就是“公共走廊”:K8s会先启动一个pause容器用于持有这些共享命名空间,业务容器再加入。业务容器崩溃重启时,pause容器不动,所以Pod的IP不会变。
隔离的部分:
- 文件系统:每个容器有独立的rootfs,互相看不到对方的文件,除非显式挂载同一个Volume。
- 进程视图:默认情况下每个容器看到的进程列表是隔离的,PID namespace是否共享取决于容器运行时和RuntimeClass配置,不能一概而谈。
- 资源限制:每个容器的CPU、内存cgroup限制是独立的,所以一个容器把内存吃满,可能不会立刻杀掉同Pod的另一个容器,但整个Pod可能被驱逐。
最容易踩的送命题在这里:一个Pod里的两个容器能不能同时监听同一个端口?答案是不能。它们共享网络栈,端口冲突会直接导致容器启动失败,报“address already in use”。
1.3 生命周期、探针与优雅终止
Pod的状态机是面试高频题:Pending、Running、Succeeded、Failed、Unknown。但比背状态更关键的是理解RestartPolicy(重启策略)和探针(Probe)。
RestartPolicy有Always、OnFailure、Never三种。它只决定Pod内某个容器异常退出后,Kubelet是否在同一个节点上重启该容器;它跟Pod本身是否被重新调度没有关系。很多人把这个概念和Job的重试策略搞混。Job里设置restartPolicy: Never,意味着容器失败后不会再重启这个容器,而是由Job控制器创建新的Pod来完成处理。
探针也是必问题。livenessProbe(存活探针)失败时kubelet会杀掉容器并用RestartPolicy重建;readinessProbe(就绪探针)失败时Pod不会从Service拿到流量,但容器本身继续运行。startupProbe是为启动慢的应用准备的,避免livenessProbe在应用还在初始化时就误杀。
我在实际项目中踩过这个坑:一个应用冷启动需要20多秒,我把它readinessProbe的initialDelaySeconds配成5秒,结果Pod启动后一直被探针打失败,Service后端的端点列表始终为空,服务间歇性不可用。后来把initialDelaySeconds调整到30秒,并加上startupProbe做缓冲,问题才消失。这种经验在面试里提一嘴,比背字段定义有价值得多。
2. 控制器与调度:从“写YAML”到“讲得清原理”
2.1 Deployment与ReplicaSet的关系
“Deployment、ReplicaSet、Pod三者是什么关系”这道题,很多人能说出ReplicaSet负责副本管理,但一到滚动更新的细节就露馅。
正确理解是:ReplicaSet保证某个时间点上指定副本数的Pod存在;Deployment通过管理多个ReplicaSet的版本,实现滚动更新、回滚、扩缩容。Deployment不是直接面向Pod的控制器,而是面向ReplicaSet的控制器。这就解释了为什么滚动更新时,kubectl get rs能看到新旧两个ReplicaSet。
滚动更新有两个核心参数:maxUnavailable和maxSurge。举个例子,副本数4,maxUnavailable=1,maxSurge=1,那么更新过程中最少可用Pod数是4-1=3,最多总Pod数是4+1=5。通过“先建新Pod、确认就绪后再删旧Pod”的方式逐步替换,服务不中断。
这里常有一个追问:滚动更新在什么情况下必然中断?答案是当副本数只有1时,或者Pod模板不支持多副本同时运行时。如果你在设计Deployment时replicas写1,就不要说自己能做到零停机。
加分回答还会提到:滚动更新之前,Pod必须有合理的readinessProbe,否则新Pod还没就绪就被服务发现挂到后端,流量直接打到未就绪的Pod上,表现为部分请求超时。
2.2 StatefulSet和DaemonSet:不要只背“有状态”和“每节点”
StatefulSet的三大特征:稳定网络标识、稳定持久化存储、有序部署/删除。
- 稳定网络标识:Pod名称固定为web-0、web-1,即使被重新调度到别的节点,名称不变,DNS也不变。所以很多依赖主机名的中间件可以用StatefulSet跑。
- 稳定存储:每个Pod对应一个PVC,Pod重建后仍然挂载同一块存储,数据不丢。
- 有序操作:扩容时从web-0开始逐个创建,缩容时从末尾开始逐个删除。
最常被追问的是:“StatefulSet缩容或删除Pod时,PVC会被一起删除吗?”答案是“不会”。PVC是独立资源,StatefulSet不会帮你删除。这是刻意的设计,因为数据比Pod更持久。如果你说“会自动删”,说明没有真正操作过有状态应用。
DaemonSet则关心“每个符合条件的节点上最多且必须运行一个Pod”,常用于日志采集Agent、监控Metrics、网络插件。它和StatefulSet的区别不用死记,记住“节点级组件选DaemonSet,有状态且要求固定标识选StatefulSet”就够了。注意DaemonSet的更新策略有RollingUpdate和OnDelete两种,节点级Agent我通常用OnDelete,因为你不想每次发布都让全集群Agent同时滚动。
2.3 Scheduler两阶段与亲和性/污点
调度器的工作逻辑可以简化成“过滤 + 打分”两步。
过滤阶段(Predicates):把所有不满足条件的节点排除掉。典型条件包括:可用CPU/内存是否满足requests、端口是否冲突、是否有无法容忍的污点、节点是否有匹配的磁盘/存储、Pod的nodeSelector是否匹配。
打分阶段(Priorities):对通过过滤的节点打分,K8s会综合考虑资源剩余量、Pod分布分散度、节点亲和性等因素,选出最高分的节点。默认调度器内置了很多打分插件,比如LeastRequestedPriority、BalancedResourceAllocation等。你不需要全部背下来,但要能说出来“默认调度会优先选资源剩余更均衡、负载更低的节点”。
再展开讲的话,面试官一定会问亲和性和污点。nodeSelector是最简单的精确匹配;nodeAffinity支持In、NotIn、Exists、Gt、Lt等操作符,表达更灵活;PodAffinity用于把某些Pod尽量调度到一起,反亲和性用于把Pod散开。
污点(Taint)和容忍(Toleration)是另一套机制。给节点打上污点后,不带对应容忍的Pod不会被调度上去。效果有三种:NoSchedule(不调度)、NoExecute(已经在运行的也会被驱逐)、PreferNoSchedule(尽量不调度)。生产环境里给基础组件专属节点加污点,再用Toleration放行特定Pod,是基础设施隔离的常见做法。比如:
kubectl taint node node-2 dedicated=infra:NoSchedule这句话的效果,面试时能讲清楚,再配一句“对应Pod通过toleration放行”,调度题基本就稳了。
3. 集群网络三层:ClusterIP、kube-proxy、Ingress各管一段
3.1 为什么需要Service,以及kube-proxy的三种模式
先说一个常被忽略的动机:Pod IP是不稳定的。Deployment滚动更新、Pod重新调度,IP都会变。如果应用直接拿Pod IP通信,整个集群的调用链会随时断裂。Service的意义就是提供一个稳定的虚拟IP(ClusterIP)和稳定的域名,背后再通过selector动态选择后端Pod。
Service的实现依赖于每个节点上的kube-proxy组件。它有三种工作模式,这道题在面试中的频率非常高:
- userspace模式:最早,数据包先进用户态代理程序,再转发给后端Pod。性能差,现在基本不会用,但适合理解机制。
- iptables模式:利用内核iptables的DNAT规则完成流量转发。性能比userspace好,但规则是链式匹配,集群规模一大、Service一多,规则数量可能上千条,更新耗时长,负载均衡只能随机选规则位实现,不健康。
- ipvs模式:基于内核IPVS哈希表,查找效率高,支持rr、wrr、lc等多种调度算法,规则数量大时性能依然稳定。现在的生产环境基本都选IPVS。
我知道很多面试者在“为什么不用IPVS之外的方案”上答不出深度。可以补一句:IPVS模式本身不具备健康检查能力,它依赖K8s的EndpointSlice来感知后端Pod状态,如果Pod readiness失败,对应后端就会被摘除。这个机制和网络Layer不同,说出来就很加分。
3.2 DNS与服务发现:域名是怎样解析的
K8s集群内部默认集成CoreDNS。每个Service会生成一条DNS记录,格式为<service-name>.<namespace>.svc.cluster.local。
同一个Namespace的Pod,直接访问service-name就能解析;跨Namespace要写成<service-name>.<namespace>.svc.cluster.local。这个细节我在实际排错时救过命:有一次跨Namespace访问不成功,我一开始以为是Service Ip被防火墙拦了,后来才发现应用代码里写的是短域名,压根没带Namespace后缀,CoreDNS当然解析失败。
面试追问经常是:“Pod里解析Service域名,走的是什么链路?”回答是:Pod的/etc/resolv.conf指向CoreDNS的ClusterIP,查询时按search domain依次拼接。如果业务对DNS延时敏感,可以配置NodeLocal DNSCache来缓存本地解析,减少DNS的trap。能讲到这一步,说明你有大规模集群优化的实际经验。
3.3 Ingress与7层路由:和NodePort的区别在哪里
Service ClusterIP只在集群内可达。要从集群外访问,常见三种途径:
- NodePort:在每个节点上开一个端口,把流量转发到Service。范围默认30000-32767,每个Service都要占一个端口,管理起来很费劲。
- LoadBalancer:云厂商的负载均衡器,通常会把流量先打到NodePort,再由Service转发。
- Ingress:七层路由器,按域名和路径做路由。比如
api.example.com/pay/*路由到支付服务,api.example.com/user/*路由到用户服务。Ingress本身只是一个API对象,真正干活的是Ingress Controller,比如nginx-ingress、traefik。
很容易答偏的问题是:“Service能不能终止HTTPS?”答案是不能。Service本质上工作在L4,不解析HTTP内容,也不管TLS。TLS证书的卸载发生在Ingress Controller层,或者应用自己处理。如果你回答“可以”,面试官基本就能判断你只停留在概念表面。
我在调试Ingress时最常用的三件事:kubectl get ingress确认配置,再看Ingress Controller的access log,最后用kubectl port-forward svc/ingress-nginx-controller做本地验证。顺序不要乱,先把问题缩小到“是路由规则写错”还是“后端Pod没就绪”,效率会高很多。
4. 存储、配置与资源控制:最能拉开分差的模块
4.1 PV/PVC/StorageClass:不要说“PV就是磁盘”
面试题里“PV、PVC、StorageClass分别是什么”几乎是必背,但很多人只背了“PV是一种存储资源,PVC是存储请求”。更关键的是三者之间的动态关系。
- PV:由管理员预先创建的存储资源,背后对接实际存储系统,比如NFS、CephRBD、云盘。
- PVC:Pod对存储的“需求单”,需要声明容量大小与访问模式。
- StorageClass:动态供给模板。PVC创建后,如果匹配到对应StorageClass,provisioner会自动创建PV,不需要管理员预置。
AccessMode也是常考项:ReadWriteOnce(单节点读写)、ReadOnlyMany(多节点只读)、ReadWriteMany(多节点读写)。注意很多云盘只支持ReadWriteOnce,多个副本的Pod要共享同一块盘时,只能通过NFS这类网络存储,否则Pod根本调度不开。
回收策略:Retain手动保留并清理,Delete则由K8s自动删除底层卷。很多人在“动态供给”场景里把Delete当成默认选项,结果删PVC把云盘也删了,数据追不回来。所以在重要的数据卷上,我会先改成Retain策略,确认数据备份后再手动清理。
一个加分的追问:“StatefulSet缩容到1,PVC会不会丢?”答案是不会,PVC和底层PV都还保留。如果要彻底清理,需要手动删除PVC、PV,并处理底层存储。能在面试里主动说出这个“删不干净”的坑,说明你真的操作过。
4.2 ConfigMap和Secret:挂成volume和环境变量的区别
配置管理在面试中往往是“软技能”考题。表面问的是差异,实际问的是你有没有处理过配置变更。
- 环境变量方式:Pod创建时把ConfigMap/Secret的内容注入成env。这个值在Pod整个生命周期内是固定的,修改ConfigMap不会影响已运行的Pod,必须重建Pod才生效。
- Volume挂载方式:把ConfigMap/Secret挂载到某个目录,例如
/etc/app/config。Kubelet会通过同步机制更新挂载文件,因此修改ConfigMap后,文件内容会变化,应用如果监听了文件变化就能热加载。 - 但注意:如果用了subPath挂载单个文件,它不会自动更新。subPath相当于把某个文件“快照”进去,ConfigMap后续变更不会影响已挂载文件。
Secret的另一个高频点:Secret不等于加密,它只是base64编码。任何有权限读取Secret的人都可以解码看到明文。面试官问“Secret在etcd里安全吗”,正确回答是:默认不加密,需要通过KMS配置静态加密,或者用外部密钥管理方案加密后再存储。
实际工作中我维护过一个需要每天轮换数据库密码的服务,最初方案是“改Secret后重建Pod”,结果每次轮换都会造成短暂漂移。后来改成把Secret挂载为volume,应用监听目录变化并reload,轮换时完全无感知。这个方案值得在回答“如何热更新配置”时提出来。
4.3 requests/limits与QoS:为什么被OOM的是业务容器
资源管理是实践性很强的话题。requests和limits的区别要讲清楚:
- requests:调度器做资源匹配的依据,相当于“预留座位”。Pod能调度到节点上,前提是节点剩余可分配资源大于所有容器的requests之和。
- limits:运行时限制,相当于“最多吃多少”。超出limits时,CPU会被限流,内存可能会被内核OOM Killer杀掉。
QoS等级有Guaranteed、Burstable、BestEffort三类:
- Guaranteed:所有容器都设置了CPU和内存的requests和limits,且两者相等。
- Burstable:至少有一个容器设置了requests,但不满足Guaranteed。
- BestEffort:所有容器都没有设置requests和limits。
当节点内存紧张时,Kubelet驱逐Pod的大致顺序是BestEffort优先、Burstable次之、Guaranteed最后。OOM Killer的优先级也和QoS相关,会结合容器的OOMScore进一步调整。
所以答案就顺了:业务容器和Sidecar同时面临内存压力时,如果Sidecar的QoS等级不低于业务容器、占用内存又少,那么内核更倾向先杀业务容器来释放更多内存。这就是为什么你经常看到业务容器被OOM Kill,而旁边的Sidecar安然无恙。
设置建议:requests参考应用常驻内存的基线,limits在基线上加30%到50%的缓冲。CPU不要把requests设成0,否则调度器可能会把Pod堆到同一节点,造成CPU争抢。把这些“基于经验的建议”讲出来,面试官就能感觉到你不是纸上谈兵。
5. 排查题:从Pod卡住到节点失联的完整链路
5.1 一个Pod卡在Pending或CrashLoopBackOff,先查什么
现在面试官也越来越爱考排错题,因为这是区分“背题”和“干活”的试金石。我的排错顺序固定是“看现象 → 看描述 → 看日志事件”。
第一步,kubectl get pod <name> -o wide,确认Pod到底在哪个状态。第二步,kubectl describe pod <name>,重点看Events里的Reason和Message。第三步,根据状态分类处理:
- Pending:调度或创建阶段出问题。常见原因包括:节点资源不足、镜像不存在或仓库认证失败、Taint不匹配、PVC无法绑定。看describe里的Events会写得很直白,比如“0/4 nodes are available”“Insufficient memory”“ErrorImagePull”。
- CrashLoopBackOff:容器反复启动又退出。这时候要看exit code和日志:
kubectl logs <pod> -c <container>。常见原因:启动命令路径错误、依赖的数据库或配置中心未就绪、liveness探针配置过短把进程误杀。 - ImagePullBackOff:重点检查镜像tag是否存在、imagePullSecrets是否配置、镜像仓库连通性。
这里有一个额外小技巧:kubectl get events --sort-by='.lastTimestamp'会比describe里的Events更全。集群里其他Pod的事件也可能会干扰判断,所以要结合时间段过滤。
我印象很深的一次排障:一批Pod全部Pending,describe后看到每个节点都没有足够内存,但单看Pod规格又不大。最后检查节点才发现,另一套环境跑了一个任务型批处理Pod,占掉了所有节点的大部分内存。这类“障眼法”问题,如果只看Pod而不看节点,永远定位不了。
5.2 节点NotReady:从kubelet到容器运行时到磁盘压力
面试题“节点NotReady,怎么排查”考察的是控制平面与节点之间的心跳链路。节点会定期通过kubelet上报状态到API Server,如果超过grace period(默认约40秒)没上报,节点会被标记为NotReady或Unknown。
我的排查链路是:
- 看集群侧:
kubectl get node、kubectl describe node <node>,确认Conditions里哪一项是False或Unknown。 - 登录节点查kubelet:
systemctl status kubelet,journalctl -u kubelet -f,看有没有证书过期、API Server连不上、CNI初始化失败等错误。 - 查容器运行时:比如containerd是否正常,
systemctl status containerd、ctr version。很多时候kubelet没死,是它底下的运行时挂了。 - 查磁盘压力:
df -h /var/lib/kubelet、df -i /var/lib/kubelet。磁盘写满或者在inode耗尽时,kubelet会主动把节点置为压力状态。 - 区分范围:单节点NotReady,大概率是节点自身问题;如果多个节点同时NotReady或大量Pod Pending,要优先检查API Server、etcd、网络分区。
有一个容易被忽视的点:如果节点只是偶尔NotReady一下又恢复,不要忽略,它很可能就是磁盘IO毛刺、内存GC停顿或者容器运行时高负载导致的。你需要在node conditions的历史里反复看时间点,找到规律。
5.3 etcd故障:判断集群是否真的“挂了”的关键
etcd是控制平面的数据核心,面试官特别喜欢深挖。它基于Raft协议,写入需要多数派节点确认,所以节点数量取奇数。3节点容忍1个故障,5节点容忍2个故障。如果3节点挂2个,集群就进入只读或无法选举的失败状态。
常见问题:“etcd性能瓶颈在哪?”答案是磁盘IO。Raft的每次写入都需要多数节点持久化日志,磁盘写延迟直接决定请求延时。生产上etcd盘一般用SSD,并且不能和其他高IO负载共用。网络分区也会导致leader频繁切换。
排障命令要能说上来:
ETCDCTL_API=3 etcdctl endpoint health --cluster ETCDCTL_API=3 etcdctl endpoint status --cluster -w table ETCDCTL_API=3 etcdctl snapshot save /backup/snapshot.db备份和恢复是更进阶的追问。定期快照是底线,建议至少配置每日快照,并异地/多副本留存。恢复时通过snapshot restore到一个新目录,再以新member身份加入集群。
还有一个实战细节:不要在etcd里塞大量大对象数据。比如ConfigMap里的超大内容、历史事件等,都会拖慢写入。事件对象默认有过期时间,但如果集群事件暴增,还是会影响etcd健康。控制面稳定,才谈得上集群稳定。
6. 高可用架构与“送命题”:从背题到得分
6.1 高可用集群怎么设计
到了架构题,面试官想看的不是“我安装过k8s”,而是“你对生产环境的控制平面设计有没有完整认知”。
我的回答大概分四层:
- API Server:无状态服务,可以横向扩容。前面配置负载均衡或虚拟IP,多个副本提供统一入口。
kubeadm init里的--control-plane-endpoint参数就是给这个LB入口用的。 - controller-manager和scheduler:主动-备选模式,通过leader选举保证只有一个主实例在工作,其他副本待命。部署时多个副本选举后自动切换。
- etcd:3或5个节点,奇数部署,分布在不同可用区。3节点可容忍1个故障,5节点可容忍2个。etcd必须做快照备份,最好独立部署不使用混合节点。
- 工作节点:横跨多个可用区,打上zone相关标签,让调度器可以跨区分布Pod;关键业务的Deployment设置反亲和性,避免同类副本堆在同一台物理机。
这里经常有人被一句话问倒:“那你的API Server自己挂了怎么办?”答案不是“它有副本所以没事”,而是要强调它前面的LB必须有探活机制,能把失败节点摘掉,同时证书与kubeconfig要妥善管理。能讲到这一层,面试官就会觉得你经历过生产架构设计。
6.2 无状态应用迁移上K8s的改造路径
“把一个原来跑在虚拟机上的Spring Boot应用迁到K8s,你会怎么做?”这道题没有标准答案,但能测出你做过多少真实迁移。
我会按这种顺序回答:
- 先把配置文件外部化:数据库地址、Redis地址、各种token,全部挪到ConfigMap/Secret,镜像里不留环境差异。
- 规范日志:应用日志打到stdout,由日志Agent统一采集,不要依赖本地文件路径,否则Pod重建就丢。
- 加探针:至少加readinessProbe,让Pod就绪前不接流量;启动慢的应用再加startupProbe。
- 设计滚动更新:副本数至少2,合理设置maxUnavailable和maxSurge,先灰度验证一个实例的日志和指标,再全量发布。
- 接入Service/Ingress:避免客户端直接解析Pod IP,用Service和DNS做服务发现。
- 数据库这类有状态组件,初期不着急搬进集群。用云托管数据库或者NFS等外部存储先顶着,等集群稳定了再考虑StatefulSet。
评分点在于你有没有想到“启动预热”“优雅关闭”“会话保持”这些细节。如果能主动提到preStop脚本里先摘流量、再等存量请求处理完,面试分一般不会低。
6.3 几个常见送命题和应对框架
最后一类,是那些“看着很简单,答不好就扣分”的送命题。我记录几个印象深刻的:
送命题一:“Pod一直Terminating,怎么删都删不掉,怎么办?”
不要上来就kubectl delete pod --force --grace-period=0。这会绕过优雅终止流程,可能留下孤儿卷和iptables残留规则。正确做法是:
- 先
kubectl describe pod看是否卡在Finalizer; - 如果是Finalizer导致,可以先用patch移除指定finalizer;
- 如果Pod挂在Terminating超过几分钟,检查kubelet状态、容器运行时状态、还有挂载卷是否被其他节点占用。
送命题二:“Pod已经Running,但一直NotReady,怎么排查?”
先查readinessProbe的配置,大概率是探针本身写错了。可以用kubectl exec进入Pod,手动curl一下探针地址,判断是“应用没起来”还是“探针URL/端口写错”。很多情况是探针路径从/health变成/actuator/health,Pod就一直被打标签为未就绪。
送命题三:“新版本Pod已经Running,但流量还是到老Pod,是什么原因?”
先看Service的selector是否匹配新Pod的label,再看新Pod的readinessProbe是否已通过,最后看NetworkPolicy或Endpoints里的实际列表。一个常见的低级错误是:Deployment里的label改成v2了,但Service的selector还写死app: appv1,结果流量全在老Pod上。
回答这类问题,我习惯按“现象 → 假设 → 验证 → 处理 → 预防”五步走。面试官要的不是背答案,而是看你的排错思维是否系统化。
7. 我准备Kubernetes面试题的复盘经验
最后分享一点个人体会。
第一,不要把时间花在背“API对象的全部字段”上,而是把核心链路串起来:Pod → Deployment → ReplicaSet → Service → Ingress,以及Controller Manager/Scheduler/Kubelet/etcd各负责什么。你能把一条调用链路从外部入口讲到容器内部,再讲到数据落盘,这道面试题基本就是加分项。
第二,一定要自己搭实验环境。很多命令你不亲手敲一遍,永远不知道describe里的Events到底有多救命。用kind或k3s快速起一个集群也行,但我建议至少有一个人从头到尾用kubeadm初始化过一遍控制平面,亲自体会证书、etcd、kubelet之间的启动依赖,这些经验网上文章很难完全替代。
第三,面试答不上来不要硬编。先说出你掌握的部分,再补一句“这个点我回去细查”,远好过讲十分钟逻辑混乱的车轱辘话。Kubernetes本身是个巨大的体系,没有人什么都背得住,面试官更看重的是你有没有清晰的分析框架和动手验证的习惯。
我到现在还保留一个习惯:每次排障完,都会把现象、命令、事件、结论整理成一份自己的排错笔记。准备面试时翻一翻,比临时刷题高效得多。希望你也能把这些高频Kubernetes面试题当成一个个入口,真正去理解背后的调度、网络、存储、控制面协作机制,而不是只为了过面试。有了这个底子,无论题目怎么变,都不会慌。