4411 字
22 分钟
Kubernetes 八股

架构与组件#

Kubernetes 核心组件有哪些?

  • Master(控制平面):kube-apiserver(API 入口)、etcd(配置存储)、kube-scheduler(调度)、kube-controller-manager(控制器)、cloud-controller-manager(云厂商控制器,可选)。
  • Node(工作节点):kubelet(Pod 生命周期)、kube-proxy(网络代理/负载均衡)、containerd(容器运行时)。

kube-apiserver 的作用? 集群统一 API 入口,所有组件通过它通信。它是唯一直接读写 etcd 的组件,负责认证(Authentication)、鉴权(Authorization)、准入控制(Admission)、校验与持久化,并提供 Watch 机制供其他组件监听资源变化。

etcd 的作用? 分布式 KV 存储,保存集群所有配置和状态数据。基于 Raft 协议保证强一致性,因此生产环境推荐 3/5 个奇数节点做高可用;它是集群的唯一真实数据源,备份 etcd 就等于备份整个集群。

kube-scheduler 如何调度 Pod? 过滤(Filtering)→ 打分(Scoring)→ 绑定(Binding)。过滤阶段剔除不满足条件的节点(资源不足、污点不容忍、端口冲突、亲和性不符);打分阶段按优先级函数(资源均衡、亲和性权重等)排序选出最优节点;最后把结果写入 Pod 的 nodeName(Binding)。调度考虑资源、亲和性、污点容忍、拓扑分布等。

kube-controller-manager 的作用? 运行一系列控制循环(Reconcile Loop),让实际状态不断逼近期望状态。常见控制器:Deployment、ReplicaSet、StatefulSet、DaemonSet、Node、Job、EndpointSlice、ServiceAccount 等。多个控制器共享同一进程以减少复杂度。

kubelet 的作用? 每个节点上的代理,负责 Pod 生命周期管理(创建、监控、销毁)。它监听 API Server 上属于自己的 Pod,通过 CRI 调用容器运行时拉起容器,并上报节点与 Pod 状态;它不管理非本节点创建的静态 Pod 之外的容器

kube-proxy 的 iptables 和 IPVS 模式区别?

  • iptables:基于规则链线性匹配,规则数量随 Service 数量增长而膨胀,适合小规模集群;随机负载均衡。
  • IPVS:基于哈希表,性能高、支持 rr/wrr/lc/sh 等多种负载均衡算法与会话保持,适合大规模集群。
  • 两者都只做四层转发,都从 EndpointSlice 获取后端地址。

一个 Pod 从创建到运行的完整流程?

  1. kubectl 提交 YAML → apiserver 认证、鉴权、准入(Mutating/Validating)→ 写入 etcd。
  2. controller-manager 中的 Deployment/ReplicaSet 控制器发现后创建对应的 Pod 对象。
  3. scheduler 监听到未绑定的 Pod,筛选节点后写入 nodeName
  4. 目标节点的 kubelet watch 到该 Pod,调用 CRI 拉镜像、先跑 Init 容器、再按顺序启动业务容器;调用 CNI 分配 IP、挂载 Volume。
  5. kubelet 上报状态,EndpointSlice 控制器把就绪 Pod 写入 Service 后端,CoreDNS 提供域名解析。

Pod#

Pod 是什么? Kubernetes 最小调度单元,一组容器的集合,共享网络(同一 Network Namespace 与 IP)和存储(Volume),可共享 UTS/IPC。每个 Pod 都有一个 pause 容器(Infra 容器)持有网络命名空间,业务容器加入其中。

为什么 Pod 是 K8s 调度的最小单元? 调度、网络、存储和资源配额都以 Pod 为粒度:

  1. 网络、存储和资源配额:容器只是进程的封装,如果容器需要共享 Network/UTS/IPC 命名空间与 Volume,必须被调度到同一节点,单独调度无法保证共置。
  2. 调度:资源 requests/limits、QoS 等级、亲和性与污点容忍都定义在 Pod 级别(容器级别只是求和)。
  3. 生命周期:Pod 是原子生命周期单位,副本数、滚动更新、扩缩容的计数对象都是 Pod。

Pod 的生命周期状态有哪些?

  • Pending(等待调度/拉镜像)
  • Running(至少一个容器运行中)
  • Succeeded(全部容器成功退出且不会重启)
  • Failed(至少一个容器异常退出且不会重启)
  • Unknown(与节点失联)
  • 容器自身的状态则为 Waiting、Running、Terminated。

