Kubernetes 面试题精选
生成时间:2026-06-06 20:57 | 共 10 题
1. 请描述 Kubernetes 的 Master 节点和 Worker 节点各自的核心组件及其职责
难度: ⭐
标准答案:
Master 节点(控制平面)核心组件:
- kube-apiserver:集群的统一入口,所有操作都通过 REST API 经由 apiserver 处理,是唯一与 etcd 通信的组件。
- etcd:分布式键值存储,持久化集群所有状态数据(资源对象、配置等),建议奇数节点部署。
- kube-scheduler:负责 Pod 调度决策,根据资源需求、亲和性、污点等策略将 Pod 分配到合适的 Node。
- kube-controller-manager:运行各种控制器(Deployment Controller、ReplicaSet Controller、Node Controller 等),通过控制循环将集群实际状态推向期望状态。
Worker 节点核心组件:
- kubelet:每个 Node 上的代理,负责 Pod 的生命周期管理(创建、启动、监控、销毁),向 apiserver 汇报节点和 Pod 状态。
- kube-proxy:维护节点上的网络规则(iptables/IPVS),实现 Service 的负载均衡和流量转发。
- 容器运行时(Container Runtime):如 containerd、CRI-O,负责实际拉取镜像和运行容器。
延伸思考: 如果 kube-apiserver 宕机,已运行的 Pod 会受影响吗?——不会立即受影响,kubelet 和 kube-proxy 有本地缓存,已有 Pod 继续运行;但无法创建/删除/更新资源,控制器也无法进行协调。
2. Pod 的完整生命周期包含哪些阶段?Init Container 和 Sidecar 分别在什么场景下使用?
难度: ⭐⭐
标准答案:
Pod 生命周期阶段(pod.status.phase):
- Pending:Pod 已被接受但容器尚未启动(正在拉取镜像、调度等)。
- Running:Pod 已绑定到节点,至少一个容器正在运行或正在启动/重启。
- Succeeded:所有容器成功执行并终止,不会重启。
- Failed:所有容器已终止,至少一个容器以非零状态退出。
- Unknown:无法获取 Pod 状态(通常是与 Node 通信失败)。
此外还有 CrashLoopBackOff(非 phase,而是 reason):容器反复崩溃退出。
Init Container:
- 在主容器启动前按顺序逐一运行,必须全部成功完成后主容器才启动。
- 适用场景:等待依赖服务就绪、数据库迁移、配置文件预处理、权限初始化。
- 与主容器共享 Volume 但不共享网络命名空间(Init 阶段独占)。
Sidecar(1.28+ 原生 Sidecar):
- 与主容器同时运行在同一 Pod 中,共享网络和存储命名空间。
- 适用场景:日志收集(如 Fluentd sidecar)、代理/网关(如 Istio Envoy)、监控 Agent。
- K8s 1.28 引入
initContainers中的restartPolicy: Always来定义原生 Sidecar,确保在主容器之前启动、之后终止。
延伸思考: Init Container 失败后 Pod 会怎样?——若 restartPolicy: Always 或 OnFailure,Pod 会重试 Init Container;若 restartPolicy: Never,Pod 状态变为 Failed。多个 Init Container 串行执行,前一个失败则后续不会执行。
3. Deployment、StatefulSet、DaemonSet 三者的核心区别是什么?分别在什么场景下选用?
难度: ⭐⭐
标准答案:
| 特性 | Deployment | StatefulSet | DaemonSet |
|---|---|---|---|
| Pod 标识 | 随机名称,可互换 | 有序编号(sts-0, sts-1),稳定持久 | 每个 Node 最多一个 |
| 存储 | 共享 PVC 或无状态 | 每个 Pod 独立 PVC,持久绑定 | 通常用 HostPath 或本地存储 |
| 扩缩容 | 随机顺序 | 有序(扩从 0→N,缩从 N→0) | 随 Node 数量自动增减 |
| 更新策略 | RollingUpdate/Recreate | RollingUpdate/OnDelete | RollingUpdate/OnDelete |
| 网络标识 | 无稳定 DNS | 每个 Pod 有稳定 DNS(headless Service) | 无 |
选用场景:
- Deployment:无状态应用(Web 服务、API、微服务),实例间无差异,可随意替换。
- StatefulSet:有状态应用(MySQL 主从、ZooKeeper、Kafka、Elasticsearch),需要稳定网络标识、持久存储、有序部署和终止。
- DaemonSet:每个节点必须运行一个副本(日志采集 Fluentd、监控 Node Exporter、网络插件 Calico/Flannel、存储代理)。
延伸思考: StatefulSet 的 Pod 重建后,它的 PVC 和网络标识会变吗?——不会。StatefulSet 保证 Pod 的有序名称和 DNS 记录稳定,PVC 与 Pod 绑定关系持久化在 etcd 中,Pod 重建后自动重新挂载原 PVC。这是 StatefulSet 最核心的价值。
4. Kubernetes 中 Service 有哪几种类型?ClusterIP、NodePort、LoadBalancer、ExternalName 分别的流量路径是什么?
难度: ⭐⭐
标准答案:
四种 Service 类型:
ClusterIP(默认):
- 分配一个集群内部虚拟 IP,仅在集群内可达。
- 流量路径:Client → ClusterIP → kube-proxy(iptables/IPVS) → Pod。
- 适用:集群内部通信(微服务间调用)。
NodePort:
- 在 ClusterIP 基础上,在每个 Node 上开放一个端口(默认范围 30000-32767)。
- 流量路径:Client → NodeIP:NodePort → kube-proxy → Pod。
- 适用:开发测试环境、需要从集群外部访问但无 LB 的场景。
LoadBalancer:
- 在 NodePort 基础上,调用云厂商 API 创建外部负载均衡器(AWS ELB、GCP LB 等)。
- 流量路径:Client → Cloud LB → NodeIP:NodePort → kube-proxy → Pod。
- 适用:生产环境对外暴露服务(云环境)。
ExternalName:
- 不代理流量,仅返回 CNAME 记录,将 Service 映射到外部 DNS 名称。
- 流量路径:Client → DNS 查询返回 CNAME → 直接连外部地址(不经过 kube-proxy)。
- 适用:集群内引用外部服务(如外部数据库
db.example.com)。
服务发现机制:
- DNS:CoreDNS 为每个 Service 创建
<svc>.<ns>.svc.cluster.local记录。 - 环境变量:Pod 启动时注入同命名空间 Service 的 IP 和端口(仅启动时已存在的 Service)。
延伸思考: 为什么生产环境一般不直接用 NodePort?——NodePort 端口范围受限、暴露所有 Node IP 存在安全风险、没有健康检查和自动故障转移能力,且客户端需自行处理负载均衡。LoadBalancer + Ingress 是更推荐的方式。
5. Ingress 和 Ingress Controller 的关系是什么?Nginx Ingress Controller 的工作原理是怎样的?
难度: ⭐⭐
标准答案:
关系:
- Ingress:是一个 API 资源对象,定义了路由规则(域名/路径 → Service 的映射),但本身不具备流量处理能力。
- Ingress Controller:是实际运行的反向代理程序(如 Nginx、Traefik、Kong),监听 Ingress 资源的变化,动态生成代理配置并处理流量。
- 类比:Ingress 是"配置文件",Ingress Controller 是"执行引擎",两者缺一不可。
Nginx Ingress Controller 工作原理:
- 以 DaemonSet 或 Deployment 部署,前端通过 Service(LoadBalancer/NodePort)接收外部流量。
- Controller 通过 Informer 机制 Watch 集群中的 Ingress、Service、Endpoint、Secret 资源变化。
- 检测到变化后,根据 Ingress 规则生成 Nginx 配置文件(
nginx.conf),写入/etc/nginx/nginx.conf。 - 执行
nginx -s reload使新配置生效(Lua 动态配置模式下可避免 reload)。 - 外部请求到达 → Nginx 根据 server_name 和 location 匹配 → 转发到对应 Service 的 Endpoint Pod。
关键特性:
- TLS 终止:Ingress 配置
tls字段,Nginx 自动加载 Secret 中的证书处理 HTTPS。 - 路径重写:通过
nginx.ingress.kubernetes.io/rewrite-target注解实现。 - 限流/认证:通过注解配置 rate-limiting、basic-auth 等。
延伸思考: Nginx Ingress Controller 每次配置变更都会 nginx -s reload,高频率变更时会有什么问题?——reload 会断开长连接(WebSocket 受影响),且会产生短暂的 QPS 抖动。OpenResty/Lua 动态配置模式可以避免 reload,通过共享字典在运行时更新 upstream。
6. ConfigMap 和 Secret 的区别和使用场景是什么?Secret 的安全性如何保障?
难度: ⭐⭐
标准答案:
核心区别:
| 特性 | ConfigMap | Secret |
|---|---|---|
| 用途 | 非敏感配置数据 | 敏感数据(密码、证书、Token) |
| 存储方式 | 明文存储在 etcd | Base64 编码存储在 etcd |
| 大小限制 | 1 MiB | 1 MiB |
| 使用方式 | 环境变量、Volume 挂载、命令行参数 | 环境变量、Volume 挂载、ImagePullSecrets |
使用方式(两者通用):
- 环境变量:
valueFrom.configMapKeyRef/valueFrom.secretKeyRef - Volume 挂载:将 Key 映射为文件,挂载到 Pod 内指定路径
- 命令行参数:通过
$(VAR_NAME)引用环境变量
Secret 安全性保障措施:
- etcd 加密:启用
EncryptionConfiguration,对 etcd 中的 Secret 数据加密存储(推荐aescbc或aesgcm)。 - RBAC:通过 Role/RoleBinding 限制对 Secret 的读写权限。
- 最小权限:Pod 只挂载需要的 Secret,避免全量暴露。
- 外部密钥管理:集成 Vault、AWS Secrets Manager、Azure Key Vault 等外部 KMS。
- 审计日志:启用 API 审计,记录 Secret 的访问行为。
- 网络策略:限制能访问 etcd 的网络范围。
重要提醒: Base64 不是加密!默认情况下 Secret 只做了 Base64 编码,任何有 etcd 访问权限的人都能解码。必须启用加密配置才能真正保护数据。
延伸思考: 使用环境变量注入 Secret 和 Volume 挂载哪种更安全?——Volume 挂载更安全。环境变量会出现在进程信息(/proc/PID/environ)、Pod 描述(kubectl describe pod)、日志中;Volume 挂载为 tmpfs 文件,仅容器内可访问,且支持自动更新(环境变量不会自动更新)。
7. PV、PVC、StorageClass 三者的关系是什么?动态供给的完整流程是怎样的?
难度: ⭐⭐⭐
标准答案:
三者关系:
- PV(PersistentVolume):集群级存储资源,由管理员预先创建或由 StorageClass 动态创建,是存储的后端抽象。
- PVC(PersistentVolumeClaim):命名空间级的存储请求,声明需要的存储大小、访问模式等,是用户对存储的前端抽象。
- StorageClass:存储类模板,定义存储类型(SSD/HDD)、供给器(Provisioner)、回收策略、参数等,用于动态创建 PV。
绑定关系:PVC 根据 storageClassName、accessModes、resources 匹配 PV,一对一绑定。
动态供给完整流程:
- 管理员创建 StorageClass,指定 Provisioner(如
kubernetes.io/aws-ebs、disk.csi.azure.com)和参数。 - 用户创建 PVC,指定
storageClassName指向该 StorageClass。 - PVC 控制器检测到无可绑定的 PV,调用 StorageClass 的 Provisioner。
- Provisioner 调用云厂商 API 或存储后端 API 创建实际存储卷。
- 自动创建对应的 PV 对象,状态为 Available。
- PVC 控制器将 PV 与 PVC 绑定,两者状态均变为 Bound。
- Pod 通过 PVC 引用该存储卷,kubelet 挂载到容器内。
访问模式(accessModes):
ReadWriteOnce(RWO):单节点读写(最常用)ReadOnlyMany(ROX):多节点只读ReadWriteMany(RWX):多节点读写(需 NFS/CephFS 等共享存储支持)
回收策略(reclaimPolicy):
Retain:删除 PVC 后 PV 保留,需手动清理Delete:删除 PVC 后自动删除 PV 和底层存储Recycle(已废弃):执行rm -rf后重新可用
延伸思考: PVC 绑定 PV 后扩容怎么做?——1)StorageClass 设置 allowVolumeExpansion: true;2)修改 PVC 的 resources.requests.storage;3)对于块存储,Pod 需要重启以识别扩容后的卷;文件存储(如 EFS)可在线扩容无需重启。注意:缩容不支持。
8. HPA 和 VPA 的区别是什么?HPA 基于自定义指标伸缩的配置要点有哪些?
难度: ⭐⭐⭐
标准答案:
HPA(Horizontal Pod Autoscaler)vs VPA(Vertical Pod Autoscaler):
| 特性 | HPA | VPA |
|---|---|---|
| 伸缩方向 | 水平(增减 Pod 数量) | 垂直(调整 Pod 的 CPU/内存请求) |
| 适用场景 | 无状态应用、Web 服务、API | 资源配置不合理需要优化 |
| 实时性 | 实时响应指标变化 | 建议模式(Updater 重启 Pod 生效) |
| 与 PDB 兼容 | 兼容 | 重启 Pod 可能与 PDB 冲突 |
| 生产就绪 | GA,稳定 | 某些模式仍在 Beta |
HPA 基于自定义指标伸缩配置要点:
部署 Metrics Pipeline:
- CPU/内存:
metrics-server - 自定义指标:
Prometheus Adapter(将 Prometheus 指标暴露给 Metrics API)
- CPU/内存:
HPA 配置示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
- type: Object
object:
metric:
name: requests_total
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: my-ingress
target:
type: Value
value: "10k"
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15- 关键配置要点:
behavior.scaleDown.stabilizationWindowSeconds:缩容冷却期,防止抖动。behavior.scaleUp.policies:控制扩容速率,避免过快扩容浪费资源。- 自定义指标需在 Prometheus Adapter 的
rules中配置映射。 - 确保 Metrics API 已注册:
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1
延伸思考: HPA 和 VPA 能同时使用吗?——不推荐同时作用于同一资源指标(如 CPU)。若 HPA 基于 CPU 扩缩容,VPA 也调整 CPU 请求,两者会产生冲突。推荐做法:HPA 基于自定义指标(QPS、队列深度),VPA 仅在建议模式下运行提供资源优化建议,不自动调整。
9. Kubernetes 调度策略中 nodeSelector、nodeAffinity、taint/toleration 的区别和使用场景是什么?
难度: ⭐⭐⭐
标准答案:
nodeSelector:
- 最简单的调度约束,通过标签精确匹配节点。
- 用法:Pod 中指定
nodeSelector: { disktype: ssd },调度器只选择带该标签的节点。 - 限制:只能"必须匹配",不支持"优先匹配"或"排斥"逻辑。
nodeAffinity:
- nodeSelector 的增强版,支持更丰富的表达式。
- requiredDuringSchedulingIgnoredDuringExecution:硬性要求,必须满足才调度(类似 nodeSelector)。
- preferredDuringSchedulingIgnoredDuringExecution:软性偏好,优先调度到满足条件的节点,不满足也可以。
- 支持
In、NotIn、Exists、DoesNotExist、Gt、Lt运算符。
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values: ["us-east-1a", "us-east-1b"]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: node-type
operator: In
values: ["high-mem"]taint / toleration:
- Taint 打在 Node 上:标记节点"排斥"某些 Pod(如
key=value:NoSchedule)。 - Toleration 打在 Pod 上:声明 Pod 可以"容忍"哪些 Taint。
- 三种效果:
NoSchedule:不调度新 Pod(已运行的不受影响)PreferNoSchedule:尽量不调度(软性)NoExecute:不调度且驱逐已运行的 Pod
# Node 上打 Taint
kubectl taint nodes node1 dedicated=gpu:NoSchedule
# Pod 上配置 Toleration
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"场景对比:
- nodeSelector/nodeAffinity:Pod 主动选择 Node("我想去哪")——如调度到 GPU 节点、特定可用区。
- taint/toleration:Node 主动排斥 Pod("谁能来")——如专用节点(GPU 节点只跑 GPU 任务)、问题节点隔离。
延伸思考: 如果一个节点被打了 NoExecute 的 Taint,已有 Pod 会被立即驱逐吗?——不会立即驱逐。Pod 的 Toleration 中可以配置 tolerationSeconds,表示能容忍多长时间后再被驱逐。这为节点维护场景提供了优雅缓冲期。
10. Pod 的安全上下文(Security Context)如何配置?PSP/SCC 的作用和替代方案是什么?
难度: ⭐⭐⭐
标准答案:
Pod 安全上下文(SecurityContext)配置:
分为 Pod 级别和容器级别,容器级别覆盖 Pod 级别:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext: # Pod 级别
runAsNonRoot: true # 禁止以 root 运行
runAsUser: 1000 # 以 UID 1000 运行
runAsGroup: 3000 # 以 GID 3000 运行
fsGroup: 2000 # 挂载卷的文件系统 GID
seccompProfile:
type: RuntimeDefault # 使用运行时默认 seccomp 配置
containers:
- name: app
image: myapp
securityContext: # 容器级别
allowPrivilegeEscalation: false # 禁止权限提升
readOnlyRootFilesystem: true # 只读根文件系统
capabilities:
drop: ["ALL"] # 丢弃所有 Linux capabilities
add: ["NET_BIND_SERVICE"] # 仅保留必要的PSP(PodSecurityPolicy)/ SCC(SecurityContextConstraints):
- PSP:K8s 内置的集群级准入控制器,定义 Pod 必须满足的安全约束(如禁止特权容器、限制挂载类型等)。已在 K8s 1.21 弃用,1.25 移除。
- SCC:OpenShift 特有的安全约束,功能类似 PSP 但更细粒度,控制 SELinux 上下文、用户 ID 范围等。
PSP 替代方案(K8s 1.25+):
Pod Security Standards(PSS)+ Pod Security Admission(PSA):
- K8s 官方替代方案,内置三种安全级别:
- Privileged:无限制(系统/基础设施组件)
- Baseline:最小限制,阻止已知提权(普通应用)
- Restricted:严格限制,最佳实践(安全敏感应用)
- 在命名空间级别通过标签配置:yaml
apiVersion: v1 kind: Namespace metadata: name: my-namespace labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/warn: restricted
- K8s 官方替代方案,内置三种安全级别:
OPA/Gatekeeper:更灵活的策略引擎,可自定义复杂规则。
Kyverno:策略即代码,支持 mutate 和 validate 两种模式,比 OPA 更易上手。
延伸思考: PSA 的 enforce、audit、warn 三种模式有什么区别?——enforce 会直接拒绝违规 Pod;audit 在审计日志中记录违规但不阻止;warn 向用户发出警告但不阻止。推荐渐进式上线:先 warn → audit → enforce。
附:运维排障速查
| 场景 | 命令 |
|---|---|
| Pod 异常 | kubectl describe pod <name> 查看 Events |
| 容器日志 | kubectl logs <pod> [-c container] [--previous] |
| 集群事件 | kubectl get events --sort-by='.lastTimestamp' |
| 节点状态 | kubectl describe node <name> 查看 Conditions |
| 资源使用 | kubectl top pods/nodes(需 metrics-server) |
| 网络调试 | kubectl run debug --image=busybox -it --rm -- sh |
| API 资源 | kubectl api-resources 查看所有资源类型 |
| 集群诊断 | kubectl get componentstatuses |
本文档覆盖 K8s 架构、Pod 生命周期、工作负载、服务发现、Ingress、配置管理、存储、自动伸缩、调度策略、安全上下文等核心考点,适合中高级面试准备。