我们可以通过hostPath或者emptyDir的方式来持久化数据。但这两种存储方式都是很大局限性的。我们希望容器在重建以后,依然能正确使用之前保存的数据。Kubernetes引入了PV和PVC两个重要的资源来实现对存储的管理。
PV
PersistentVolume,持久化卷,是对底层共享存储的一种抽象。底层共享的实现,可以是Ceph, GlusterFS, NFS等。
我们在CentOS上搭建NFS服务讲了如何搭建NFS服务。PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略等关键信息。
现在新建一个PV资源对象,使用NFS类型的存储,1G空间,访问模式为ReadWriteOnce,回收策略为Recycle,yaml文件pv1-demo.yaml
内容如下:
1 | apiVersion: v1 |
应用一下
1 | kubectl apply -f pv1-demo.yaml |
查看刚才创建的结果
1 | kubectl get pv |
Status状态为Available,表示pv1已经就绪,可以被PVC申请了。
这里讲一下PV的几个属性
STATUS
一个 PV 的生命周期中,可能会处于4中不同的阶段:
- Available(可用):表示可用状态,还未被任何 PVC 绑定
- Bound(已绑定):表示 PVC 已经被 PVC 绑定
- Released(已释放):PVC 被删除,但是资源还未被集群重新声明
- Failed(失败): 表示该 PV 的自动回收失败
CAPACITY
目前只有空间大小,pv1的空间为1G,以后可能会加入IOPS,吞吐量等指标。
ACCESS MODES
AccessModes是用来对PV进行访问模式的设置。
- ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
- ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
- ReadWriteMany(RWX):读写权限,可以被多个节点挂载
RECLAIM POLICY
回收策略
- Retain(保留)- 保留数据,需要管理员手工清理数据
- Recycle(回收)- 清除PV中的数据,效果相当于执行 rm -rf /thevoluem/*
- Delete(删除)- 与PV相连的后端存储完成volume的删除操作
生产上一般使用Retain策略。
PVC
PersistentVolumeClaim,持久化卷声明。如果说Pod消耗的是Node资源的话,PVC则是消耗的PV资源,Pod可以请求CPU和内存,而PVC可以请求特定的存储空间和访问模式。
我们新建一个PVC,请求1G的空间,pvc-nfs.yaml
内容如下:
1 | kind: PersistentVolumeClaim |
这里需要注册的是,PV是没有namespace的,而PVC是有namespace的。
1 | kubectl apply -f pvc-nfs.yaml |
PVC已经是Bound
状态了。我们再查看一个PV的状态,发现也是Bound
状态了。对应的声明是default/pvc-nfs
,就是default
命名空间下面的pvc-nfs
。
1 | kubectl get pv |
这里可能觉得奇怪,我们并没有在 yaml 文件里面指定 PVC 和 PV 的关系,他们怎么可能绑定到一起呢?其实这是系统自动帮我们去匹配的,他会根据我们的声明要求去查找处于 Available 状态的 PV,如果没有找到的话那么我们的 PVC 就会一直处于 Pending 状态,找到了的话当然就会把当前的 PVC 和目标 PV 进行绑定,这个时候状态就会变成 Bound 状态了。
如果使用PVC,可以参考Grafana安装及持久化