Init 容器的作用? 在主容器启动前串行执行、必须成功退出,常用于等待依赖服务就绪、初始化配置、修改数据卷权限;与普通容器不同的还有:不支持探针、不计入 QoS 计算。

Pod 与 Deployment 的区别? Pod 是单个调度单元,生命周期短暂,重启/迁移后 IP 变化;Deployment 通过 ReplicaSet 管理 Pod 副本,提供声明式副本数、滚动更新和回滚。

Pod 健康检查的探针有哪些?

三种探针:

  • Liveness Probe(存活探针,失败则按 restartPolicy 重启容器)
  • Readiness Probe(就绪探针,失败则从 Service 后端摘除、不转发流量)
  • Startup Probe(启动探针,成功前抑制其他探针,适合慢启动应用)

实现方式:exec(执行命令)、httpGettcpSocketgrpc。参数有 initialDelaySeconds、periodSeconds、timeoutSeconds、failureThreshold。

讲一下Pod重启,restartPolicy 有哪些?

  • 重启是重启容器而不是重建 Pod,所以 Pod IP 不变,但重启间隔会指数退避(10s→20s→40s…上限 5min),这就是 CrashLoopBackOff。
  • 重启策略:Always(默认,Deployment 用)、OnFailure、Never(Job 常用)。

Pod 处于 CrashLoopBackOff / ImagePullBackOff 怎么办?

  • CrashLoopBackOff:kubectl logs --previous 看上次崩溃日志,常见原因有配置错误、依赖服务不可用、探针配置过严、OOMKilled(kubectl describe pod 看 Last State)。
  • ImagePullBackOff:镜像名/标签错误、私有仓库缺少 imagePullSecrets、节点网络不通。
  • Pending:资源不足、没有可调度节点、PVC 未绑定。
  • Terminating 卡住:finalizer 未清理或节点失联。

Pod 的 QoS 等级?

  • Guaranteed(所有容器都设了 requests == limits)
  • Burstable(设了部分 requests,不满足 Guaranteed)
  • BestEffort(完全没设)
  • 节点内存不足时按 BestEffort → Burstable → Guaranteed 的顺序驱逐

Service 与网络#

Service 的类型有哪些?

  • ClusterIP(默认,仅集群内访问,虚拟 IP);
  • NodePort(每个节点开放 30000-32767 端口映射);
  • LoadBalancer(调用云厂商 LB,通常是 NodePort 的超集);
  • ExternalName(CNAME/DNS 别名,不转发流量);
  • 另外还有无头服务 Headless Service(clusterIP: None,直接返回 Pod IP,供 StatefulSet 使用)。

Service 的实现原理? Service 只是一组 iptables/IPVS 规则的抽象:apiserver 分配 ClusterIP 后,kube-proxy 监听 Service 与 EndpointSlice 变化并下发规则,把访问 ClusterIP 的流量 DNAT 到某个就绪 Pod 的 IP;CoreDNS 把 svc.namespace.svc.cluster.local 解析为 ClusterIP。三层结构 = DNS 名称 → ClusterIP → Pod IP。

Ingress 是什么?与 Service 的关系? Ingress 提供集群外部到 Service 的 HTTP/HTTPS 路由规则集合(基于 Host/Path 转发、TLS 终止),本身只是一份配置,必须由 Ingress Controller(Nginx Ingress、Traefik、Higress 等)解析并生效。流量路径为:客户端 → Ingress Controller → Service → Pod。Ingress 是七层,Service 是四层。

CNI 是什么?常见实现? Container Network Interface,容器网络插件标准(负责给 Pod 分配 IP、配置路由与网卡)。常见:Flannel(Overlay 网络,VXLAN/host-gw,简单但无 NetworkPolicy)、Calico(BGP 三层网络或 IPIP,性能好且支持 NetworkPolicy)、Cilium(eBPF,性能和可观测性更强)。

K8s 如何实现负载均衡? 分层次实现:

  1. 四层(Service):kube-proxy 通过 iptables/IPVS 把 ClusterIP 的流量随机/轮询转发到后端 Pod,可用 sessionAffinity: ClientIP 做会话保持。
  2. 七层(Ingress / Gateway API):按域名、路径、Header、权重做路由。
  3. 外部入口:LoadBalancer 类型 Service 或云厂商 SLB/Nginx 做最外层负载均衡。
  4. 客户端侧:无头 Service + 客户端自行负载均衡(gRPC 常用)。

