[toc]
13 容器的持久化存储#
13.1 k8s存储设计#
k8s里因为历史兼容因素,导致的存储概念特别多,通过手册学习非常困难。本书作者会以volume概念到docker到k8s的演进历程为主线,梳理和讲解存储设计
13.1.1 mount和volume#
docker内置三种存储挂载类型: bind 、 volume 和tmpfs
bind就是把宿主机的目录或者文件挂载到容器的指定目录下。
缺点在于只允许容器和宿主机之间映射, 无法实现不同宿主机上的容器共享同一个存储,除非在宿主机外面再对接共享存储系统挂载, 此时对存储的管理更多是宿主机上的工作而不是容器的工作了。下图这个就是在宿主机外面再对接一个共享存储系统的情况
volumn则能提升docker对不同存储介质的自称能力, 用抽象的资源来代表宿主机或者网络中的存储区域,让docker能够管理这些资源。
tmpfs则是在内存中临时读写的数据,和持久化存储关系不大。
13.1.2 静态存储分配#
指的是k8s里的 persistentVolumn机制
需要系统管理员手动分配persistentVolumn, 这个东西是在pod之外的部署在宿主机上的。
然后容器使用者指定pod期望容量persistenVolumn
k8s帮忙做撮合并实现“1对1”的匹配, 这会导致独占的情况,即使空间有剩余,而且系统管理员手动分配问题会很多。如下图所示:
13.1.3 动态存储分配#
k8s为了改进静态存储分配的问题, 开发出了 dynamic provisioning的动态存储解决方案。
管理员不再手工分配persistentVolume,而是配置storageClass。 用户依旧使用persistentVolumeClaim来声明存储。
资源分配器自己完成中间宿主机和pod之间的分配, 省去了管理员人工操作的中间层,也不用暴露pesistentVolumn的概念。
另外回收方面动态也比静态有优势。 当回收pod时,静态分配会要求设置成recycle策略并让系统执行rm -rf /volume/* 这种粗暴命令, 而动态分配汇总如何删除由资源分配器代码管理,不需要人工接入删除行为
13.2 容器存储生态#
13.2.1 k8s存储架构#
k8s对容器的外部存储有以下三种操作
- privision/delete 准备或移除存储
- Attach/Detach 将存储接入/分离到系统中,让系统通过fdisk -l可以查看
- Mount/Unmount 将设备挂载/卸载到系统的指定位置,确定了设备的访问目录、文件系统各种等应用侧信息
上面六个操作是存储插件自己实现的,k8s只负责调用。
k8s使用了以下3个状态控制器来进行调用:
- PV控制器: 所有处于等待状态的persistentVolumeClaim都能匹配到与之绑定的PersistentVolume
用来根据需要进行provision/Delete操作 - AD控制器: 所有被调度到的pod节点都会附加要使用的存储设备,pod销毁后pod节点也会分离存储。
用来调用attach/Detach - Volume管理器
在本节点中的volume中执行mount/unmount操作