Local Persistent Volume是用来做什么的
可以实现pod在本地的持久化存储, 而不需要依赖远程存储服务来提供持久化 , 即使这个pod再次被调度的时候 , 也能被再次调度到local pv所在的node
出现原因
既然有了hostPath Volume
这种方式 , 为什么还要 再搞一个local PV呢 , 这是因为hostPath Volume这种方式并不适合在线上环境使用 , 原因如下:
- 如果使用hostPath Volume这种方法 , 还得选择节点来调度
- 需要事先创建好目录 , 而且还得注意权限的配置, 比如root用户创建的目录 , 普通用户就用不了了
- 不能指定大小 , 可能 会面临磁盘随时被写满的危险 , 而且没有I/O隔离机制
- statefulset不能使用hostPath Volume , 写好的Helm不能兼容hostPath Volume
Local Persistent Volume使用的场景:
- 分布式数据库存储MongoDB , Cassandra数据库等等, 分布式系统文件GlusterFS , Ceph等等
- 需要在本地磁盘进行大量缓存数据的应用 , 或者是为了加速Pod读取数据
Local Persistent Volume需要注意的地方是什么?
- 一旦节点宕机 , 在上面的数据就会丢失 , 这需要使用Local Persistent Volume的应用要有数据恢复和备份能力
- Local Persistent Volume对应的存储介质, 一定是一块额外挂载在 宿主机的磁盘或者块设备(意思是它不应用是宿主机根目录所使用的主硬盘 , ) 一定要一个PV一个盘 , 而且要提前准备好
例子
先创建本地磁盘对应的pv
1 | apiVersion: v1 |
其中:
local.path
写对应的磁盘路径- 必须指定对应的node , 用
.spec.nodeAffinity
来对应的node .spec.volumeMode
可以是FileSystem(Default)和Block- 确保先运行了StorageClass (即下面写的文件)
再写对于的StorageClass文件
1 | kind: StorageClass |
其中:
- provisioner是kubernetes.io/no-provisioner , 这是因为local pv不支持Dynamic Provisioning, 所以它没有办法在创建出pvc的时候, 自动创建对应pv
- volumeBindingMode是WaitForFirstConsumer , WaitForFirstConsumer即延迟绑定 , 这样可以既可以保证推迟到调度的时候 , 再进行绑定 , 又可以保证调度到指定的pod上 , 其实WaitForFirstConsumer又2种: 一种是WaitForFirstConsumer , 一直是Immediate , 这里必须用延迟绑定模式
再创建一个pvc
1 | kind: PersistentVolumeClaim |
这里需要注意的地方就是storageClassName要写出我们之前自己创建的storageClassName的名字:local-storage
之后应用这个文件 , 使用命令kubectl get pvc
可以看到他的状态是Pending , 这个时候虽然有了匹配的pv , 但是也不会进行绑定 , 依然在等待
之后我们写个pod应用这个pvc
1 | kind: Pod |
这里写的.spec.volumes
里的pvc , 要指定成刚刚我们写好的那个pvc
这样就部署好了一个local pv在pod上 , 这样即可pod没有了 , 再次再重新在这个node上创建, 写入的文件也能持久化的存储在特定位置
如何删除这个pv
一定要按照流程来 , 要不然会删除失败
- 删除使用这个pv的pod
- 从node上移除这个磁盘(按照一个pv一块盘)
- 删除pvc
- 删除pv
local volume static provisioner
如果这个pod不用这个pv了 还得删除, 挺麻烦的 , 官方给出一个static provisioner来管理这些pv
比如我们所有的磁盘都挂载到/mnt/disks目录下
那当static provisioner启动后 , 会通过 DaemonSet 来自动检测每个宿主机上的/mnt/disks目录 . 之后调用kubernetes API , 来为这些目录的每一个挂载 ,根据配置文件里的storageClassName, path, nodeAffinity, and capacity创建一个对应的pv对象来 , 至于说这个static provisioner的各种定义, 比如StorageClass名字, 挂载位置等等 , 都可以通过配置文件指定 , 而且当Pod结束并删除了使用local volume的PVC,它将自动清理该local mount上的所有文件, 然后删除对应的PersistentVolume object
具体的地址: