感谢作者,原文链接:https://haojianxun.github.io/2019/01/10/kubernetes%E7%9A%84%E6%9C%AC%E5%9C%B0%E6%8C%81%E4%B9%85%E5%8C%96%E5%AD%98%E5%82%A8--Local%20Persistent%20Volume%E8%A7%A3%E6%9E%90/
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
其中:
local.path写对应的磁盘路径
必须指定对应的node , 用.spec.nodeAffinity 来对应的node
.spec.volumeMode可以是FileSystem(Default)和Block
确保先运行了StorageClass (即下面写的文件)
再写对于的StorageClass文件
其中:
provisioner是kubernetes.io/no-provisioner , 这是因为local pv不支持Dynamic Provisioning, 所以它没有办法在创建出pvc的时候, 自动创建对应pv
volumeBindingMode是WaitForFirstConsumer , WaitForFirstConsumer即延迟绑定 , 这样可以既可以保证推迟到调度的时候 , 再进行绑定 , 又可以保证调度到指定的pod上 , 其实WaitForFirstConsumer又2种: 一种是WaitForFirstConsumer , 一直是Immediate , 这里必须用延迟绑定模式
再创建一个pvc
这里需要注意的地方就是storageClassName要写出我们之前自己创建的storageClassName的名字:local-storage
之后应用这个文件 , 使用命令kubectl get pvc可以看到他的状态是Pending , 这个时候虽然有了匹配的pv , 但是也不会进行绑定 , 依然在等待
之后我们写个pod应用这个pvc
这里写的.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
具体的地址:
指定配置文件:https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume/helm
使用指南:https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume#option-1-using-the-local-volume-static-provisioner