存储管理3:理解StorageClass
在前面的文章中,我们通过手动方式创建出了所需要的PV。接下来,我们来看一种自动创建PV的方式。
1.1、Static Provisioning & Dynamic Provisioning
在一个大规模的Kubernetes集群中,集群用户可能会创建出成千上万个PVC,这时,集群管理员就需要不停地创建出满足一定条件的PV,否则新Pod就会因为PVC无法绑定PV而运行失败。显然,在实际操作中,完全依靠人工是不实现的。
Kubernetes 为我们提供了一套可以自动创建 PV 的机制,即:Dynamic Provisioning。与之对应的,人工创建 PV 的方式就叫作 Static Provisioning。而Dynamic Provisioning的核心,就在于一个名叫StorageClass的API对象。
1.2、理解StorageClass对象
StorageClass对象是一个用来自动创建PV的模板。具体来说,一个StorageClass对象通常会定义如下两部分内容:
-
创建PV需要用到的存储插件。比如,Ceph等
-
PV的属性。比如,Volume大小等
一旦有了这两个信息,kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass。然后,Kubernetes就会调用该StorageClass声明的存储插件,创建出所需要的PV。
下面我们通过一个示例来实践StorageClass对象的使用。
1.2.1、创建StorageClass对象
在这里,我们通过部署在本地的Kubernetes集群以及Rook存储服务来创建StorageClass对象。定义的内容如下所示:
1 |
|
在这个 YAML 文件中,我们定义了一个名叫 block-service 的 StorageClass。这个 StorageClass 的 provisioner 字段的值是:ceph.rook.io/block,即我们使用的存储插件是Rook。有关定义StorageClass对象的更多信息可参考kubernetes官方文档。
1.2.2、创建PVC
创建好StorageClass对象之后,我们只需要在PVC中指定要使用的StorageClass的名字即可,如下所示:
1 |
|
可以看到,在这个 PVC 对象中添加了一个叫作 storageClassName 的字段,它指定了该 PVC 所要使用的 StorageClass 是:block-service。当我们创建好这个PVC后,它就会和一个由kubernetes自动创建的PV相绑定,如下所示:
1 |
|
1.2.3、查看PV
通过查看这个自动创建出来的 PV 的属性,我们就可以看到它跟我们在 PVC 里声明的存储的属性是一致的,如下所示:
1 |
|
此外,我们还可以看到,这个自动创建出来的 PV 的 StorageClass 字段的值,也是 block-service。这是因为,Kubernetes 只会将 StorageClass 相同的 PVC 和 PV 绑定起来。
1.2.4、小结
在有了 Dynamic Provisioning 后,集群管理员只需要在 Kubernetes 集群里创建出数量有限的 StorageClass 对象就可以了。这就好比,运维人员在 Kubernetes 集群里创建出了各种各样的 PV 模板。后续,当开发人员提交了包含 StorageClassName 字段的 PVC 之后,Kubernetes 就会根据这个 StorageClass 创建出对应的 PV。
在 Kubernetes 的官方文档里已经列出了默认所支持的 Dynamic Provisioning 存储插件。对于不在文档里的插件,比如 NFS,或者其他非内置存储插件,我们其实可以通过kubernetes-incubator/external-storage这个库来自己编写一个外部插件完成这个工作。就如同 Rook一样,因为它内置了 external-storage 的实现,所以 Rook 是完全支持 Dynamic Provisioning 特性的。
需要注意的是,StorageClass 对象并不是专门为了 Dynamic Provisioning 而设计的。比如,在前面的文章中,我们在 PV 和 PVC 里都声明了 storageClassName=manual。而我们的集群里,实际上并没有一个名叫 manual 的 StorageClass 对象。但这完全没有问题,此时 Kubernetes 进行的是 Static Provisioning,但在做绑定决策的时候,它依然会考虑 PV 和 PVC 的 StorageClass 定义。这么做的好处也很明显:这个 PVC 和 PV 的绑定关系,完全在我们自己的掌控之中。
此外,如果集群开启了一个名叫 DefaultStorageClass 的 Admission Plugin,那么它就会为 PVC 和 PV 自动添加一个默认的 StorageClass;否则,PVC 的 storageClassName 的值就是“”,这也意味着它只能够跟 storageClassName 也是“”的 PV 进行绑定。
1.3、小结
根据持久化存储的创建方式,Kubernetes将存储管理抽象成静态供应(Static Provisioning)和动态供应(Dynamic Provisioning)两种类型。其中:
- Static Provisioning是一种手动管理方式,创建PVC的同时需要手动创建相应的PV,适用于较小规模的集群;
- Dynamic Provisioning则是一种动态管理方式,其核心是Storage Class对象。一个Storage Class对象就是一个事先创建好的PV模板,后续一旦有PVC提交,kubernetes就会通过相应Storage Class对象所声明的存储插件创建出满足条件的PV,适用于大规模集群。
1.4、参考
https://time.geekbang.org/column/intro/100015201
https://kubernetes.io/zh/docs/concepts/storage/storage-classes/