Kubernetes指南:容器持久化存储
持久化Volume
持久化Volume的实现,往往依赖于一个远程存储服务, 比如:远程文件存储(比如NFS、GlusterFS)、远程块存储(比如公有云提供的远程磁盘)等等;
hostPath和emptyDir类型的Volume并不具备持久化Volume的特性: 它们既有可能被kubelet清理掉,也不能被“迁移”到其他节点上;
PV、PVC、StorageClass
PVC可以理解为持久化存储的“接口”,它提供了对某种持久化存储的描述,但不提供具体的实现; 而这个持久化存储的实现部分则由PV负责完成;
作为应用开发者,只需要跟PVC这个“接口”打交道, 而不必关心具体的实现是NFS还是Ceph;
PV
PV描述的,是持久化存储数据卷;
这个API对象主要定义的是一个持久化存储在宿主机上的目录,比如一个NFS的挂载目录;
通常情况下,PV对象是由运维人员事先创建在Kubernetes集群里待用的;
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.244.1.4
path: "/"
PVC
PVC描述的,则是Pod所希望使用的持久化存储的属性;
比如,Volume存储的大小、可读写权限等等;
PVC对象通常由开发人员创建;或者以PVC模板的方式成为StatefulSet的一部分,然后由StatefulSet控制器负责创建带编号的PVC;
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
在成功地将 PVC 和 PV 进行绑定之后,Pod 就能够像使用 hostPath 等常规类型的 Volume 一样, 在自己的YAML文件里声明使用这个 PVC 了:
apiVersion: v1
kind: Pod
metadata:
labels:
role: web-frontend
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
Pod需要做的,就是在volumes字段里声明自己要使用的 PVC 名字; 接下来,等这个Pod创建之后,kubelet就会把这个PVC所对应的PV, 也就是一个NFS类型的Volume,挂载在这个Pod容器内的目录上;
总结
PVC:描述的是Pod想要使用的持久化存储的属性,比如存储的大小、读写权限等;
PV:描述的则是一个具体的Volume的属性,比如Volume的类型、挂载目录、远程存储服务器地址等;
StorageClass的作用,则是充当PV的模板。并且,只有同属于一个StorageClass的PV和PVC,才可以绑定在一起;
设计思想
“不能用”、“不好用”、“需要定制开发”,落地开源基础设施项目的三大常态;
在持久化存储领域,用户呼声最高的定制化需求就是支持“本地”持久化存储; 用户希望Kubernetes能够直接使用宿主机上的本地磁盘目录, 而不依赖于远程存储服务,来提供“持久化”的容器Volume;
refs
https://time.geekbang.org/column/article/42698