数据与数据卷
我们知道,Docker容器拥有沙盒隔离,容器的相关操作和数据流动相对封闭,容器与容器相隔离,容器与外部也相隔离。数据的共享、传输等操作就相对麻烦。
Docker通过UFS,将宿主机的文件/目录挂载到容器中,并让容器内外共享,使得容器数据与宿主机能够直接联通。这样做的另一个好处就是不必担心数据的持久化,因为直接挂载到了宿主机上,也就是硬盘中。
文件挂载
Docker有三个不同的文件挂载方式
- Bind Mount(绑定挂载):
- 绑定挂载允许将宿主机的文件或目录挂载到容器中,实现宿主机和容器之间的共享。
- 这意味着容器中的更改会直接影响宿主机中的文件,反之亦然。
- 这种挂载方式使得容器内的数据可以持久化保存在宿主机上。
- Volume(卷):
- 卷是一种特殊的目录,它可以绕过容器文件系统并直接管理容器数据。
- 卷可以提供持久化的存储,并且可以在容器之间共享和重用。
- 使用卷可以更有效地管理数据,并使得容器的数据可以独立于容器的生命周期而存在。
- Tmpfs Mount(临时文件系统挂载):
- Tmpfs 是一种基于内存的临时文件系统,它允许将临时文件系统挂载到容器中。
- 与绑定挂载和卷不同,Tmpfs Mount 仅在容器运行时存在,并且数据存储在内存中。
- 一旦容器停止运行,Tmpfs Mount 中的数据也会被清除。
简而言之,前两种是通过硬盘挂载,最后一种通过内存挂载;第一种挂载方式需要手动指定目录,第二种是通过Docker自动执行。
挂载命令
从使用和记忆角度,三种不同的挂载命令有如下区别
Bind Mount
- -v 指定两个目录(host dir:container dir)
Volume
- -v 指定一个目录(host dir)
Tmpfs Mount
- --tmpfs 指定一个目录(host dir)
Bind Mount
挂载一般在容器创建的时候通过-v选项
docker run -d --name xxx -v <host dir>:<container dir> ooo
* 以只读方式存储,<host dir>:<container dir>:ro (ro指的是readonly),对应的是容器中Mounts里的RW
docker run -d --name xxx -v <宿主机目录>:<Container目录>:ro ooo
* 这里的目录必须需要通过绝对目录的形式
查看详细情况
docker inspect <container-name / containerID / alias>
* 在Mounts中可以看到挂载相关信息
Volume
通过volume方法挂载,不需要指定宿主机目录,所以参数传递只需要传递容器目录即可,这也是在使用方面Bind Mount和Volume的区别之一
如果数据卷存在会直接引用,如果不存在会创建一个数据卷
docker urn -d --name xxx -v <contrainer dir> ooo
除此之外,因为volume同container等隔离,volume可以单独创建
docker volume create <volume-name>
查看创建的数据卷
docker volume ls
删除数据卷,不过因为需要指定数据卷名称,而很多数据卷都是自动命名,所以实际上并不好用
docker rm <volume-name>
在容器删除时,联级删除相关的数据卷,以节约资源
docker rm -v <volume-name>
删除没有被引用的数据卷,相当于手动GC
docker volume prune
Tmpfs Mount
与上述两种挂载方式不同的是,临时目录挂载需要通过--tmpfs指令指定
docker run -d --name xxx --tmpfs <host dir> ooo
查看容器情况
docker inspect <container-name>
* 在Tmpfs中可以看到关于tmpfs mount挂载相关信息
上文我们简单提及,Tmpfs Mount是通过内存进行储存的,虽然内存并没有持久储存的能力,但内存相较于硬盘而言其读写速度更快。适用于数据吞吐量较大且并不需要持久化储存的场景。
数据卷容器
多个数据卷可以通过数据卷容器进一步封装,隐藏配置细节,使其内聚更强,迁移更为便利。
数据卷容器持有内部数据卷的引用,不依赖于容器的运行。
docker create --name xxx -v <host dir> ooo
在创建容器时使用--volumes-from指定数据卷容器
docker run -d --name xxx --volumes-from <volume-container-name> ooo
数据备份与迁移
备份与迁移,本质上是打包-移动-解压的过程。通过创建临时容器,并结合数据卷容器可以很便捷地进行数据备份与迁移。
以下语句的意思是:通过Docker创建Bind Mount文件挂载并对数据卷容器引用的数据卷内的数据进行打包再把tar包迁移到宿主机目录中,完成操作后容器自动删除
docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage
我们简单拆分一下这条语句
--rm 结果是创建了临时容器。--rm的效果是停止后自动删除
--volumes-from appdata 引用的数据卷容器
-v /backup:/backup 宿主机的backup:Docker中的backup
ubuntu 这里就是镜像名,没有使用--name重命名
tar cvf... 这里需要了解一个机制:镜像定义后接上命令,会替换掉镜像原本的主程序启动命令。 这里的效果就是通过Docker打tar包并存放到宿主机中
另外,可以通过--mount实现操作的颗粒化程度更高的挂载,如果习惯configure-like的操作,可以通过结合Linux的输出重定向、管道符等实现更为定制化的挂载,这里不再展开。