kubernetes(K8s)学习笔记:第十三期与第十四期核心知识点自测与详解
本自测解析针对 Kubernetes 系列第十三期(集群存储与有状态应用(上篇):动态卷供应——StorageClass + Provisioner)和第十四期(集群存储与有状态应用(下篇):StatefulSet 有状态应用管理)的核心内容。共 10 题,每题包含题目回顾、考查知识点、详细解答与分析,帮助读者巩固 Kubernetes 动态存储与有状态应用管理的核心技能。
文章索引:
Kubernetes(K8s)学习笔记(第十三期):集群存储与有状态应用(上篇):动态卷供应——StorageClass + Provisioner
Kubernetes(K8s)学习笔记(第十四期):集群存储与有状态应用(下篇):StatefulSet 有状态应用管理
更多自我检测系列欢迎浏览:每日知识点小问答
我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~
第十三期:动态卷供应(StorageClass + Provisioner)(第 1-5 题)
题目一:动态卷供应与静态卷供应的核心区别
题目:Kubernetes 中动态卷供应和静态卷供应的核心区别是什么?请从 PV 创建方式、管理员工作量、资源利用率、适用场景四个维度对比。为什么动态卷供应是生产环境推荐的方式?
考查知识点
- 动态卷 vs 静态卷对比 —— 第十三期 §1.1、§5.1
- 两种方式的优缺点
详细解答
核心区别:
| 对比维度 | 静态卷供应 | 动态卷供应 |
|---|---|---|
| PV 创建方式 | 管理员预先手动创建每个 PV | 系统根据 PVC自动创建PV |
| 管理员工作量 | 高(每个 PV 手动指定存储路径、容量) | 低(只需配置 StorageClass) |
| 资源利用率 | 可能浪费(PV 预分配后闲置) | 高效(按需分配,用完回收) |
| 响应速度 | 慢(需等待管理员操作) | 秒级自动创建 |
| 适用场景 | 小规模、固定存储需求 | 大规模、动态存储需求 |
为什么动态卷供应是生产环境推荐方式:
- 自动化:用户只需创建 PVC,系统自动完成 PV 创建和绑定,无需管理员干预
- 高效利用资源:按需分配,避免资源浪费
- 快速响应:秒级完成存储分配,不影响应用部署速度
- 可扩展:支持大规模集群,无需为每个 PVC 手动创建 PV
- 标准化:通过 StorageClass 统一管理存储套餐,降低运维复杂度
题目二:StorageClass 的核心配置字段
题目:StorageClass 的provisioner、reclaimPolicy、volumeBindingMode三个字段分别起什么作用?NFS 存储和本地存储是否有内置的 Provisioner?Local Path Provisioner 的volumeBindingMode应该设置为什么值?为什么?
考查知识点
- StorageClass 核心配置 —— 第十三期 §2
- 各字段含义与适用场景
详细解答
三个核心字段:
| 字段 | 作用 | 可选值 |
|---|---|---|
provisioner | 指定用哪个“造卷工具”创建 PV | rancher.io/local-path、fuseim.pri/ifs等 |
reclaimPolicy | PVC 删除后 PV 的回收策略 | Delete(默认)/Retain |
volumeBindingMode | PVC 与 PV 的绑定时机 | Immediate(默认)/WaitForFirstConsumer |
NFS 和本地存储的内置 Provisioner:
- NFS:❌没有内置 Provisioner,需部署外部组件(如 NFS Provisioner)
- 本地存储:❌没有内置 Provisioner,需部署外部组件(如 Local Path Provisioner)
Local Path Provisioner 的 volumeBindingMode:
- 应设置为
WaitForFirstConsumer - 原因:本地存储绑定到特定节点,需要等 Pod 调度后才能确定在哪个节点创建 PV
- 如果使用
Immediate模式,PV 可能创建在错误的节点上,导致 Pod 无法访问
YAML 示例:
apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:local-pathprovisioner:rancher.io/local-pathreclaimPolicy:DeletevolumeBindingMode:WaitForFirstConsumer# 本地存储必须使用此模式题目三:Local Path Provisioner 的工作原理与局限性
题目:Local Path Provisioner 的工作原理是什么?它使用什么类型的存储?为什么 Local Path Provisioner 不支持 Pod 跨节点调度?请写出其典型使用场景。
考查知识点
- Local Path Provisioner —— 第十三期 §3
- 工作原理与局限性
详细解答
工作原理:
- Local Path Provisioner 在每个节点上使用本地磁盘目录(默认
/opt/local-path-provisioner) - 当用户创建 PVC 时,PVC 处于
Pending状态(volumeBindingMode: WaitForFirstConsumer) - 当 Pod 创建并调度到某个节点后,Provisioner 在该节点上创建对应的存储目录
- 系统自动创建 PV 并与 PVC 绑定
- Pod 使用该 PVC 挂载本地存储
Helper Pod 的工作机制:
- 以
privileged: true权限运行,确保有权限创建目录 - 使用
system-node-critical优先级,不会被驱逐 - 容忍
node.kubernetes.io/disk-pressure污点
为什么不支持 Pod 跨节点调度:
- PV 创建在特定节点的本地磁盘上
- PVC 已经绑定了该节点的 PV
- 其他节点无法访问该节点的本地存储
- 因此,使用该 PVC 的所有 Pod 副本都必须调度到同一个节点
典型使用场景:
- ✅ 测试环境的临时存储
- ✅ 对性能要求高、对数据持久性要求不高的场景
- ✅ 单节点存储(不需要跨节点共享)
- ❌ 不适用于需要跨节点共享数据的生产环境
题目四:NFS Provisioner 的部署流程与优势
题目:请简述 NFS Provisioner 的部署流程(从 NFS 服务端到 StorageClass)。NFS Provisioner 相比 Local Path Provisioner 的核心优势是什么?NFS 的volumeBindingMode应该设置为什么值?
考查知识点
- NFS Provisioner 部署 —— 第十三期 §4
- 两种 Provisioner 对比
详细解答
NFS Provisioner 部署流程:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1. 部署 NFS 服务端 | 安装nfs-kernel-server,创建共享目录,配置/etc/exports | 所有 Worker 节点安装nfs-common |
| 2. 创建命名空间 | kubectl create ns kube-storage | 隔离相关资源 |
| 3. 创建 RBAC 权限 | 创建 ServiceAccount、ClusterRole、ClusterRoleBinding | 赋予 Provisioner 操作 PV/PVC 的权限 |
| 4. 部署 Provisioner 应用 | 创建 Deployment,指定 NFS 服务器地址和共享路径 | 镜像nfs-subdir-external-provisioner |
| 5. 创建 StorageClass | 指定provisioner: fuseim.pri/ifs | 供 PVC 引用 |
核心优势对比:
| 对比项 | Local Path Provisioner | NFS Provisioner |
|---|---|---|
| 存储位置 | 节点本地磁盘 | NFS 服务器 |
| 跨节点共享 | ❌ 不支持 | ✅ 支持(RWX 模式) |
| Pod 跨节点调度 | ❌ 不支持 | ✅ 支持 |
| 绑定模式 | WaitForFirstConsumer | Immediate |
| 适用场景 | 临时存储、单节点 | 共享存储、多节点、生产环境 |
NFS 的volumeBindingMode:
- 应设置为
Immediate(默认值) - 原因:NFS 是共享存储,所有节点都可以访问,不绑定特定节点
- 创建 PVC 时即可立即创建 PV 并绑定,无需等待 Pod 调度
题目五:动态卷供应实验——PV 创建失败排查
题目:使用 Local Path Provisioner 创建 PVC 后,PVC 一直处于Pending状态。请列出可能的原因和排查步骤。如果使用 NFS Provisioner 时 Pod 出现CrashLoopBackOff,可能是什么问题?
考查知识点
- 常见错误排查 —— 第十三期 §5.5
- 排错思路
详细解答
Local Path PVC Pending 的可能原因:
| 原因 | 排查方法 | 解决方法 |
|---|---|---|
| Provisioner 未部署 | kubectl get pods -n local-path-storage | 部署 Provisioner |
| StorageClass 名称不匹配 | 检查 PVC 的storageClassName | 修正为正确的 StorageClass 名称 |
| 节点资源不足 | kubectl describe pod <pod-name> | 检查节点资源或扩容 |
| Pod 未创建 | volumeBindingMode: WaitForFirstConsumer | 创建使用该 PVC 的 Pod |
| Helper Pod 创建失败 | 检查 Helper Pod 日志 | 检查节点权限和磁盘空间 |
排查步骤:
# 1. 检查 PVC 状态和事件kubectl describe pvc<pvc-name># 2. 检查 Provisioner Pod 状态kubectl get pods-nlocal-path-storage# 3. 检查 StorageClasskubectl get sc# 4. 如果使用 Local Path,检查节点目录是否存在ls/opt/local-path-provisioner/NFS Provisioner Pod CrashLoopBackOff 的可能原因:
| 原因 | 排查方法 | 解决方法 |
|---|---|---|
| NFS 服务端未启动 | systemctl status nfs-server | 启动 NFS 服务 |
| NFS 共享路径不存在 | ls /shares/ | 创建共享目录 |
| 网络不通 | ping <NFS-SERVER-IP> | 检查网络连通性 |
| Worker 节点未安装 NFS 客户端 | which mount.nfs | 安装nfs-common |
| NFS 导出配置错误 | cat /etc/exports | 修正配置并exportfs -a |
第十四期:StatefulSet 有状态应用管理(第 6-10 题)
题目六:StatefulSet 的三大核心特性
题目:StatefulSet 的三大核心特性是什么?请分别说明其含义。为什么 StatefulSet 必须关联 Headless Service?
考查知识点
- StatefulSet 核心特性 —— 第十四期 §2
- Headless Service 的作用
详细解答
StatefulSet 三大核心特性:
| 特性 | 含义 |
|---|---|
| 固定身份标识 | 每个 Pod 拥有唯一的序号(从 0 开始递增),hostname 固定为「StatefulSet 名称-序号」,重建后保持不变 |
| 有序操作 | 创建/扩容按0→N-1顺序;缩容/删除按N-1→0逆序;更新按N-1→0逆序滚动 |
| 稳定存储 | 通过PVC 模板为每个 Pod 自动创建独立的 PVC,Pod 重建后自动复用原 PVC,数据不丢失 |
为什么必须关联 Headless Service:
- StatefulSet 需要为每个 Pod 提供固定的 DNS 解析
- Headless Service(
clusterIP: None)不分配 ClusterIP,只负责 DNS 解析 - Pod 的 DNS 记录格式:
<statefulset-name>-<ordinal>.<service-name>.<namespace>.svc.cluster.local - 例如:
nginx-0.nginx.default.svc.cluster.local - 这保证了 Pod 之间可以通过固定的 DNS 名称互相通信
Headless Service 示例:
apiVersion:v1kind:Servicemetadata:name:nginxspec:clusterIP:None# Headless Serviceselector:app:nginxports:-port:80题目七:StatefulSet vs Deployment 对比
题目:请从适用场景、网络、存储、扩缩容、更新策略五个维度对比 StatefulSet 和 Deployment。什么场景下应该使用 StatefulSet 而不是 Deployment?
考查知识点
- StatefulSet vs Deployment —— 第十四期 §3
- 选型依据
详细解答
| 对比维度 | StatefulSet | Deployment |
|---|---|---|
| 适用场景 | 有状态应用(数据库、分布式集群、消息队列) | 无状态应用(Web 服务、API 接口) |
| 网络 | Headless Service(固定 DNS 解析) | ClusterIP/LoadBalancer(共享 IP) |
| 存储 | 必须 PVC + PV(每个 Pod 独立存储) | 可选 PVC(无持久化要求) |
| 扩缩容 | 有序(0→1→2,N-1→0) | 无序(瞬间完成) |
| 更新策略 | 有序更新(逆序) | 滚动更新(无顺序) |
应该使用 StatefulSet 的场景:
| 场景 | 原因 |
|---|---|
| 数据库(MySQL、PostgreSQL) | 需要独立存储,主从身份不能混淆 |
| 分布式中间件(ZooKeeper、etcd) | 节点需要固定网络标识,集群需要按顺序启动 |
| 消息队列(Kafka) | 节点间需要稳定的通信地址 |
| 缓存集群(Redis Cluster) | 需要固定身份和持久化存储 |
典型判断标准:
- 应用实例是否有唯一身份?(如主从、节点编号)
- 应用是否依赖持久化存储?
- 应用启动/关闭是否有顺序要求?
- 如果以上任一答案为“是”,应考虑使用 StatefulSet。
题目八:PVC 模板(volumeClaimTemplates)的工作机制
题目:StatefulSet 中的volumeClaimTemplates是什么?它为每个 Pod 创建的 PVC 命名格式是什么?当 StatefulSet 被删除时,PVC 会自动删除吗?为什么?
考查知识点
- PVC 模板 —— 第十四期 §2.4
- 存储生命周期
详细解答
volumeClaimTemplates的作用:
- 为 StatefulSet 中的每个 Pod 自动创建独立的 PVC
- 每个 Pod 获得专属的存储卷,互不干扰
- 确保 Pod 重建后能复用原有的数据
PVC 命名格式:
<template-name>-<statefulset-name>-<ordinal>示例:
volumeClaimTemplates:-metadata:name:nginx-dataStatefulSet 名称:nginx,副本数:3
创建的 PVC 名称:
nginx-data-nginx-0nginx-data-nginx-1nginx-data-nginx-2
删除 StatefulSet 时 PVC 的行为:
❌ PVC不会自动删除
原因:数据是核心资产,Kubernetes 不会自动删除 PVC,防止数据丢失
如需清理,必须手动删除PVC:
kubectl delete pvc nginx-data-nginx-0 nginx-data-nginx-1 nginx-data-nginx-2如果 PV 的
reclaimPolicy是Delete,删除 PVC 后 PV 和后端存储会被自动清理;如果是Retain,则需管理员手动清理
题目九:StatefulSet 的有序操作与启动依赖
题目:StatefulSet 创建 Pod 时的顺序是什么?为什么需要这种有序操作?在 etcd 集群中,ETCD_INITIAL_CLUSTER环境变量是如何利用 StatefulSet 的固定 DNS 实现集群自动组网的?
考查知识点
- 有序操作 —— 第十四期 §2.3
- etcd 集群组网实验 —— 第十四期 §5
详细解答
创建顺序:
- 从序号 0 开始递增:0 → 1 → 2 → … → N-1
- 前一个 Pod 必须处于Running 和 Ready状态后,才创建下一个
- 每个 Pod 创建间隔约 20~30 秒(由
minReadySeconds控制)
缩容顺序:
- 从最大序号开始递减:N-1 → … → 2 → 1 → 0
- 前一个 Pod 彻底删除后,才删除下一个
为什么需要有序操作:
- 有状态应用通常有启动依赖关系
- 主节点(ordinal=0)必须先启动,初始化集群
- 从节点(ordinal>0)依赖主节点的网络地址加入集群
- 如果无序启动,从节点可能无法找到主节点,集群组网失败
etcd 集群自动组网:
env:-name:ETCD_NAMEvalueFrom:fieldRef:fieldPath:metadata.name# 获取 Pod 名称(etcd-0、etcd-1、etcd-2)-name:ETCD_INITIAL_CLUSTERvalue:"etcd-0=http://etcd-0.etcd.statefulset.svc.cluster.local:2380,etcd-1=http://etcd-1.etcd.statefulset.svc.cluster.local:2380,etcd-2=http://etcd-2.etcd.statefulset.svc.cluster.local:2380"工作原理:
ETCD_NAME通过fieldRef获取 Pod 名称(如etcd-0)ETCD_INITIAL_CLUSTER使用固定的 DNS 名称(StatefulSet 提供的稳定网络标识)- 每个 etcd 节点通过 DNS 名称找到其他节点
- 即使 Pod 重建,DNS 名称不变,集群自动恢复
- 实现了无需手动配置 IP 的自动组网
题目十:StatefulSet 的更新策略与生产环境最佳实践
题目:StatefulSet 支持哪两种更新策略?RollingUpdate策略的默认更新顺序是什么?如果希望只更新序号大于等于特定值的 Pod(金丝雀发布),应该配置什么参数?请写出生产环境中 StatefulSet 的三条最佳实践。
考查知识点
- StatefulSet 更新策略 —— 第十四期 §8
- 生产环境最佳实践 —— 第十四期 §10.6
详细解答
两种更新策略:
| 策略 | 行为 | 适用场景 |
|---|---|---|
| RollingUpdate(默认) | 从最后一个序号开始逆序滚动更新 | 大多数生产场景 |
| OnDelete | 只有手动删除 Pod时才更新 | 需要完全控制更新节奏 |
RollingUpdate 默认顺序:
... → 2 → 1 → 0(逆序)- 从最大的序号开始更新
- 这样可以确保更新过程中集群的最小可用性
金丝雀发布配置:
apiVersion:apps/v1kind:StatefulSetmetadata:name:webspec:updateStrategy:type:RollingUpdaterollingUpdate:partition:2# 只更新序号 >= 2 的 Pod- 序号
< partition的 Pod 保持不变(稳定版) - 序号
>= partition的 Pod 会被更新(金丝雀版) - 验证金丝雀版本稳定后,可将
partition调整为 0 完成全量更新
生产环境最佳实践:
| 实践 | 说明 |
|---|---|
| 使用动态卷供应 | 避免手动创建 PV,使用 StorageClass 自动管理存储,降低运维负担 |
| 设置资源限制 | 为有状态应用配置合理的 CPU/内存请求和限制,避免资源争抢 |
| 定期备份数据 | 有状态应用的数据是关键资产,需定期备份 PV 中的数据 |
| 使用 Retain 回收策略 | 防止误删 PVC 导致数据永久丢失,生产环境强烈建议 |
| 配置 PodDisruptionBudget | 保护有状态应用不被同时驱逐,确保集群高可用 |
| 合理设置副本数 | 生产环境至少 3 节点(满足 etcd/Redis 多数派要求),避免脑裂 |
附:知识点对应总表
| 题号 | 主要考查知识点(对应笔记章节) |
|---|---|
| 1 | 第十三期 §1.1、§5.1 动态卷 vs 静态卷 |
| 2 | 第十三期 §2 StorageClass 核心配置 |
| 3 | 第十三期 §3 Local Path Provisioner |
| 4 | 第十三期 §4 NFS Provisioner |
| 5 | 第十三期 §5.5 常见错误排查 |
| 6 | 第十四期 §2 StatefulSet 核心特性 |
| 7 | 第十四期 §3 StatefulSet vs Deployment |
| 8 | 第十四期 §2.4 PVC 模板 |
| 9 | 第十四期 §2.3 有序操作;§5 etcd 实验 |
| 10 | 第十四期 §8 更新策略;§10.6 生产最佳实践 |
学习建议:对于答错的题目,请回看第十三期或第十四期对应章节,并动手在集群环境中执行相关命令。动态存储供应和有状态应用管理是 Kubernetes 生产环境的核心技能,建议通过实际操作加深理解。