Hello Docker(七)——Docker数据持久化

Hello Docker(七)——Docker数据持久化

一、Docker数据持久化简介

默认情况下,Docker容器内部新创建文件或者修改文件,结果会保存在容器的可读写层中,因此:
(1)当container消失时,与container一体的可读写层也一并消失,数据并未持久化。当一个container需要其它container中可读写层的数据时,读取操作非常困难。
(2)container可读写层与宿主机的文件系统紧密结合,很难进行迁移。
(3)写入数据到container可读写层需要storage driver,与直接在宿主机文件系统中读写数据相比效率要低。
Docker支持的数据持久化方案如下:
(1)volume。
(2)bind mount。
(3)tmpfs mount,仅限Linux操作系统中。
Hello Docker(七)——Docker数据持久化
Docker创建容器时通过参数选项指定数据持久化路径,bind mount与volume使用-v或者--volume选项,tmpfs通过--tmpfs选项。从docker17.0.6开始,推荐使用新选项--mount。
--mount参数选项如下:
type:可以是bind、volume或者tmpfs,默认是volume
source:宿主机上目录路径,可以用缩写src
destination:目标路径,容器上挂载的路径,可以用dst或者 target
readonly :可选项,容器挂载的路径会被设置为只读
volume-opt:可选项,当volume驱动接受同时多个参数作为选项时,可以以多个键值对的方式传入。
如果主机中的文件或目录不存在,当使用--mount挂载时,Docker会报错,当使用-v或--volume时,会在主机上创建目录。

二、volume持久化方案

1、volume简介

volume是Docker官方推荐的持久化方案,默认情况下,volume的存储空间来自于宿主机文件系统中的某个目录,如/var/lib/docker/volumes/,docker系统外的程序无权限修改其中的数据。
volume由Docker负责创建、管理。用户可以显式的调用命令docker volume create创建volume,也可以通过container、service的启动隐式创建。
一个volume可以同时供多个container使用,如果没有container使用volume,其不会自动删除,用户需运行docker volume prune明确删除。
如果用户显式创建volume,则需要给其指定一个名称;如果是隐式创建volume,Docker会自动为其分配一个在宿主机范围内唯一的名字。
Docker引入Volume原因如下:
(1)删除容器时,volume不会被删除。
(2)在不同容器间共享volume(存储 / 数据)。
(3)容器与存储分离。
(4)将volume存储在远程主机或云上。

2、volume特点

docker volume create -v 创建volume时,宿主机目录路径必须以/或~/开头,否则Docker会将其当成volume 而不是bind mount。
如果宿主机上的目录不存在,docker 会自动创建目录;如果容器中的目录不存在,docker会自动创建目录;如果容器中的目录已有内容,docker会使用宿主机上目录的内容覆盖容器目录的内容。

3、挂载指定volume

docker run -it -v my-volume:/data --name container1 busybox
启动容器 container1 时,挂载名为my-volume的volume到容器的 /data目录。如果 my-volume不存在,docker会自动创建my-volume,并挂载到 /data 目录。
my-volume在宿主机目录为 /var/lib/docker/volumes/my-volume/_data
docker run -v 命令中,如果没有指定volume名称,docker会默认创建一个匿名的volume。
docker run -it -v /data --name container1 busybox
创建匿名volume位于/var/lib/docker/volumes/xxxxx/_data
可以使用docker inspect container1查看容器的volume的具体信息。
docker run -it -v test:/test --name test busybox
创建的volume位于/var/lib/docker/volumes/test/_data

4、volume使用场景

通过使用第三方提供的volume driver,用户可以将数据持久到远程主机或者云存储中。
(1)多个容器间共享数据。
(2)宿主机不保证存在固定目录结构。
(3)持久化数据到远程主机或者云存储而非本地。
(4)需要备份、迁移、合并数据时。停止container,将volume整体复制,用于备份、迁移、合并等。

三、bind mount持久化方案

1、bind mount

bind mount持久化方式将宿主机中的文件、目录挂载到容器上,相应文件、目录可以被宿主机读写,也可以被容器读写。
bind mount持久化方式可以将数据存储在宿主机器任何地方,但会依赖宿主机的目录结构,因此不能通过docker CLI直接管理,并且非Docker进程和Docker进程都可以修改。
docker run -it -v host-dava:container-data alpine sh
将host主机host-data目录mount到container中的container-data目录
bind mount注意事项:
(1)-v 宿主机目录路径必须以/或~/开头,否则docker会将其当成是volume 而不是bind mount。
(2)如果宿主机上的目录不存在,docker会自动创建目录。
(3)如果容器中的目录不存在,docker会自动创建目录。
(4)如果容器中目录已有内容,那么docker会使用宿主机上目录的内容覆盖容器目录的内容。
docker volume create vm_test
创建volume
docker run -it --mount source=vm_test,target=/test test /bin/bash
启动容器,挂载vm_test到容器/test目录

2、bind mount特点

(1)性能最好
(2)Docker容器与宿主机耦合过于紧密,移植性较差。

3、bind mount使用场景

(1)container共享宿主机配置文件,如docker将宿主机文件/etc/resov.conf文件bind mount到容器上,两者会使用相同的DNS服务器。
(2)开发环境中build容器化。开发过程中将build过程container化,将宿主机上源代码目录bind mount到build container中。修改代码后,运行build container的build命令,build container则将build结果写入另一个bind mount的目录中。
(3)监控服务container化。读取宿主机固定文件中的数据实现监控。

四、tmpfs mount持久化方案

1、tmpfs mount

tmpfs mount只在Linux主机内存中持久化,是临时性的。当容器停止,tmpfs mount会被移除,通常用于临时存放敏感文件。
在docker内部,swarm服务使用tmpfs方式来将secrets挂载到服务的容器中。
docker run -d -it --name tmptest --tmpfs /test busybox

2、tmpfs mount特点

(1)只能在Linux主机内存中,不会持久化到磁盘。
(2)不支持多容器间共享。

3、tmpfs mount使用场景

Docker可将用户名与密码等敏感数据保存在某个数据库中,当启动需要访问这些敏感数据的container或者service时,docker会在宿主机上创建一个tmpfs,然后将敏感数据从数据库读出写到tmpfs中,再将tmpfs mount到container中,安样能保证数据安全。当容器停止运行时,则相应的tmpfs也从系统中删除。

猜你喜欢

转载自blog.51cto.com/9291927/2543303