使用 的过程中,数据保存是很重要的一环,因为容器一旦被删除,容器内的数据也将一并被删除。而 Volume 正是为了解决这个问题而存在,它可以映射一个物理机上的文件夹到容器内部,用于保存容器产生的数据。下面就来说说 Dokcer Volume 的使用及注意事项。

数据卷特性

Volume 也称 Data Volume,是一种数据卷的形式,它是供一个或多个容器使用的文件或目录,有以下特性:

  • 可以共享于多个容器之间;
  • 对数据卷的修改会立即生效;
  • 对数据卷的更新与镜像无关;
  • 数据卷会一直存在直到手动清除。

使用数据卷

docker run 的帮助命令中可以看到,Volume 是其中的一个参数,也就是说数据卷需要在容器启动时进行配置并生效。

使用数据卷有如下几种方式:

方式一:docker run -v /MOUNT_POINT

这种是使用默认物理主机路径进行映射,默认的映射路径为:

比如:

运行一个名为 TEST:7 容器,使用默认路径映射到容器内的 /root 中,并创建 test_volume 文件。

可以看到,在 /var/lib/docker/volumes/ 的某文件夹内(名称是随机的),也创建了同样的 test_volume 文件。可以证明这个文件夹与容器内的 /root 是相互映射的。只要不去执行删除卷的操作(后面会说到),则容器内 /root 里面的内容是永久保存在物理机上的。

但是这种方式带来一个问题,就是由于默认路径下,物理机上的文件夹命名是随机的,当需要映射数据卷的容器增多时,很难能找到某个容器映射的数据卷所在的物理路径,对于数据提取及备份来说,很是麻烦。所以一般来说建议使用第二种方式。

方式二:docker run -v /HOST/DIR:/CONTAINER/DIR

这种方式使用指定物理机上的某个路径,与容器中的某个路径进行映射,这样就能明确地知道容器中映射的是哪个物理路径,便于数据提取及备份。

比如:

还是跟前一个例子类似,只是我们将容器内 /root 映射到物理机的 /root 中来看看效果。

可以看到,物理机上 /root 中出现了容器所创建的 test_volume 文件,说明映射成功。

容器之间共享卷

数据卷不单可以将容器内的文件夹映射到物理机,还可以实现多个容器共用同一个物理文件夹。

方式一:映射同一个文件夹

可以将两个容器运行时,指定同一个物理机文件夹作为数据卷使用。

可以看到,我用 TEST6 容器创建的 /root/test_volume_6 文件,可以同时在 TEST7 容器及物理机中看到,说明两个容器的数据卷都同时映射到了物理机的同一个目录,实现了数据共享。

方式二:使用 --volumes-from value 参数

如果前一个容器使用的是默认挂载的方式(不指定物理路径),那两个容器间要想实现数据共享,用方式一就比较麻烦了,毕竟得先找出前一个容器数据卷的物理机路径。

这时候就需要用到 docker run 自带的参数了。

可以看到,容器 TEST6 和容器 TEST7 实现了 /root 路径的共享,并且无需知道所映射的物理路径。

删除卷

要删除数据卷也有两种方式。

第一种是在删除容器时,将数据卷一起删掉:

第二种是在运行容器时,加上 --rm 选项,这样表示容器关闭会被自动删除,同时删除其卷:

需要注意的是,以上两种删除方式的前提是,此容器为最后一个使用此卷的容器,也就是说,如果卷是共享的,则删除卷的前提是没有容器在使用此卷

当然,还有第三种非官方的方式,就是在删除容器后,找到数据卷所映射的物理机路径,手动进行删除。在使用指定物理机映射路径的情况下,建议使用这种方式,避免误操作导致数据丢失。

备份和恢复

既然有误删数据的风险,那是否有备份机制呢?

当然还是有的,想想看,既然都知道物理机路径了,该咋备份还不明白吗?

+tar 走起,嘿嘿。

当然以上方式针对于指定物理机映射路径的容器来说比较方便。对于使用默认路径映射的容器,能否找到物理机映射路径还是个问题。那这种容器是否有快捷的备份方式呢?

方法还是有的,那就是使用另一个指定物理机映射路径的容器,通过与原容器共享卷来进行备份,如下:

容器 CentOS6 是没有指定物理机映射路径的,但我们可以再开启一个指定物理机映射路径的 busybox 容器,并使其与 CentOS6 容器共享卷,然后通过 tar 命令,将共享卷的内容同步到指定物理机映射路径的数据卷上,完成备份。