6.1 持久化存储: PV 和 PVC 的设计与实现原理
Volume Controller
- PersistentVolumeController 绑定 PVC 与 PV
持久化 Volume:

- 持久化 Volume 依赖远程存储服务
将宿主机目录持久化
- 第一阶段
kubelet 默认为 Volume 创建的目录是一个宿主机上的路径:
/var/lib/kubelet/pods/<Pod ID>/volumes/kubernetes.io~<Volume Type>/<Volume Name>
根据 Volume 类型再进行下一步:
- 如果是远程块存储 (如 GCE), 那么 kuberlet 就调用 Google Cloud 的 API, 将 Persistent Disk 挂载到宿主机上
- 相当于执行:
$ gcloud compute instances attach-disk <虚拟机名字> --disk <远程磁盘名字>
- 第二阶段
kubelet 格式化这个磁盘, 然后挂载到宿主机的挂载点上.
- 相当于执行:

挂载不是 mount 命令吗?
如果使用 NFS, 那么只有第二阶段:

- 第一阶段依靠 AttachDetachController
- 第二阶段依靠 VolumeManagerReconciler
StorageClass
自动创建 PV 机制: Dynamic Provisioning
- 人工管理 PV: Static Provisioning
StorageClass 是API 对象, 作用是创建 PV 的模板:
- PV 属性, 存储类型, Volume 大小等
- 存储插件, 如 Ceph
Kubernetes 根据用户提交的PVC找到一个对应的StorageClass。然后’Kubemetes就会调用该StorageClass声明的存储插件’创建出需要的PV°
StorageClass 定义:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: block-service
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
使用 Rook 存储服务:

在 PVC 中指定要使用的 StorageClass:


小结


6.2 深入理解本地持久化数据卷
Local PV, 适用场景有限.
难点一: 如何抽象本地磁盘为 PV
- 一个磁盘一个 PV
难点二: 如何保证 Pod 正确被调度到 Local PV 所在节点
- 调度器需要知道所有节点于 Local PV 的对应关系
- VolumeBindingChecker

- 如果 Pod 想要使用 这个 PV, 就必须在 node-1 上运行
创建 PVC 使用的 StorageClass:
- no-provisioner: Local PV 不支持 Dynamic Provisioning
- WaitForFirstConsumer: 延迟绑定, 避免 PV 与具体磁盘在调度 Pod 之前绑定, 防止亲和性冲突

定义一个 PVC:

定义 Pod:

删除 PV 流程步骤:

Static Provisioner: 自动创建/删除 PV
