本文为面试精简版,深入技术细节见 K8s 存储 CSI 系列。
1. PV / PVC / StorageClass 是什么
| 资源 | 角色 |
|---|---|
| PV | 集群中的一块存储(类型、容量、远程存储地址) |
| PVC | Pod 对存储的声明(大小、读写权限) |
| StorageClass | PV 模板(存储插件 + 参数),实现动态供应 |
2. PVC 与 PV 如何绑定
- PV 容量必须满足 PVC 请求
- PV 与 PVC 的 StorageClass 必须一致
3. Volume Controller 的功能
| 控制器 | 功能 |
|---|---|
| PersistentVolumeController | 监听未绑定 PVC,遍历可用 PV 进行绑定 |
| AttachDetachController | 检测 Pod 对应的 PV,执行 Attach / Detach |
| VolumeManagerReconciler | 每个节点独立运行,负责卷的 Mount / Unmount |
4. 容器挂载存储的两阶段处理
| 阶段 | 操作 | 结果 |
|---|---|---|
| Attach | 远程块存储挂载到节点(/dev/sdb) | 设备就绪 |
| Mount | 格式化 + 挂载到宿主机容器目录 | /var/lib/kubelet/pods/<podID>/volumes |
之后 kubelet 通过 CRI 的 Mounts 参数将目录传给容器运行时。
NFS 跳过 Attach 阶段(无"磁盘挂载到虚拟机"的概念)。
5. StorageClass 的意义
手动维护 PV 工作量过大,StorageClass 配合 Dynamic Provisioning 自动创建 PV:
- 充当 PV 模板
- 指定 Provisioner(存储插件)
6. LocalPath 模式如何避免调度冲突
StorageClass 中设置 volumeBindingMode: WaitForFirstConsumer,将 PV/PVC 绑定延迟到 Pod 调度之后。
7. K8S 存储方案演进
| 阶段 | 特点 | 缺点 |
|---|---|---|
| In-Tree Volume Plugin | K8s 核心代码内置 | 新增存储类型需修改 K8s 源码 |
| FlexVolume | 外部二进制插件,实现 Attach/Detach 等接口 | 不支持 Dynamic Provisioning,上下文不可复用 |
| CSI | 存储管理从核心代码剥离为独立组件 | — |
详见 FlexVolume 与 CSI 演进 和 CSI 架构详解。
8. Kubelet 主循环
Kubelet Sync Loop 的设计原则:主控制循环绝对不可以被 block。耗时的 Attach/Mount 操作交由独立的 Controller 和 Goroutine 异步处理。