← 返回文章列表

K8s最核心的100道高频面试题

涵盖K8s架构、Pod生命周期、控制器、调度机制、网络存储、安全监控等核心内容的100道高频面试题详解。

51 分钟阅读
字号

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 的完整流程?(经典必考)

  1. 用户通过 kubectl 或 API 提交创建 Pod 的请求。
  2. apiserver 接收请求,进行认证鉴权后,将 Pod 的元数据信息写入 etcd。
  3. kube-scheduler 通过 watch 机制监听到有新的、未调度的 Pod,执行调度算法(预选、优选),为 Pod 选择一个合适的 Node,并将绑定信息告诉 apiserver,更新到 etcd。
  4. 目标 Node 上的 kubelet 监听到有 Pod 被分配到了自己身上,调用容器运行时(CRI)拉取镜像并启动容器。
  5. 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)必须满足:

  1. 所有的 Pod 之间可以在不使用 NAT 的情况下相互通信。
  2. 所有的 Node 与所有的 Pod 之间可以在不使用 NAT 的情况下相互通信。
  3. 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 状态,如何排查?

  1. 使用 kubectl describe pod <pod-name> 查看最后 Events。
  2. 通常是因为调度失败:资源不足(CPU/内存无法满足 requests),找不到匹配的 NodeSelector/节点亲和性,或者没有容忍目标 Node 的 Taints。
  3. 检查 PVC 是否处于 Unbound 状态,导致 Pod 无法挂载存储而无法调度。

24. Pod 一直处于 CrashLoopBackOff 状态,如何排查?