Pod 之间如何通信?跨节点呢?

  • 同一 Pod 内通过 localhost;
  • 同节点不同 Pod 通过 CNI 创建的 veth/bridge 通信;
  • 跨节点由 CNI 路由(Flannel VXLAN 封装、Calico BGP 路由)完成,要求满足 K8s 网络模型:每个 Pod 一个 IP,Pod 间可直接通信无需 NAT。

Service 访问不通怎么排查?

  1. kubectl get endpointslices 确认后端是否有就绪 Pod(没有则检查探针/标签选择器)。
  2. kubectl exec 进 Pod 测 nslookupcurl ClusterIP,定位是 DNS 还是转发问题。
  3. 检查 targetPort 与容器实际监听端口是否一致。
  4. 检查 NetworkPolicy 是否拦截流量。

存储#

PV、PVC、StorageClass 的关系?

  • PV(PersistentVolume):集群级存储资源,由管理员静态创建或由 provisioner 动态创建。
  • PVC(PersistentVolumeClaim):用户存储申请(容量、accessMode、storageClassName),绑定到某个 PV。
  • StorageClass:动态存储供给配置,声明 provisioner 与参数(如 reclaimPolicy、磁盘类型),PVC 引用它即可自动创建 PV。

访问模式 accessMode 有哪些?

  • ReadWriteOnce(RWO,单节点读写,最常见)
  • ReadOnlyMany(ROX)
  • ReadWriteMany(RWX,需 NFS/CephFS 等支持)
  • ReadWriteOncePod
  • 回收策略有 Retain / Delete / Recycle

PVC 处于 Pending 状态的可能原因? 没有匹配的 PV(容量 / accessMode / storageClassName / 标签选择器不匹配);StorageClass 不存在或 provisioner 故障;WaitForFirstConsumer 模式下还没有 Pod 使用它。

如何配置持久化存储? 三步:创建 StorageClass(或管理员静态建 PV)→ 创建 PVC 申请 → Pod 通过 volumes 引用 PVC。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs # 或 csi 驱动
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
storageClassName: fast
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: data

emptyDir、hostPath 与 PVC 的区别? emptyDir 生命周期与 Pod 相同(Pod 删除即清空),适合缓存与容器间共享;hostPath 挂载宿主机目录,Pod 漂移后数据仍在但强绑定节点,仅适合特殊场景(日志采集);PVC 才是真正的持久化、与 Pod 解耦的存储。

配置与安全#

ConfigMap 和 Secret 的区别? ConfigMap 存明文非敏感配置;Secret 存敏感信息,值以 base64 编码存储(并非加密),可限制为 type: Opaque 或 dockerconfigjson 等。使用时都可以通过环境变量或 Volume 挂载注入。 注意:base64 是可逆编码不是加密,要真正安全需开启 etcd 静态加密、RBAC 限制读取、或使用外部密钥管理(Vault/KMS)。

更新 ConfigMap/Secret 后 Pod 会立即生效吗? 环境变量方式注入的不会生效,必须重建 Pod(Deployment 可用 kubectl rollout restart);以 Volume 挂载方式的最终会更新(kubelet 周期同步,约 1 分钟),但应用需自行 reload。

RBAC 中 Role 和 ClusterRole 的区别? Role 作用于单个 Namespace;ClusterRole 作用于整个集群(或用于跨 Namespace 复用与集群级资源如 Node、PV)。通过 RoleBinding 绑定 Role/ClusterRole(限定在某 Namespace),通过 ClusterRoleBinding 绑定 ClusterRole(全集群生效)。RBAC 是纯允许模型,没有拒绝规则。

ServiceAccount 的作用? Pod 访问 API Server 时的身份标识,未指定则使用 default。Token 会自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount,配合 RoleBinding 即可实现 Pod 级别最小权限。

Pod 安全限制有哪些手段? SecurityContext(runAsUser、readOnlyRootFilesystem、capabilities、privileged)、Pod Security Admission(baseline/restricted)、NetworkPolicy(网络隔离)、ResourceQuota/LimitRange(资源约束)。

高级资源#

StatefulSet 和 Deployment 的区别?

  • Deployment 用于无状态应用,Pod 完全等价、可随意替换;
  • StatefulSet 用于有状态应用,常用于数据库、消息队列、ZooKeeper 等,提供:
    • 稳定的网络标识(pod-name-0.svc 依赖 Headless Service)
    • 稳定的独立存储(volumeClaimTemplates)
    • 有序的创建/删除/滚动(0→N创建,逆序删除)

DaemonSet 的典型应用场景? 每个(或指定的)节点运行一个 Pod,如日志收集(Fluentd/Filebeat)、节点监控(Node Exporter)、CNI 组件、kube-proxy。新节点加入时会自动部署。

