PV、PVC、StorageClass 概览
为何如此设计
- 解耦对存储的使用与维护
- 拓展不同的存储需求
定义
PV 描述的是持久化存储数据卷。这个 API 对象主要定义的是⼀个持久化存储在宿主机上的⽬录,⽐如⼀个 NFS 的挂载⽬录。通常情况下,PV 对象是由运维⼈员事先创建在 Kubernetes 集群⾥待⽤的。_类似于接口的具体实现,干活的打工人。
PVC 描述的是 Pod 所希望使⽤的持久化存储的属性。PVC 对象通常由开发⼈员创建;或者以 PVC 模板的⽅式成为 StatefulSet 的⼀部分,然后由 StatefulSet 控制器负责创建带编号的 PVC。类似于接口,不提供具体实现_。
PV与PVC匹配绑定
规则
- 两者的 spec 字段匹配
- 两者的 storageClassName 字段必须相同
过程
通过 operator 机制,为每个未处于 Bound 状态的 PVC,遍历所有可用的 PV,来匹配到合适的 PV。
结果
在 PVC 的 spec.volumeName 字段上填写上 PV 的名称
两阶段处理
- Attach 调用存储系统的 API 将存储挂载到 Pod 将要调度到的 Node 上;
由 AttachDetachController 管理。它不断地检查每⼀个 Pod 对应的 PV,和 这个 Pod 所在宿主机之间挂载情况。从⽽决定,是否需要对这个 PV 进⾏ Attach(或者 Dettach)操作。
作为⼀个 Kubernetes 内置的控制器,Volume Controller ⾃然是 kube-controller-manager 的⼀部分。所以,AttachDetachController 也⼀定是运⾏在 Master 节点上的。当然,Attach 操作只需要调⽤公有云或者具体存储项⽬的 API,并不需要在具体的宿主机上执⾏操作。
- Mount
- 格式化存储设备
- 绑定挂载到 Pod 中
由 VolumeManagerReconciler 管理。它必须发⽣在 Pod 对应的宿主机上,所以必须是 kubelet 组件的⼀部分。它运⾏起来之后,是⼀个独⽴于 kubelet 主循环的 Goroutine(不堵塞 kubelet 主控循环)。
PV 管理方式
- Static Provisioning
创建 PVC 之后,由运维人员手动创建 PV 的方式
- Dynamic Provisioning
创建 PVC 时指定 StorageClass,由 StorageClass 中指定的 provisioner 来创建对应的 PV。
StorageClass
当 PVC 中指定的 StorageClass 存在时,调用对应的 provisioner 来创建 PV;否则去匹配带有相同 StorageClass 的 PV。
如果 PVC 中未指定 StorageClass,当集群已经开启了名叫 DefaultStorageClass 的 Admission Plugin时,它就会为 PVC 和 PV ⾃动添加⼀个默认的 StorageClass;否则,PVC 的 storageClassName 的值就是“”,这也意味着它只能够跟 storageClassName 也是“”的 PV 进⾏绑定。
本地持久化卷的实现
延迟绑定:当使用本地存储后,需要延迟 PV 与 PVC 之间的绑定时机到 Pod 调度时,避免出现 PV 与 Pod 不在同一节点上面的问题。
1 | kind: StorageClass |
PV、PVC、StorageClass 概览