学习笔记397—Docker数据管理

发布时间 2023-04-12 23:23:12作者: 何弈

Docker有两种数据管理的方式

  • 数据卷: 容器内数据直接映射到本地主机环境;
  • 数据卷容器: 使用特定容器维护数据卷.

数据卷

数据卷是一个可供容器使用的特殊==目录==, 它将主机操作系统目录直接映射进容器

数据卷的特性:

  1. 可以在容器之间共享和重用, 容器间传递数据将变得高效与方便;
  2. 对数据卷内数据的修改会立即生效,无论是容器内操作还是本地操作;
  3. 对数据卷的更新不会影响镜像,解耦开应用和容器;
  4. 卷会一直存在,直到没有容器使用,可以安全地卸载它

创建数据卷

$ docker volume create 数据卷名

可用的选项

  • -d --driver string 指定卷驱动程序名,默认为local
  • --label 为卷设置元数据
  • -o --opt map 设置驱动程序特定选项

创建的数据卷在/var/lib/docker/volumes路径下

挂载数据卷

挂载数据卷一般是在docker run命令中使用--mount或者-v选项

最初,-v 或 --volume 标志用于独立容器,而 --mount 标志用于群集服务。但是,从 Docker 17.06 开始,也可以在独立容器上使用 --mount。一般来说,--mount 更明确和详细。最大的不同在于 -v 语法将所有选项组合在一个字段中,而 --mount 语法将它们分开。建议使用 --mount语法。

使用--mount(推荐)

$ docker run --mount,type=xxx,source=xxx,destination=xxx,readonly,bind-propagation=xxx
  • type为数据卷类型,有三种类型的数据卷
    • volume 普通数据卷,在主机/var/lib/docker/volumes路径下创建一个新目录,Docker会管理该目录内容,将容器目录下的数据同步到该目录
    • bind 绑定数据卷,主机上的文件或目录被挂载到容器中,覆盖容器相关目录内容;依赖宿主机特定的目录结构,DockerFile不能使用这种方式
    • tmpfs 临时数据卷,只存在于内存中
  • source 宿主机位置 也可以替换为 src,匿名卷忽略这个参数;如果目录不存在,会报错
    • type是volume时填写已创建好数据卷的名字
    • type是bind时填写绑定文件夹的绝对路径
  • destination 容器内位置 必须是容器内绝对路径
  • readonly为只读,容器只有数据卷挂载目录的只读权限
  • bind-propagation子属性
    • shared 原始mount的次级mount会显示在重复mount中, 且重复mount的次级mount的内容也会在原始mount中显示
    • slave 与shared mount相似,只是内容单方向可见,重复mount的内容不会在原始mount中显示。
    • private 次级mount在原始mount和重复mount之间互不可见
    • rshared 与shared mount一样,只是传播范围扩展至嵌套的重复mount和原始mount
    • rslave 与slave mount一样,只是传播范围扩展至嵌套的重复mount和原始mount
    • rprivate 默认值,与private mount一样,即原始mount和重复mount之间都不会传播内容。

使用-v

$ docker run -v source:destination:option

-v的语法比较简单,通过两个冒号分隔出三个位置

  • 第一个位置是宿主机位置,如果目录不存在,会创建数据卷或者目录
    • 如果填写绝对路径,数据卷类型为bind绑定数据卷
    • 如果填写相对路径,数据卷类型为volume普通数据卷
  • 第二个位置是容器内位置,必须是绝对路径
  • 第三个位置是可选的,是一个使用逗号分隔的选项列表
    • ro 只读
    • delegated
    • cached
    • z
    • Z

关于数据卷,还有其他命令

查看数据卷

$ docker volume ls

需要注意,只会显示volume类型的数据卷

  • -f, --filter 指定过滤规则
    • 'dangling=true' 未经任何容器使用的卷
    • 'driver=xxx' 过滤卷上的驱动程序名
  • --format 使用模板规则打印
  • -q 只显示卷名

查看数据卷详细信息

$ docker volume inspect 数据卷名

删除数据卷

  1.  $ docker volume rm 数据卷名
  2.  # 清理无用数据卷
  3. $ docker volume prune

数据卷容器

数据卷容器是一个用于多个容器之间共享更新数据的==容器==

创建数据卷容器

首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata

$ docker run -it -v /dbdata --name dbdata ubuntu

这个例子中使用的是匿名数据卷,将一个随机名字的数据卷挂载到容器的/dbdata目录

常用的镜像都可以生成数据卷容器

可以在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷

  1.  $ docker run -it --volumes-from dbdata -name dbl ubuntu
  2.  $ docker run -it --volumes-from dbdata -name db2 ubuntu

这三个容器任意一方在该目录写入,其它容器都可以看到

可以多次使用--volumes-from 参数来从多个容器挂载多个数据卷,还可以从其他已 经挂载了容器卷的容器来挂载数据卷:

$ docker run -d --name db3 --volumes-from dbl training/postgres 

简单来说,就是获取其他容器上挂载的数据卷,同时挂载在自己这个容器上

利用数据卷容器来迁移数据

备份

$ docker run --name worker --volumes-from dbdata -v /dataDir:/backer busybox tar -cvf /backer/backup.tar /dbdata 

这句命令的意思是,创建一个镜像,获取dbdata的数据卷,挂载到当前容器同名目录(dbdata挂载在/dbdata,所以我们的容器中也挂载在/dbdata),然后新建一个bind类型数据卷,挂载宿主机/dataDir到容器内部的/backer

启动容器后执行命令tar -cvf /backer/backup.tar /dbdata 将dbdata的数据卷内数据打包,放在新建数据卷内

这样,我们宿主机的/dataDir就可以获取dbdata数据卷内的打包数据backup.tar

使用busybox的原因是,这个容器的使命就是运行打包这条命令,运行之后容器就执行完毕,所以没必要使用拥有完善功能的镜像,busybox就几个MB却包含了经常使用的命令,非常适合这种场景

恢复

首先我们再创建一个和dbdata1相同的数据卷容器,命名为dbdata2

$ docker run -it -v /dbdata --name dbdata2 ubuntu

下面我们将上一步备份的数据,恢复到数据卷容器中

$ docker run --name worker2 --volumes-from dbdata2 -v /dataDir:/backer busybox tar -xvf /backer/backup.tar

和备份的思路相同,获取dbdata2的数据卷,挂载在容器/dbdata;然后主机含有tar文件的dataDir挂载到容器/backer

因为上一步是用绝对路径压缩的,而我们当前容器目录结构和备份时容器目录结构是相同的,所以不用指定解压目录。

参考链接:https://blog.csdn.net/bahan88123/article/details/101090625