Docker中的存储有两个概念:存储驱动程序Storage Driver和卷驱动程序Volumes Drivers。
首先我们来看一下安装docker以后,docker的文件夹下面有哪些内容:
cd /var/lib/docker && ll
这里存储了所有的数据,容器,网络,数据卷,镜像都在这个里面。
docker是分层架构,如果一般来说如果你变化的层级比较靠后,比如你对Dockerfile做了一定的修改,但是前4层是一样的,没有任何更新,这个时候在构建镜像的时候,它会从缓存中去读取前四层,而把第四层之后的变化更新到镜像。
docker的工作机制是所有这些层都是在运行Docker build命令以形成最终Docker镜像时创建的,都是Docker镜像层。构建完成后, 将无法修改这些层的内容。我们启动容器以后会生成一个新的read write层,这一层的数据都是副本,会随着容器的删除被删除,也就是不会被持久化。
如果我们想持久化数据就需要进行卷的挂载,存在两种方式:
1 卷挂载
#创建一个卷
docker volume create data_volume
#我们可以在卷目录看到我们创建的卷
ls /var/lib/docker/volumes -al
#启动的时候将这个卷进行挂载
docker run -v data_volume:/var/lib/mysql mysql
2 绑定挂载
这种方式我们可以灵活的指定主机的任意路径挂载到容器的卷上。
#例如以mysql为例子
docker run -v /data/mysql:/var/lib/mysql mysql
#下面这条语句是新的写法 但是上面那种语法没有被移除也还是支持的
docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
了解了上面的知识,那么来维护这些操作是可以选用不同的驱动的,这些驱动维护分层体系结构, 创建读写层,跨层移动文件以实现拷贝与写入等。
一些常见的存储驱动Storage Driver:
存储驱动程序的选择取决于所使用的底层操作系统。
对于Ubuntu, 默认存储驱动程序是AUFS,而AUFS在Fedora或CentOS等其他操作系统上不可用。
在这种情况下, Device Mapper设备映射器是更好的选择。Docker将根据操作系统自动选择可用的最佳存储驱动程序。
存储驱动Storage Driver不处理卷, 卷由卷驱动插件Volumes Driver Plugin处理。默认的卷驱动程序插件是本地local。
local volume插件可帮助在Docker主机上创建卷, 并将其数据存储在/var/lib/docker/volumes目录下。
许多其他卷驱动程序插件允许在第三方解决方案上创建卷:
K8s为了具有更好的拓展性,于是在计算,网络和存储提供了一套标准的接口,这就有点类似于java中的数据库,具体的实现是有不同厂商的不同驱动来实现的。
CSI定义了一组将由容器编排器调用的RPC远程过程调用,由存储驱动程序来实现。
例如, 创建一个pod并需要一个卷时,容器编排器(Kubernetes)应调用CreateVolume RPC并传递一组详细信息, 如卷名。存储驱动程序应实现RPC并处理该请求, 在存储阵列上配置新卷, 然后返回操作结果。
删除卷时, 容器编排器应当DeleteVolume RPC,存储驱动器应当实现调用然后从阵列中停用卷。
RPC规范详细说明了 容器编排器应发送哪些参数, 解决方案提供商应接收哪些参数,以及应返回哪些错误代码。
参考资料