K8s最核心的100道高频面试题
涵盖K8s架构、Pod生命周期、控制器、调度机制、网络存储、安全监控等核心内容的100道高频面试题详解。
K8s最核心的100道高频面试题
K8s(Kubernetes)作为云原生时代的核心基础设施,是每位后端工程师和运维人员必须掌握的技能。本文整理了100道最核心的高频面试题,涵盖架构、调度、网络、存储、安全、排障等核心领域,助你全面备战K8s面试。
一、架构与核心组件 (Architecture & Components)
1. 请简述 Kubernetes 的整体架构和核心组件?
K8s 采用经典的 Master/Worker 架构。
Master 节点(控制平面):
- kube-apiserver:集群的统一入口,所有资源请求和控制命令都通过它,提供基于 RESTful 的声明式 API,并负责认证、授权、准入控制。
- etcd:分布式键值数据库,存储集群的所有状态数据和配置信息。
- kube-scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的 Worker 节点上。
- kube-controller-manager:维护集群状态,比如故障检测、自动扩展、滚动更新等(包含 NodeController, ReplicaSetController 等)。
Worker 节点(数据平面):
- kubelet:负责维护容器的生命周期,与 apiserver 交互,根据接收到的指令管理 Pod 和容器(通过 CRI)。
- kube-proxy:负责提供集群内部的服务发现和负载均衡(实现 Service 概念,通过修改 iptables 或 ipvs 规则)。
- Container Runtime:容器运行环境(如 containerd, Docker 等)。
2. 描述一下创建一个 Pod 的完整流程?(经典必考)
- 用户通过 kubectl 或 API 提交创建 Pod 的请求。
- apiserver 接收请求,进行认证鉴权后,将 Pod 的元数据信息写入 etcd。
- kube-scheduler 通过 watch 机制监听到有新的、未调度的 Pod,执行调度算法(预选、优选),为 Pod 选择一个合适的 Node,并将绑定信息告诉 apiserver,更新到 etcd。
- 目标 Node 上的 kubelet 监听到有 Pod 被分配到了自己身上,调用容器运行时(CRI)拉取镜像并启动容器。
- kubelet 将 Pod 的状态(Running)汇报给 apiserver,并更新到 etcd。
3. Etcd 挂了集群会怎样?如何备份和恢复?
影响:Etcd 挂了会导致 API Server 无法读写集群状态。现有的 Pod 还会继续运行(因为 kubelet 自身有缓存机制),但无法创建新资源、无法进行调度、无法更新状态(如扩容、更新镜像失效)。
备份:使用 etcdctl snapshot save 命令定期备份。
恢复:使用 etcdctl snapshot restore 命令,需停止 apiserver,指定原有数据目录进行恢复。
二、Pod 与生命周期 (Pod & Lifecycle)
4. 为什么 K8s 需要 Pod 这个概念,而不是直接管理容器?
- 逻辑边界:Pod 是 K8s 中最小的调度和部署单元。有些应用是由多个紧密耦合的进程(容器)组成的(例如:主程序 + 收集日志的 sidecar),它们需要共享网络命名空间(同一个 IP 和端口空间)和共享存储(Volume)。
- 解耦抽象:Pod 提供了一层抽象,使得 K8s 可以不依赖于具体的容器运行时(如 Docker、containerd),专注于管理应用的生命周期。
5. 简述 Pod 的生命周期和常见状态?
- Pending(挂起):API Server 已经创建了 Pod,但还没有被调度,或者镜像正在下载中。
- Running(运行中):Pod 已经被调度到了 Node 上,且所有容器都已创建,至少有一个容器正在运行或正在启动。
- Succeeded(成功):Pod 中的所有容器都已成功终止,并且不会再重启(常见于 Job)。
- Failed(失败):Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。
- Unknown(未知):因为某些原因无法取得 Pod 的状态(通常是 kubelet 和 apiserver 失联)。
6. K8s 中有哪几种探针(Probes)?有什么区别?
- StartupProbe(启动探针):检测容器内的应用是否已经成功启动。如果配置了它,在它成功之前,其他探针都被禁用。适用于启动非常慢的应用。
- ReadinessProbe(就绪探针):检测容器是否准备好接收流量。如果失败,K8s 会将该 Pod 的 IP 从 Service 的 Endpoints 中移除,不给它转发流量。
- LivenessProbe(存活探针):检测容器是否还在健康运行。如果探测失败,kubelet 会杀死该容器,并根据 restartPolicy 决定是否重启。
7. Init Container(初始化容器)的作用是什么?
Init Container 在应用容器(App Container)启动之前运行,主要用于执行一些前置初始化操作。
特点:必须运行至完成(成功退出),且按顺序串行执行。
场景:等待数据库等外部服务就绪、修改挂载目录的权限、从远程下载配置文件等。
三、控制器 (Workload Controllers)
8. Deployment 和 StatefulSet 的区别是什么?
Deployment:适用于无状态应用。Pod 之间是相互等价的,随机命名,不保证启动顺序。数据不持久化,IP 会随时变化。
StatefulSet:适用于有状态应用(如 DB、Kafka)。
- 稳定标识:每个 Pod 都有固定的网络标识(如
pod-0,pod-1)。 - 有序部署/删除:严格按照索引顺序启动和停止。
- 稳定存储:通过 VolumeClaimTemplates,每个 Pod 都有自己独立的、不随 Pod 重建而丢失的 PVC/PV 存储。
9. DaemonSet 的应用场景是什么?
DaemonSet 确保在集群的每一个(或指定的某些)Node 上都运行一个且仅运行一个 Pod 副本。
场景:运行集群存储 Daemon(如 Glusterd、Ceph)、运行日志收集 agent(如 Fluentd、Logstash)、运行网络/监控 agent(如 Prometheus Node Exporter)。
10. Deployment 的滚动更新(Rolling Update)机制是怎样的?
当修改了 Deployment 的 Pod 模板(如更新镜像版本)时,会触发更新。K8s 会创建一个新的 ReplicaSet,并根据 maxSurge(最大超出 Pod 数)和 maxUnavailable(最大不可用 Pod 数)两个参数,逐步增加新 RS 的 Pod 数量,同时逐步减少旧 RS 的 Pod 数量。这保证了在更新期间始终有足够的可用实例对外提供服务,实现零停机部署。
四、调度机制 (Scheduling)
11. Kube-scheduler 的调度过程是怎样的?
调度分为两大阶段:
- Predicates(预选过滤):过滤掉不满足 Pod 运行条件的 Node(如资源不足、端口冲突、节点不可达等)。
- Priorities(优选打分):对通过预选的 Node 进行打分计算(如资源利用率最均衡的打分高,镜像已存在的打分高)。选出分数最高的 Node 并绑定。
12. 解释 NodeSelector、NodeAffinity 和 PodAffinity?
- NodeSelector:简单的键值对匹配,强制要求 Pod 调度到包含对应 label 的 Node 上。
- NodeAffinity(节点亲和性):表达能力更强,支持操作符(In, NotIn, Exists)。分为硬策略(必须满足)和软策略(尽量满足)。
- PodAffinity/AntiAffinity(Pod亲/反亲和性):决定 Pod 应该与哪些已存在的 Pod 部署在同一个拓扑域(如同一个 Node 或机架),或者避开哪些 Pod(如主从节点不能在同一个 Node 上)。
13. Taint(污点)和 Toleration(容忍度)是怎么工作的?
亲和性是让 Pod "选择" Node;污点是让 Node "拒绝" Pod。
我们在 Node 上打上 Taint(如 NoSchedule 拒绝调度,NoExecute 驱逐当前 Pod)。除非 Pod 在定义时声明了对应的 Toleration(容忍这个污点),否则 Pod 无法调度到该节点上。常用于专用节点(如 GPU 节点隔离、Master 节点保护)。
五、网络与服务发现 (Networking & Service)
14. Kubernetes 的网络模型(CNI)基本原则是什么?
K8s 并不内置网络实现,而是制定了 CNI 规范,要求网络插件(如 Calico, Flannel)必须满足:
- 所有的 Pod 之间可以在不使用 NAT 的情况下相互通信。
- 所有的 Node 与所有的 Pod 之间可以在不使用 NAT 的情况下相互通信。
- Pod 自己看到的 IP 也就是其他网络实体看到的该 Pod 的 IP。
15. Service 有哪几种常用的类型(Type)?
- ClusterIP(默认):分配一个仅在集群内部可访问的虚拟 IP。
- NodePort:在所有 Node 上开放一个静态端口(默认 30000-32767),外部流量访问 NodeIP:NodePort 会被路由到后端的 Pod。
- LoadBalancer:使用云提供商的负载均衡器,为 Service 提供公网 IP(依赖云环境)。
- ExternalName:将集群外的服务引入到集群内,通过返回 CNAME 记录实现,没有 ClusterIP。
16. Kube-proxy 的 iptables 模式和 ipvs 模式有什么区别?
- iptables:Kube-proxy 监听 Service 和 Endpoints 的变化,并创建相应的 iptables 规则。缺点:规则基于线性遍历,当 Service 数量庞大(过万)时,性能急剧下降,且不支持复杂的负载均衡算法。
- ipvs:也是基于 Netfilter 框架,但使用哈希表来存储规则,支持 O(1) 的查找复杂度,性能极高。支持多种轮询算法(rr, lc, dh 等)。生产环境通常推荐使用 ipvs。
17. Ingress 和 Service 的区别是什么?
- Service 主要工作在网络层(L4),解决的是集群内部的服务发现和基于 TCP/UDP 的负载均衡。
- Ingress 工作在应用层(L7),本质是一个反向代理(如 Nginx、Traefik)。它提供 HTTP/HTTPS 的路由规则,通过域名或 URL 路径将外部流量转发到集群内部的不同 Service。
六、存储 (Storage)
18. 解释一下 PV、PVC 和 StorageClass 之间的关系?
- PV (PersistentVolume):集群级别的存储资源池,由管理员配置或自动动态配置(是对底层存储如 NFS, Ceph 的抽象)。
- PVC (PersistentVolumeClaim):命名空间级别的资源,是用户对存储的请求(指定需要多少容量,哪种读写模式)。PVC 和 PV 进行绑定。
- StorageClass:用于实现动态存储供应。管理员定义不同类型的 SC,当用户创建 PVC 并指定 SC 时,K8s 会自动调用对应的 Provisioner 动态生成一个 PV 与之绑定,无需人工介入。
19. emptyDir 和 hostPath 的区别?
- emptyDir:Pod 分配到 Node 时创建的临时空目录。当 Pod 被删除时,emptyDir 中的数据也会被永久删除。多用于 Pod 内不同容器共享临时数据。
- hostPath:将 Node 宿主机上的实际目录挂载到 Pod 中。即使 Pod 被删除,宿主机上的数据依然保留。缺点是降低了 Pod 的可移植性(强绑定特定节点)。
七、安全与配置 (Security & Config)
20. ConfigMap 和 Secret 的区别是什么?更新后 Pod 会自动生效吗?
区别:ConfigMap 用于存储明文配置(如配置文件、环境变量)。Secret 用于存储敏感数据(如密码、证书),数据在 etcd 中默认是 base64 编码的。
自动生效问题:如果作为环境变量注入,修改 CM/Secret 后 Pod 不会自动更新环境变量,需要重启 Pod。如果作为 Volume 挂载,修改后 kubelet 会在下一个同步周期(约几分钟内)自动热更新文件,应用是否能感知取决于应用本身是否支持热加载配置。
21. K8s 的 RBAC 包含哪几个核心概念?
基于角色的访问控制包含四个核心对象:
- Role / ClusterRole:定义了一组权限规则(可以对哪些资源执行什么操作,如对 Pod 执行 get/list)。Role 针对单个命名空间,ClusterRole 针对全集群。
- RoleBinding / ClusterRoleBinding:将 Role/ClusterRole 赋予给具体的实体(User、Group 或 ServiceAccount)。
22. ServiceAccount 和 UserAccount 的区别?
- UserAccount:给集群外的人员(人类用户)使用的,K8s 本身不管理 UserAccount 的存储,通常依赖外部认证系统(如 OIDC, LDAP)。全局有效。
- ServiceAccount:给集群内部的进程(Pod)使用的,让 Pod 能安全地与 API Server 交互。属于特定的 Namespace,由 K8s 自动管理和颁发 Token。
八、监控与排障 (Troubleshooting)
23. Pod 一直处于 Pending 状态,如何排查?
- 使用
kubectl describe pod <pod-name>查看最后 Events。 - 通常是因为调度失败:资源不足(CPU/内存无法满足 requests),找不到匹配的 NodeSelector/节点亲和性,或者没有容忍目标 Node 的 Taints。
- 检查 PVC 是否处于 Unbound 状态,导致 Pod 无法挂载存储而无法调度。
24. Pod 一直处于 CrashLoopBackOff 状态,如何排查?
CrashLoopBackOff 表示容器启动后很快就崩溃了,kubelet 正在尝试不断重启它。
- 使用
kubectl logs <pod-name> [--previous]查看应用崩溃的错误日志。 - 检查应用是否缺乏必要的依赖(如连不上数据库、ConfigMap 配置错误)。
- 检查 Liveness 存活探针是否配置过于严格,导致应用启动还没完成就被频繁杀死。
- 检查 Dockerfile 的 CMD/ENTRYPOINT 是否正确,前台进程是否意外退出。
25. 什么是 HPA (Horizontal Pod Autoscaler)?它的工作依赖什么?
HPA 是 Pod 的水平自动扩缩容组件。它根据监控指标动态增加或减少 Deployment 的 Pod 副本数。
依赖:它依赖 Metrics Server 提供资源指标(如 CPU、内存使用率)。如果是基于自定义指标(如 QPS),则依赖 Prometheus 等监控系统配合 prometheus-adapter 提供 Custom Metrics。
九、进阶与杂项 (Advanced & Misc)
26. 容器逃逸是什么?K8s 中如何防范?
容器内进程突破隔离,获取到了宿主机的 root 权限。防范措施:禁止 Privileged 特权模式运行,使用 SecurityContext 限制用户(runAsNonRoot),使用 AppArmor/SELinux 等进行内核级隔离。
27. 简述 CRD 和 Operator?
CRD (Custom Resource Definition) 是 K8s 提供的扩展机制,允许用户自定义资源对象。Operator = CRD + 自定义控制器 (Controller)。它将运维人员的知识代码化,用来自动化管理复杂应用(如自动化部署和备份 MySQL/Elasticsearch 集群)。
28. 如何实现 K8s 集群的高可用?
主要是控制平面的高可用。部署多个 Master 节点(通常至少 3 个)。Etcd 组成集群;多个 APIServer 前挂一个 LoadBalancer(如 HAProxy + Keepalived);Controller Manager 和 Scheduler 通过内部选主机制(Leader Election)确保同一时间只有一个在工作。
29. 如果删除一个带 finalizer 的资源,会发生什么?
资源不会立即被物理删除,状态会变成 Terminating,并且 deletionTimestamp 字段会被赋值。直到专门的控制器处理完资源回收逻辑并移除了对应的 finalizer 标识,K8s 才会真正将其从 etcd 中删除。
30. 什么是 Headless Service?有什么用?
将 Service 的 clusterIP 设为 None 的 Service。它不走 kube-proxy 的负载均衡,也不分配虚拟 IP。主要用于 StatefulSet,通过 CoreDNS 回答该 Service 名称时,会直接返回后端所有 Pod 的真实 IP 列表,方便应用端自己做负载均衡或点对点通信(如 Kafka, Zookeeper 集群)。
十、进阶网络 (Advanced Networking)
31. Flannel 的 VXLAN 模式和 Host-GW 模式有什么区别?
- VXLAN(默认):属于 Overlay(叠加)网络。它在 L2/L3 层面上封装原始报文(UDP 封装),使得跨主机的 Pod 看起来在同一个二层局域网内。优点是对底层网络要求低,缺点是封包解包有性能损耗。
- Host-GW:纯路由模式。它将每个 Node 作为一个路由器,直接通过修改主机的路由表来进行转发。优点是没有封包解包开销,性能极高;缺点是要求所有 Node 必须在同一个物理二层网络内(不能跨子网)。
32. Calico 的 IPIP 模式和 BGP 模式的区别是什么?
Calico 默认是三层网络插件。
- IPIP 模式:类似 VXLAN,也是一种 Overlay 隧道技术(IP in IP),性能会有一定折损,通常用于跨网段的 Node 之间通信。
- BGP 模式:性能最好的 Underlay 模式。每个 Node 运行一个 BGP 路由进程,将 Pod 的路由信息广播给其他节点或物理交换机。数据包直接通过原生路由转发,无额外封装。
33. CoreDNS 在 K8s 中的服务发现机制是怎样的?域名格式是什么?
机制:CoreDNS 监听 apiserver 中 Service 和 Endpoints 的变化,并动态生成 DNS 记录。当 Pod 需要访问 Service 时,会通过自身的 /etc/resolv.conf 将 DNS 请求发给 CoreDNS。
域名格式:<service-name>.<namespace>.svc.cluster.local。如果是同 Namespace 访问,可以直接用 <service-name>。
34. 什么是 NetworkPolicy(网络策略)?
默认情况下,K8s 集群内的 Pod 是全连通的。NetworkPolicy 相当于 Pod 级别的"防火墙",用于控制 Pod 之间、Pod 与外部网络之间的进出流量(Ingress / Egress)。它依赖底层网络插件(如 Calico, Cilium)来实现,Flannel 默认不支持。
35. Ingress Controller 是如何感知 Service 变化并更新路由的?
Ingress Controller(如 Nginx Ingress)作为一个 Pod 运行在集群中。它通过 K8s 的 Informer 机制持续 Watch(监听) Ingress、Service 和 Endpoints 资源。当后端 Pod 扩缩容导致 Endpoints 改变时,Controller 会自动重新生成 Nginx 的配置文件(nginx.conf),并触发 Nginx 的 reload 从而生效。
十一、进阶存储与持久化 (Advanced Storage)
36. 什么是 CSI (Container Storage Interface)?为什么要用它?
CSI 是容器存储接口的标准规范。以前 K8s 的存储插件代码是直接写死在 K8s 源码里的(in-tree),导致 K8s 核心代码臃肿,且存储厂商更新插件必须跟着 K8s 发版。CSI 将存储解耦(out-of-tree),存储厂商只要实现 CSI 接口的独立组件,即可在任何支持 CSI 的调度器中使用。
37. StatefulSet 缩容时,对应的 PVC 和 PV 会被删除吗?
不会。为了防止数据丢失,StatefulSet 在缩容或删除 Pod 时,绝对不会自动删除关联的 PVC。如果需要释放存储空间,必须由管理员手动删除对应的 PVC(随后 PV 会根据回收策略 Retain/Delete 决定是否保留)。
38. 如何实现 K8s 中 PV 的动态扩容?
前提是底层存储插件支持且 StorageClass 开启了 allowVolumeExpansion: true。操作时,只需修改 PVC 中的 resources.requests.storage 大小。K8s 的 volume-expansion 控制器会自动调用底层存储扩容,并由 kubelet 调整 Pod 挂载目录的文件系统大小。
39. local 存储卷(Local Persistent Volume)和 hostPath 的本质区别?
- 两者都使用节点本地磁盘。
- hostPath 没有调度的概念。如果在 Pod 声明,调度器不管节点上有没有这个目录,先调度过去再说。
- Local PV 是 K8s 作为标准 PV 来管理的,它与 Node 强绑定。调度器在调度使用了 Local PV 的 Pod 时,会感知存储的拓扑位置,强制将 Pod 调度到拥有该块磁盘的特定 Node 上,更适合生产环境的分布式数据库(如 TiDB, Elasticsearch)。
十二、资源管理与调度 (Resource & Scheduling)
40. K8s 中的 QoS (Quality of Service) 分为哪三种级别?
K8s 根据 Pod 对 CPU/Memory 的 Requests 和 Limits 配置,将 Pod 划分为三个 QoS 级别,决定了节点内存不足(OOM)时被杀掉的优先级:
- Guaranteed(最高,最后被杀):Pod 中所有容器都同时设置了相同大小的 Requests 和 Limits。
- Burstable(中等):至少有一个容器设置了 Requests,但不满足 Guaranteed 条件(如 Limits 大于 Requests,或只设了 Requests)。
- BestEffort(最低,最先被杀):所有容器既没有设置 Requests 也没有设置 Limits。
41. 如果只设置 Limits 不设置 Requests 会发生什么?
K8s 默认会自动将 Requests 设置为与 Limits 相同的值。此时该容器的 QoS 级别会提升为 Guaranteed。
42. VPA (Vertical Pod Autoscaler) 能和 HPA 同时使用吗?
VPA 用于垂直扩缩容(自动调整 Pod 的 CPU/内存 Requests)。官方不建议将 VPA 和基于 CPU/内存指标的 HPA 混用,因为它们会产生冲突:当负载变高时,VPA 想调大 CPU 请求导致 Pod 重建,而 HPA 想增加 Pod 副本数。如果要混用,HPA 只能基于自定义指标(如 QPS)。
43. 什么是 CPU Manager(绑核)?在什么场景下使用?
默认情况下,容器的 CPU 进程会在宿主机的多个 CPU 核心之间频繁上下文切换,影响性能。开启 kubelet 的 CPU Manager 且策略为 static 时,对于 QoS 为 Guaranteed 且 CPU 为整数个的 Pod,K8s 会为其分配独占的物理 CPU 核心。常用于对延迟极其敏感的场景(如高频交易、DPDK 网络应用)。
44. Descheduler(重调度器)的作用是什么?
原生的 kube-scheduler 是静态调度的(只管创建时安排在哪)。但集群运行久了,节点资源碎片化或新增了节点,会导致资源分布极度不均。Descheduler 是一个独立组件,它根据策略(如节点利用率过低、违反了反亲和性等)主动驱逐(Evict)已经在运行的 Pod,让 kube-scheduler 重新将它们调度到更合理的节点上。
十三、安全与权限 (Security & Authentication)
45. K8s API Server 的安全控制包含哪三个关键步骤?
所有请求到达 APIServer 都要经过三道关卡:
- 认证 (Authentication):确认"你是谁"(如通过 X509 证书、ServiceAccount Token、OIDC)。
- 授权 (Authorization):确认"你能做什么"(如通过 RBAC 检查你是否有权限 get/delete 这个 Pod)。
- 准入控制 (Admission Control):确认"你的请求内容是否合规"(进一步修改或拒绝请求,如限制镜像仓库、强制注入 Sidecar)。
46. 准入控制器 (Admission Controller) 中的 Mutating 和 Validating 区别?
- Mutating(变更型):发生在 Validating 之前。它可以修改用户的请求。例如 Istio 自动注入就是拦截 Pod 创建请求,把 sidecar 容器的代码塞进请求体里。
- Validating(验证型):用于校验请求是否合法。例如拦截不允许从 public 仓库拉取镜像的请求。如果不符合规则,直接拒绝拦截。
47. kubelet 的匿名访问有什么安全风险?
默认情况下,kubelet 监听的 10250 端口可能允许匿名访问。如果未配置鉴权(authorization.mode=Webhook),攻击者可以直接调用 kubelet API 接口(如 /run 或 /exec)在任意 Pod 内执行恶意命令,甚至导致集群被完全控制。
48. 什么是 PodSecurityContext?它能做什么?
用于定义 Pod 或容器的权限和访问控制设置。可以做到的事情包括:
runAsUser / runAsGroup:强制容器以非 root 用户运行。privileged: false:禁止容器开启特权模式。readOnlyRootFilesystem: true:将容器的根文件系统设为只读。
十四、核心组件源码级机制 (Core Internals)
49. 什么是 Informer 机制?为什么不直接 Watch Etcd?
机制:Informer 是 K8s client-go 库中的核心组件。它通过对 APIServer 执行 List&Watch 操作,在本地建立并维护一个资源的内存缓存(Local Store)。
原因:如果所有的 Controller(如 Deployment, Node 控制器)都直接去 Watch Etcd 或频繁轮询 API Server,会导致极大的网络和存储压力。Informer 使得 Controller 只需要读取本地内存缓存,极大提升了性能并降低了 APIServer 的负载。
50. kubelet 的 SyncLoop (同步循环) 是如何工作的?
SyncLoop 是 kubelet 的主循环。它通过各种来源(File, URL, APIServer)监听 Pod 的期望状态(Spec)。当监听到变化时,SyncLoop 会将当前节点上 Pod 的实际运行状态与期望状态进行对比(对比镜像、容器状态、网络等),然后通过调用 CRI 接口(如创建/删除容器)来抹平差异,使实际状态逼近期望状态。
51. 什么是 CNI、CRI 和 CSI?它们在 K8s 架构中分别负责什么?
这是 K8s 走向高可扩展性的三大标准化接口:
- CRI (Container Runtime Interface):容器运行时接口。kubelet 通过它与底层的容器引擎(Containerd, CRI-O)通信,管理容器生命周期。
- CNI (Container Network Interface):容器网络接口。kubelet 创建 Pod 时调用它为网络命名空间分配 IP、配置路由规则(如 Calico, Flannel)。
- CSI (Container Storage Interface):容器存储接口。负责 PV 的生命周期管理,将存储卷挂载/卸载到 Pod。
52. Kubernetes 1.24 为什么移除了 Dockershim?有什么影响?
原因:K8s 内部通过 CRI 与容器运行时交互。而 Docker 原生不支持 CRI。之前 K8s 为了支持 Docker,在 kubelet 中硬编码写了一个转换层叫 Dockershim。移除它是为了去掉这层技术债,提升性能并鼓励使用更轻量的 CRI 兼容运行时(如 Containerd)。
影响:对普通业务开发者无影响(镜像格式仍通用)。对运维而言,节点上的容器引擎需要从 Docker 切换为 Containerd,部分强依赖 docker socket 的日志收集或 CI/CD 工具需要适配。
十五、生产排障与稳定性 (Production Troubleshooting)
53. Node 的状态变成 NotReady,通常的排查思路是什么?
- 检查组件:SSH 登录节点,
systemctl status kubelet和docker/containerd,看是否进程挂了。 - 检查日志:
journalctl -u kubelet -f查看错误。常见原因是节点资源(CPU/内存/磁盘)耗尽被系统挂起,或证书过期。 - 网络排查:检查该 Node 与 Master 节点的网络连通性,kubelet 是否无法上报心跳给 APIServer。
54. 什么是 Eviction (驱逐)?Kubelet 什么情况下会触发本地驱逐?
Kubelet 会定期监控节点资源(Memory, 磁盘可用空间, PID 数量)。当这些资源低于设定的阈值(evictionHard)时,kubelet 会触发驱逐机制,主动杀掉部分 Pod(优先杀 BestEffort 类型的)以回收资源,保护宿主机不崩溃。被驱逐的 Pod 状态会变为 Evicted。
55. 出现 ImagePullBackOff 错误,除了网络不通还有哪些原因?
- 镜像仓库地址或镜像 tag 写错(不存在)。
- 拉取私有镜像仓库时,忘记配置或绑错 imagePullSecrets。
- Node 节点的磁盘空间满了,无法解压新的镜像层。
- 并发拉取镜像过多导致被 Registry 频控限流(如 Docker Hub 的 Rate Limit)。
56. Service 发布后偶尔出现 Connection Refused,可能是什么原因?
- 应用未就绪:没有正确配置 ReadinessProbe,导致应用还在启动初始化中,流量就被转发进来了。
- 优雅退出未处理:缩容或滚动更新时,Pod 被打上了删除标记但仍在处理旧请求。应该在应用中处理 SIGTERM 信号,或在 preStop hook 中 sleep 几秒,等待 K8s 更新完 iptables/ipvs 规则后再停止进程。
57. 什么是 OOMKilled?如何排查?
Pod 被宿主机的 Linux OOM (Out Of Memory) Killer 杀死了。通常是因为容器使用的内存超过了在 K8s 中设定的 Limits 值。
排查:kubectl describe pod 会显示 Reason: OOMKilled,Exit Code 通常是 137。需要结合应用日志和 APM 监控排查代码是否存在内存泄漏,或者适当调大资源 Limits。
58. K8s 有回收站机制吗?Pod 被误删了怎么办?
K8s 原生没有资源回收站机制,一旦从 APIServer 删除就没了(如果是非级联删除,可能后台资源还在)。
恢复:如果是 Deployment 等控制器部署的,控制器会自动拉起一个新的 Pod。如果是直接创建裸 Pod 被删了,只能从之前的 Yaml 文件或 GitOps 仓库重新创建。推荐生产环境使用 Velero 等工具定期备份集群状态。
59. 如何防止核心应用在缩容或节点维护时全部掉线?
配置 PDB (PodDisruptionBudget)。它可以限制由于自愿中断(如主动驱逐、Node 维护排空)导致的某个应用的最小可用副本数或最大不可用副本数。比如设置 minAvailable: 80%,当节点维护导致驱逐时,K8s 会严格保证至少有 80% 的实例存活。
60. kubectl exec 的完整底层网络链路是怎样的?
这是一道极其考验内功的题。
- 用户执行命令 -> 请求发给 APIServer。
- APIServer 根据 Pod 所在 Node,主动与该 Node 上的 kubelet 建立 HTTP 且 Upgrade 为 SPDY/WebSocket 长连接。
- kubelet 通过 CRI 接口调用底层的容器运行时(如 Containerd)。
- 容器运行时在宿主机上启动相应的进程(如
/bin/bash),将其标准输入输出流(stdin/stdout)通过管道接管,并顺着刚才的长连接链路原路返回给最终用户的终端。
十六、网络排错深度实战 (Network Troubleshooting)
61. 在 Pod 内访问外部域名非常慢,甚至时好时坏,如何定位?
- DNS 缓存问题:检查 Pod 内
/etc/resolv.conf的 ndots 配置,默认 5 会导致多次无效搜索。 - CoreDNS 负载:检查 CoreDNS Pod 的 CPU/内存是否触及 Limit 导致丢包。
- 并发连接数:某些内核版本下,Conntrack 表满或
nf_conntrack竞争会导致 DNS 请求(UDP)丢包。 - IPv6 干扰:检查是否是因为 AAAA 记录查询超时。
62. 如何排查 Service 负载均衡不均的问题?
- 会话保持:检查 Service 是否开启了 sessionAffinity。
- 代理模式:检查 kube-proxy 模式。iptables 模式下是随机转发,而 ipvs 模式下支持轮询(rr)或最小连接数(lc)。
- 长连接干扰:如果应用使用 HTTP/2 或 gRPC 长连接,L4 层面的 Service 无法感知负载,需使用 L7 Ingress 或 Service Mesh。
63. 跨主机的 Pod 之间无法 Ping 通,排查步骤有哪些?
- 检查 CNI 状态:所有 Node 上的 CNI 插件是否运行正常。
- 物理网络:检查安全组/防火墙是否放行了隧道协议端口(如 VXLAN 的 UDP 4789,IPIP 的协议号 4)。
- MTU 冲突:检查 CNI 网卡与物理网卡的 MTU 大小,隧道封装会导致有效载荷变小,不匹配会造成大包丢弃。
- 路由表:检查宿主机路由表是否有冲突,或指向对方 Pod 掩码的路由是否正确。
64. 什么是 TCP "Half-Open" 连接,在 K8s 中如何监控它?
指 TCP 三次握手未完成的状态。
监控:在 Node 上使用 ss -ant | grep SYN-RECV 或 netstat。
K8s 场景:通常发生在 Service 压力过大、kube-proxy 转发规则失效或后端 Pod 挂起时。
65. 如何在不修改镜像的情况下,对运行中的 Pod 进行抓包?
- kubectl debug:使用
kubectl debug -it <pod-name> --image=nicolaka/netshoot启动一个共享网络命名空间的临时容器。 - 宿主机抓包:找到 Pod 的 container_id,利用
nsenter -t <pid> -n tcpdump进入 Pod 网络空间抓包。
十七、性能调优 (Performance Optimization)
66. APIServer 压力过大,响应变慢,应该从哪些方面调优?
- Etcd 优化:确保 Etcd 使用高性能 SSD,调整
--max-request-bytes。 - 限流降级:调整 APIServer 的
max-requests-inflight(非突发请求数)和max-mutating-requests-inflight。 - 并发处理:增加
--api-audiences和工作线程数。 - 客户端优化:检查是否有错误的 Controller 在频繁 List 全量资源,推动其改为使用 Informer 机制。
67. Kubelet 出现 "Disk Pressure" 报警,但磁盘空间还够,可能是什么原因?
除了总空间不足,Inode 耗尽也会触发磁盘压力报警。如果容器产生大量小文件(如未处理的日志),会导致 Inode 耗尽。
68. 大规模集群(5000+ 节点)下,如何优化 Kube-proxy 的性能?
必须切换到 IPVS 模式。IPVS 使用哈希表,在规则极多时查找效率远高于 iptables 的链式遍历。此外,可以调整 ipvs-sync-period 来控制规则同步频率。
69. 如何优化 Pod 的启动速度?
- 镜像预拉取:提前在 Node 上缓存基础镜像。
- 减少体积:使用 Alpine 或 Distroless 镜像。
- 启动探针延迟:合理配置
initialDelaySeconds,避免应用还没初始化完就被探测导致重启。 - ImagePullPolicy:生产环境建议设为
IfNotPresent。
70. 什么是 CPU Throttling?如何发现并解决?
当容器在周期内用完了 limits 分配的 CPU 时间片后,会被内核强行限制。
发现:监控 container_cpu_cfs_throttled_seconds_total 指标。
解决:即使平均 CPU 不高,突发流量也会导致 Throttling。应适当调大 Limits,或优化代码中的多线程并发逻辑。
十八、CI/CD 集成与交付 (CI/CD & Delivery)
71. 描述一种典型的基于 K8s 的 GitOps 流程?
- 开发提交代码到 Git。
- CI 工具(如 Jenkins/GitLab CI)构建镜像并推送到镜像仓库。
- CI 工具更新 Git 仓库中的 Yaml 配置(而不是直接
kubectl apply)。 - CD 工具(如 ArgoCD 或 Flux)监听到 Yaml 变更,自动将集群状态同步至与 Git 描述一致。
72. 蓝绿部署和金丝雀发布(Canary)在 K8s 中分别如何实现?
- 蓝绿部署:部署两套全量 Service/Deployment。通过切换 Ingress 或 Service 的 label selector 来实现瞬间切换。
- 金丝雀发布:创建一个新的 Deployment 运行少量副本。利用 Ingress 控制器(如 Nginx Annotations)或 Service Mesh(如 Istio)按权重(如 10% 流量)切分部分流量到新版本,验证无误后再全量更新。
73. Jenkins 动态 Slave 节点在 K8s 中是如何工作的?
利用 Kubernetes Plugin。当 Jenkins 有构建任务时,会调用 K8s API 动态创建一个临时 Pod 作为 Agent 执行构建;任务结束后,Pod 自动销毁。这极大地节省了资源并实现了构建环境的标准化。
74. 如何在 K8s 中安全地管理镜像仓库的凭证?
创建类型为 kubernetes.io/dockerconfigjson 的 Secret。在 Deployment 的 imagePullSecrets 中引用该 Secret。如果是全集群通用,可以将 Secret 绑定到 default ServiceAccount 的 imagePullSecrets 列表中。
75. Helm Chart 的核心作用是什么?它解决了什么痛点?
Helm 是 K8s 的包管理器。它解决了原生 Yaml 无法传参、版本管理难、多组件依赖复杂的痛点。通过模板引擎,可以实现一套配置在不同环境(开发/生产)的差异化部署。
十九、集群运维与高可用 (Ops & HA)
76. 如果集群证书快过期了,如何不间断业务进行更换?
K8s 1.15+ 支持 kubeadm certs renew。
- 更新 Master 各组件证书。
- 重启控制平面组件。
- 开启 kubelet 证书自动续签(
RotateKubeletClientCertificate)。
77. 为什么说 K8s 控制平面节点建议部署奇数个(3, 5, 7)?
主要是为了满足 Etcd 的 **Quorum(法定人数)**机制。Etcd 基于 Raft 协议,需要 (n/2)+1 个节点存活才能正常工作。3 个节点允许坏 1 个,4 个节点也只允许坏 1 个(且增加了一倍同步开销),所以奇数性价比最高。
78. 什么是"惊群效应"(Thundering Herd)在 K8s 调度中的体现?
当一个拥有大量副本数的 Deployment 突然因为某原因被全部删除并重建时,成千上万个 Pod 瞬间进入 Pending 状态等待调度,会造成 Scheduler 和 APIServer 负载瞬间暴涨。
79. K8s 如何对接外部的负载均衡器(如 F5 或云厂商 SLB)?
通过 Cloud Controller Manager (CCM)。当 Service 类型设为 LoadBalancer 时,CCM 会监听并调用云厂商的 API 来创建 LB,并将后端 Pod 的 IP 自动同步到 LB 的后端服务器池中。
80. 如何实现跨地域(Multi-Region)的 K8s 集群管理?
- 多集群模式:使用 Karmada 或 KubeFed 等联邦工具统一调度。
- 单集群跨域:对网络延迟要求极高,需通过专线打通,并使用节点亲和性确保业务不跨地域通信。
二十、综合场景与架构设计 (Architecture & Design)
81. 你的应用 Pod 频繁重启,但 kubectl logs 没有任何输出,怎么查?
- 检查
kubectl describe pod里的 Exit Code。如果是 137,是 OOM;如果是 1,是应用逻辑报错。 - 如果 logs 没输出,说明应用可能在初始化阶段或将日志写到了文件而非标准输出。尝试挂载 emptyDir 查看内部日志文件。
82. 生产环境中,你会如何配置 Pod 的优雅退出(Graceful Shutdown)?
- 应用代码监听 SIGTERM 信号,停止接收新请求并处理完存量请求。
- 设置合理的
terminationGracePeriodSeconds(默认 30s)。 - 如果应用不支持信号处理,在
lifecycle.preStop中添加脚本执行 sleep 或退出指令。
83. 什么是 K8s 的 Sidecar 模式?除了日志收集还有什么用?
在同一个 Pod 中运行辅助容器。
用途:服务网格代理(Envoy)、数据库代理、配置热同步、安全代理(鉴权)、调试工具。
84. 如何保证 Master 节点不运行任何业务 Pod?
给 Master 节点打上特殊的 Taint(污点):node-role.kubernetes.io/master:NoSchedule。
85. 集群中有 1000 个 Service,kube-proxy 消耗了大量 CPU,怎么解决?
切换到 IPVS 模式。iptables 模式下,每增加一个 Service 都会在全量规则中追加,数据包匹配是线性扫描;而 IPVS 是 Hash 查找。
86. 如何给运行中的 K8s 集群增加一个新的 Worker 节点?
使用 kubeadm token create --print-join-command 在 Master 生成加入命令,然后在远程机器执行 kubeadm join 即可。
87. 什么是 VPA 的 "Auto" 模式,它有什么潜在危险?
它会自动重启 Pod 以修改 CPU/内存的 Requests 值。如果在业务高峰期触发重启,且没有冗余副本,会导致业务中断。
88. 为什么 Pod 的 IP 地址是动态变化的?如何实现 Pod 的固定 IP?
动态变化是为了实现云原生的弹性和快速漂移。若非要固定 IP,通常需要特定的 CNI 插件(如 Calico 的静态 IP 绑定或某些云厂商的网卡直通技术),但通常建议通过 Service 域名访问来规避此需求。
89. 谈谈你对云原生安全中 "4C" 模型的理解?
- Cloud(云平台安全)
- Cluster(集群组件安全)
- Container(容器镜像安全)
- Code(代码与应用安全)
90. 如果 API Server 证书过期了,kubectl 还能用吗?
不能用,所有的请求都会报证书认证错误。需要手动进入 Master 节点使用 kubeadm 或手动工具替换证书并重启容器。
二十一、底层与趋势
91. 简述 eBPF 技术对 K8s 网络的革命性影响?
eBPF 可以在内核级别拦截和处理数据包,完全绕过 iptables/ipvs。代表项目 Cilium 实现了极高的网络转发、更精细的安全策略以及强大的可观测性。
92. 什么是 KEDA?它如何增强 K8s 的扩缩容?
基于事件驱动的自动伸缩。它可以根据消息队列(Kafka/RabbitMQ)的堆积量、数据库指标等外部事件来触发 Pod 扩缩容,甚至是缩容到 0。
93. 解释 Serverless 架构在 K8s 中的落地方式(如 Knative)?
Knative 提供了按需分配的能力。当没有请求时副本为 0,当请求到达时瞬间拉起 Pod(Scale-to-zero),并自动处理复杂的流量控制。
94. 为什么 K8s 默认不提供负载均衡器的 IP?
因为负载均衡器通常需要与底层基础设施(硬件或云平台)紧密集成,属于 IaaS 层的职责,K8s 通过接口(Cloud Provider)将这一能力外包。
95. 如何审计 K8s 中谁在什么时间删除了哪个 Pod?
开启 Audit Log(审计日志)。通过配置 Audit Policy,APIServer 会将所有的操作记录(Who, When, What)持久化到文件或外部系统。
96. K8s 的资源隔离是通过哪些内核技术实现的?
- Namespace(隔离视图,如网络、PID、挂载点)
- Cgroups(限制资源用量,如 CPU、内存)
97. 什么是容器的"幽灵进程"?如何防止?
当容器内 1 号进程不处理子进程回收时,会产生大量僵尸进程。
防止:镜像中使用 tini 作为 entrypoint,或在 Pod 中开启 shareProcessNamespace: true。
98. 简述大规模集群下 etcd 的碎片化问题及解决方法?
频繁的数据修改会导致 etcd 文件出现大量空洞(碎片)。需要定期执行 etcdctl defrag 整理磁盘空间,否则会导致存储占满引发集群锁定。
99. 如何实现 K8s 的多租户隔离?
- 软隔离:基于 Namespace + RBAC + NetworkPolicy + ResourceQuota。
- 硬隔离:使用 Kata Container 或 gVisor 等安全容器,或者干脆为不同租户部署独立集群。
100. 你认为 Kubernetes 未来的演进方向是什么?
- 下沉:成为像 Linux 一样的不可见的基础设施(如各种云托管服务)。
- 边缘计算:K3s/KubeEdge 推动 K8s 走向边缘。
- AI 合一:AI 算力调度(GPU 优化、调度增强)成为 K8s 的核心任务之一。