1、概述
在前面这章 k8s-持久化存储PV与PVC(1) 中,熟悉了PV/PVC之后,简单回顾:PV 和 PVC 一一对应的,PV 是由运维人员事先负责提前创建好的,在 kubernetes 等待使用;PVC 通常由开发人员创建,假如开发人员想要申请一个为 1 GiB 大小的 PVC,创建完成后会向 kubernetes 申请资源,申请成功会将 PV 与 PVC 进行绑定。
但现在有一个比较棘手的问题,当大规模的 kubernetes 生产集群中,可能会有很多的 PVC,而且随着项目的增加,可能还需要不断创建新的 PV,不然可能为某个新的 Pod 因 PVC 绑定不到 PV 而创建失败。如果还是让运维人员去一个个创建 PV 的话,其实是个非常麻烦的,人工也无法做到,于是 kubernetes 提供可以自动创建 PV 的机制,核心是 StorageClass API对象。
2、如何持久化 Volume
首先,来了解持久化 Volume 的实现,想要持久化 Volume 大多数情况是需要依赖一个远程存储服务的,比如:远程文件存储(如:NFS)、远程块存储(如:公有云提供的远程磁盘)等。而 Kubernetes 需要使用这些存储服务,来为容器准备一个持久化的宿主机目录,以供将来进行绑定挂载时使用。
那么,准备 "持久化" 宿主机目录这个过程,可分为 Attach 和 Mount 两个阶段处理。
Attach 阶段:当一个 Pod 调度到一个 Node 之后,kubelet 会负责把帮这个 Pod 创建它的 Volume 目录。如果 Volume 类型是远程块存储比如:Google Cloud 的 Persistent Disk(GCE 提供的远程磁盘服务),那么 kubelet 就需要先调用 Goolge Cloud 的 API,将它所提供的 Persistent Disk 挂载到 Pod 所在的宿主机上。
Mount 阶段:为了能使用远程磁盘,kubelet 需要进行将这磁盘进行格式化并且挂载到 Volume 宿主机目录的操作。此时,这个 Volume 的宿主机目录就是一个 "持久化" 的目录了,当容器写入内容时,会保存到 Google Cloud 远程磁盘里头。
3、动态供应策略(Dynamic Provisioning)
通过人工创建 PV的方式叫作静态供应策略(Static Provisioning),这种会造成资源浪费。
Dynamic Provisioning 机制工作的核心,在于一个名叫 StorageClass 的 API 对象。而 StorageClass 对象的作用,其实就是创建 PV 的模板。
栗子:假如我们的 Volume 的类型是 GCE 的 Persistent Disk ,运维人员就需要定义一个如下所示的 StorageClass:
yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: block-service-demo
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
- StorageClass 的 provisioner 字段的值是:kubernetes.io/gce-pd,这正是 Kubernetes 内置的 GCE PD 存储插件的名字。
- StorageClass 的 parameters 字段:是 PV 参数。(type=pd-ssd,指的是这个 PV 的类型是"SSD 格式的 GCE 远程磁盘")
开发者,只需要在 PVC 里指定要使用的 StorageClass 名字即可,如下所示:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: block-service-demo
resources:
requests:
storage: 10Gi
可以看到这个 PVC 里添加了一个叫作 storageClassName 的字段,用于指定该 PVC 所要使用的 StorageClass 的名字是:block-service-demo。
上面以 Google Cloud 为例,当开发人员创建好 PVC 对象后,keubernetes 会去调用 Google Cloud 的 API,创建出一块 SSD 格式的 Persistent Disk。
总结
- 首先,集群管理员事先创建一个或多个存储类,并将其中一个标记为默认值;
- 开发者创建存储类的 PVC;
- Kubernetes 会去查找 StorageClass 和其中引用的配置器,并要求配置器根据 PVC 请求的访问模式和存储大小以及 StorageClass 中的参数配置新的 PV;
- 供应商提供实际存储,创建 PV,并将其绑定到 PVC;
- 最终用户创建一个带有卷的pod,通过名称引用 PVC 了;