CrashLoopBackOff 表示容器启动后很快就崩溃了,kubelet 正在尝试不断重启它。

  1. 使用 kubectl logs <pod-name> [--previous] 查看应用崩溃的错误日志。
  2. 检查应用是否缺乏必要的依赖(如连不上数据库、ConfigMap 配置错误)。
  3. 检查 Liveness 存活探针是否配置过于严格,导致应用启动还没完成就被频繁杀死。
  4. 检查 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)时被杀掉的优先级:

  1. Guaranteed(最高,最后被杀):Pod 中所有容器都同时设置了相同大小的 Requests 和 Limits。
  2. Burstable(中等):至少有一个容器设置了 Requests,但不满足 Guaranteed 条件(如 Limits 大于 Requests,或只设了 Requests)。
  3. 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 都要经过三道关卡:

  1. 认证 (Authentication):确认"你是谁"(如通过 X509 证书、ServiceAccount Token、OIDC)。
  2. 授权 (Authorization):确认"你能做什么"(如通过 RBAC 检查你是否有权限 get/delete 这个 Pod)。
  3. 准入控制 (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,通常的排查思路是什么?

  1. 检查组件:SSH 登录节点,systemctl status kubeletdocker/containerd,看是否进程挂了。
  2. 检查日志journalctl -u kubelet -f 查看错误。常见原因是节点资源(CPU/内存/磁盘)耗尽被系统挂起,或证书过期。
  3. 网络排查:检查该 Node 与 Master 节点的网络连通性,kubelet 是否无法上报心跳给 APIServer。

54. 什么是 Eviction (驱逐)?Kubelet 什么情况下会触发本地驱逐?

Kubelet 会定期监控节点资源(Memory, 磁盘可用空间, PID 数量)。当这些资源低于设定的阈值(evictionHard)时,kubelet 会触发驱逐机制,主动杀掉部分 Pod(优先杀 BestEffort 类型的)以回收资源,保护宿主机不崩溃。被驱逐的 Pod 状态会变为 Evicted

55. 出现 ImagePullBackOff 错误,除了网络不通还有哪些原因?

  1. 镜像仓库地址或镜像 tag 写错(不存在)。
  2. 拉取私有镜像仓库时,忘记配置或绑错 imagePullSecrets。
  3. Node 节点的磁盘空间满了,无法解压新的镜像层。
  4. 并发拉取镜像过多导致被 Registry 频控限流(如 Docker Hub 的 Rate Limit)。

56. Service 发布后偶尔出现 Connection Refused,可能是什么原因?

  1. 应用未就绪:没有正确配置 ReadinessProbe,导致应用还在启动初始化中,流量就被转发进来了。
  2. 优雅退出未处理:缩容或滚动更新时,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 的完整底层网络链路是怎样的?

这是一道极其考验内功的题。

  1. 用户执行命令 -> 请求发给 APIServer。
  2. APIServer 根据 Pod 所在 Node,主动与该 Node 上的 kubelet 建立 HTTP 且 Upgrade 为 SPDY/WebSocket 长连接。
  3. kubelet 通过 CRI 接口调用底层的容器运行时(如 Containerd)。
  4. 容器运行时在宿主机上启动相应的进程(如 /bin/bash),将其标准输入输出流(stdin/stdout)通过管道接管,并顺着刚才的长连接链路原路返回给最终用户的终端。

十六、网络排错深度实战 (Network Troubleshooting)

61. 在 Pod 内访问外部域名非常慢,甚至时好时坏,如何定位?

  1. DNS 缓存问题:检查 Pod 内 /etc/resolv.conf 的 ndots 配置,默认 5 会导致多次无效搜索。
  2. CoreDNS 负载:检查 CoreDNS Pod 的 CPU/内存是否触及 Limit 导致丢包。
  3. 并发连接数:某些内核版本下,Conntrack 表满或 nf_conntrack 竞争会导致 DNS 请求(UDP)丢包。
  4. IPv6 干扰:检查是否是因为 AAAA 记录查询超时。

62. 如何排查 Service 负载均衡不均的问题?

  1. 会话保持:检查 Service 是否开启了 sessionAffinity。
  2. 代理模式:检查 kube-proxy 模式。iptables 模式下是随机转发,而 ipvs 模式下支持轮询(rr)或最小连接数(lc)。
  3. 长连接干扰:如果应用使用 HTTP/2 或 gRPC 长连接,L4 层面的 Service 无法感知负载,需使用 L7 Ingress 或 Service Mesh。

63. 跨主机的 Pod 之间无法 Ping 通,排查步骤有哪些?

  1. 检查 CNI 状态:所有 Node 上的 CNI 插件是否运行正常。
  2. 物理网络:检查安全组/防火墙是否放行了隧道协议端口(如 VXLAN 的 UDP 4789,IPIP 的协议号 4)。
  3. MTU 冲突:检查 CNI 网卡与物理网卡的 MTU 大小,隧道封装会导致有效载荷变小,不匹配会造成大包丢弃。
  4. 路由表:检查宿主机路由表是否有冲突,或指向对方 Pod 掩码的路由是否正确。

64. 什么是 TCP "Half-Open" 连接,在 K8s 中如何监控它?

指 TCP 三次握手未完成的状态。

监控:在 Node 上使用 ss -ant | grep SYN-RECVnetstat

K8s 场景:通常发生在 Service 压力过大、kube-proxy 转发规则失效或后端 Pod 挂起时。

65. 如何在不修改镜像的情况下,对运行中的 Pod 进行抓包?

  1. kubectl debug:使用 kubectl debug -it <pod-name> --image=nicolaka/netshoot 启动一个共享网络命名空间的临时容器。
  2. 宿主机抓包:找到 Pod 的 container_id,利用 nsenter -t <pid> -n tcpdump 进入 Pod 网络空间抓包。

十七、性能调优 (Performance Optimization)

66. APIServer 压力过大,响应变慢,应该从哪些方面调优?

  1. Etcd 优化:确保 Etcd 使用高性能 SSD,调整 --max-request-bytes
  2. 限流降级:调整 APIServer 的 max-requests-inflight(非突发请求数)和 max-mutating-requests-inflight
  3. 并发处理:增加 --api-audiences 和工作线程数。
  4. 客户端优化:检查是否有错误的 Controller 在频繁 List 全量资源,推动其改为使用 Informer 机制。

67. Kubelet 出现 "Disk Pressure" 报警,但磁盘空间还够,可能是什么原因?

除了总空间不足,Inode 耗尽也会触发磁盘压力报警。如果容器产生大量小文件(如未处理的日志),会导致 Inode 耗尽。

68. 大规模集群(5000+ 节点)下,如何优化 Kube-proxy 的性能?

必须切换到 IPVS 模式。IPVS 使用哈希表,在规则极多时查找效率远高于 iptables 的链式遍历。此外,可以调整 ipvs-sync-period 来控制规则同步频率。

69. 如何优化 Pod 的启动速度?

  1. 镜像预拉取:提前在 Node 上缓存基础镜像。
  2. 减少体积:使用 Alpine 或 Distroless 镜像。
  3. 启动探针延迟:合理配置 initialDelaySeconds,避免应用还没初始化完就被探测导致重启。
  4. ImagePullPolicy:生产环境建议设为 IfNotPresent

70. 什么是 CPU Throttling?如何发现并解决?

当容器在周期内用完了 limits 分配的 CPU 时间片后,会被内核强行限制。

发现:监控 container_cpu_cfs_throttled_seconds_total 指标。

解决:即使平均 CPU 不高,突发流量也会导致 Throttling。应适当调大 Limits,或优化代码中的多线程并发逻辑。

十八、CI/CD 集成与交付 (CI/CD & Delivery)

71. 描述一种典型的基于 K8s 的 GitOps 流程?

  1. 开发提交代码到 Git。
  2. CI 工具(如 Jenkins/GitLab CI)构建镜像并推送到镜像仓库。
  3. CI 工具更新 Git 仓库中的 Yaml 配置(而不是直接 kubectl apply)。
  4. CD 工具(如 ArgoCD 或 Flux)监听到 Yaml 变更,自动将集群状态同步至与 Git 描述一致。

72. 蓝绿部署和金丝雀发布(Canary)在 K8s 中分别如何实现?

  1. 蓝绿部署:部署两套全量 Service/Deployment。通过切换 Ingress 或 Service 的 label selector 来实现瞬间切换。
  2. 金丝雀发布:创建一个新的 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

  1. 更新 Master 各组件证书。
  2. 重启控制平面组件。
  3. 开启 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 集群管理?

  1. 多集群模式:使用 Karmada 或 KubeFed 等联邦工具统一调度。
  2. 单集群跨域:对网络延迟要求极高,需通过专线打通,并使用节点亲和性确保业务不跨地域通信。

二十、综合场景与架构设计 (Architecture & Design)

81. 你的应用 Pod 频繁重启,但 kubectl logs 没有任何输出,怎么查?

  1. 检查 kubectl describe pod 里的 Exit Code。如果是 137,是 OOM;如果是 1,是应用逻辑报错。
  2. 如果 logs 没输出,说明应用可能在初始化阶段或将日志写到了文件而非标准输出。尝试挂载 emptyDir 查看内部日志文件。

82. 生产环境中,你会如何配置 Pod 的优雅退出(Graceful Shutdown)?

  1. 应用代码监听 SIGTERM 信号,停止接收新请求并处理完存量请求。
  2. 设置合理的 terminationGracePeriodSeconds(默认 30s)。
  3. 如果应用不支持信号处理,在 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 的多租户隔离?

  1. 软隔离:基于 Namespace + RBAC + NetworkPolicy + ResourceQuota。
  2. 硬隔离:使用 Kata Container 或 gVisor 等安全容器,或者干脆为不同租户部署独立集群。

100. 你认为 Kubernetes 未来的演进方向是什么?

  1. 下沉:成为像 Linux 一样的不可见的基础设施(如各种云托管服务)。
  2. 边缘计算:K3s/KubeEdge 推动 K8s 走向边缘。
  3. AI 合一:AI 算力调度(GPU 优化、调度增强)成为 K8s 的核心任务之一。
分享

// RELATED_POSTS

0%