HPA 是什么? Horizontal Pod Autoscaler,基于 CPU/内存或自定义指标自动扩缩容 Pod 副本数。默认每 15s 采集一次指标(依赖 Metrics Server),按 期望副本数 = 当前副本数 × 当前指标 / 目标指标 计算并受 tolerance 与扩缩容冷却时间限制。配套还有 VPA(垂直调资源)与 Cluster Autoscaler(扩节点)。

Job 和 CronJob 的区别? Job 运行一次性任务直到成功(可设 completions/parallelism、backoffLimit);CronJob 按 cron 表达式周期性创建 Job,支持 concurrencyPolicy 与历史保留数。

如何限制 Pod 资源使用? 在 Pod 的 resources 字段定义 requests(调度依据,保证下限)和 limits(运行时上限,超出内存会被 OOMKilled、超出 CPU 会被限流)。命名空间级别可用 LimitRange 设默认值与上下限,用 ResourceQuota 限制总量。

节点亲和性与污点容忍的区别?

  • 亲和性是 Pod 主动选择节点(吸引,支持 requiredDuringScheduling 硬性 与 preferredDuringScheduling 软性、nodeAffinity/podAffinity/podAntiAffinity);
  • 污点容忍是 Pod 被动适应节点(排斥),节点打污点排斥 Pod,Pod 加容忍才能调度上去。污点效果有 NoSchedule、PreferNoSchedule、NoExecute(NoExecute 还会驱逐不容忍的存量 Pod)。

包管理#

Helm#

Helm 是什么? Kubernetes 的包管理器,把一组 YAML 抽象成可参数化、可版本化、可复用的 Chart。三个核心概念:Chart(模板包)、Release(Chart 的一次部署实例)、Repository(Chart 仓库)。

常用命令?

Terminal window
helm repo add bitnami https://charts.bitnami.com/bitnami
helm search repo nginx
helm install my-nginx bitnami/nginx -n web --create-namespace -f values.yaml
helm upgrade my-nginx bitnami/nginx --set replicaCount=3
helm rollback my-nginx 1 # 回滚到指定 revision
helm history my-nginx
helm uninstall my-nginx -n web
helm template ./chart # 本地渲染,不部署

Helm 的目录结构? Chart.yaml(元数据)、values.yaml(默认值)、templates/(Go Template 模板 YAML)、charts/(子 Chart 依赖)。升级/回滚依赖 release 的 revision 记录(存在 Secret 中)。

kustomize#

kustomize 是什么? K8s 原生命令(kubectl apply -k)的配置定制工具。不用模板,而是通过 base + overlay 的叠加(patch)方式复用同一份基础 YAML,适配不同环境。

典型目录结构?

base/
kustomization.yaml # resources: [deployment.yaml, service.yaml]
deployment.yaml
overlays/
dev/kustomization.yaml # resources: [../../base]; replicas/patch 覆盖
prod/kustomization.yaml

kustomize 常用能力? resources 引入基础资源、patchesStrategicMerge/patches 覆盖字段、replicas 改副本数、images 改镜像 tag、namePrefix/commonLabels 统一前缀与标签、configMapGenerator 自动生成配置并触发滚动更新。

Helm 与 kustomize 怎么选? Helm 适合对外分发、需要参数化与版本管理的场景;kustomize 适合内部多环境、以 patch 为主、不想维护模板语法的场景。两者常组合使用(Helm 渲染 base + kustomize 做 overlay patch)。

更新与发布#

什么是滚动更新?如何实现滚动更新与回滚?(命令) 滚动更新(RollingUpdate)是 Deployment 的默认策略:新建一个 ReplicaSet,逐步增加新 Pod 副本、同时减少旧 Pod 副本,过程中始终有可用实例,实现零中断发布。

Terminal window
kubectl set image deploy/app app=nginx:1.25 # 触发更新
kubectl rollout status deploy/app # 观察进度
kubectl rollout history deploy/app # 查看历史版本
kubectl rollout undo deploy/app --to-revision=2 # 回滚
kubectl rollout pause/resume deploy/app # 暂停/继续

滚动更新涉及哪些组件?如何控制? 链路是 Deployment → ReplicaSet → Pod:Deployment 控制器发现 Pod 模板变更后创建新的 ReplicaSet 并扩缩两个 RS 的副本数,kubelet 负责实际起停容器。控制参数在 strategy.rollingUpdate

  • maxSurge:更新过程中最多超出期望副本数的 Pod 数(默认 25%);
  • maxUnavailable:最多不可用的 Pod 数(默认 25%,设为 0 即”先扩后缩”的零中断更新);
  • minReadySeconds:Pod 就绪后多久才认为可用;
  • progressDeadlineSeconds:超时未完成则标记为失败。 滚动更新不丢请求的前提是配置了 Readiness 探针与优雅退出(preStop + terminationGracePeriodSeconds)。

什么是 Recreate 策略? Recreate 是一种用于更新应用的 Deployment 策略。它通过先终止所有旧的 Pod,再创建新的 Pod来完成更新。存在停机时间。适合不能同时运行多个版本的应用(如数据库迁移)。

什么是灰度发布 / 金丝雀发布?如何实现? 灰度(金丝雀)发布指先让一小部分流量进入新版本,观察指标正常后再逐步放量到 100%。实现方式:

  1. 副本比例:新旧两个 Deployment 共用同一个 Service 的标签,靠调节副本数比例分流(最粗糙,比例受 Pod 数限制)。
  2. Ingress 注解:Nginx Ingress 的 nginx.ingress.kubernetes.io/canary: "true" + canary-weight: 10 / canary-by-header 精确切流。
  3. 服务网格:Istio VirtualService 按权重/Header/用户维度切流,粒度最细。
  4. 渐进式交付工具:Argo Rollouts、Flagger,支持自动分析指标并自动回滚。

滚动更新、蓝绿、金丝雀的区别?

  • 滚动更新:逐个替换实例,资源占用小,回滚快,但新旧版本会短暂共存。
  • 蓝绿发布:同时部署完整的新旧两套环境,切流量即完成发布/回滚,需要双倍资源,回滚最快。
  • 金丝雀发布:按比例放量,风险最小,需要完善的监控与流量控制能力。

其他#

K8s 为何要关闭 Swap?

  1. 资源确定性被破坏:K8s 依赖 cgroups 严格限制 Pod 的内存上限(limits)。如果开启 Swap,Pod 写数据可能被换出到磁盘,导致 cgroups 统计的内存使用量不准确,容器无法精准判断自己是否达到内存限制。
  2. 性能不可控:Swap 依赖磁盘 I/O,速度比内存慢几个数量级。一旦发生大量换页,Pod 响应延迟会急剧飙升,且这种抖动毫无预兆,破坏了 Kubernetes 承诺的 服务质量(QoS)
  3. 调度误判:Kubelet 根据节点上的内存容量进行 Pod 调度,如果 Swap 被占用,实际可用内存被稀释,容易产生节点资源枯竭但调度器不知情的情况。

K8s 节点上只有 containerd 而没有 Docker,如何构建镜像? Docker 和 containerd 都是运行时,构建镜像需要单独的构建器:

  • nerdctl + BuildKitnerdctl 是兼容 Docker CLI 的 containerd 客户端,nerdctl build 依赖 buildkitd(需单独部署,buildkitd --oci-worker-no-process-sandbox),也支持 nerdctl compose
  • buildctl + buildkitd:直接用 BuildKit 原生客户端,支持多平台构建与缓存导入导出。
  • 在集群内构建:Kaniko(无需特权,在 Pod 内构建)、Buildpacks、或 Tekton/Argo Workflows 流水线。
  • 生产实践通常是 CI 里用 Docker/BuildKit 构建并推送镜像,节点只负责拉取运行。

K8s 与 Docker 的关系? Docker 是容器技术的早期实现(CLI + daemon + 运行时 + 镜像格式);K8s 是容器编排系统。早期 K8s 通过 dockershim 调用 Docker,1.24 起移除 dockershim,直接使用 CRI 对接 containerd/CRI-O,因此“K8s 弃用 Docker”弃用的是 dockershim 这层适配,镜像(OCI 标准)依然通用。

常用排错命令?

Terminal window
kubectl get pod -A -o wide # 全量 Pod 与所在节点
kubectl describe pod <pod> # 事件、探针、调度失败原因
kubectl logs <pod> -c <container> -f # 日志(--previous 看上次崩溃)
kubectl exec -it <pod> -- sh
kubectl top node / pod # 资源使用(依赖 metrics-server)
kubectl get events --sort-by=.lastTimestamp
kubectl get pod <pod> -o yaml # 看最终生效的 spec
kubectl auth can-i get pods --as=system:serviceaccount:default:default
Kubernetes 八股
https://blog-l7wd3.pages.dev/posts/interview/k8s/
作者
L7WD3-Xiao
发布于
2026-08-21
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取