Docker系列学习(六)——容器数据卷

  本章介绍如何将docker中的容器连接到本地的数据,或者各个容器之间共用本地数据。在前面的学习中我们知道docker容器相当于一个小的系统,但是操作容器的时候把数据全部放到容器中容器就会显得很大,并且当你删除容器之后,数据也就没有了,那有没有一种技术可以使得容器能访问本地的数据并且能将容器中产生的数据自动存储到本地(docker cp命令可以操作,但是每次数据产生都需要操作cp就很麻烦),或者几个容器能同时访问到同一组数据呢?这就是容器数据卷的工作了。

  数据卷的本质就是将容器中的某个目录挂载到本机上面,使用方式包括以下几种:

启动容器时使用-v参数来指定容器与主机的目录映射。

docker run -it -v 主机目录:容器内部目录 镜像名

  在为镜像创建容器的时候,将容器内部的某个目录和主机某个目录进行对应(此时主机中并不需要存在这样的一个目录)。

  举个例子,我现在主机中没有CircleWang这个文件夹。

  下面我将启动ubuntu镜像,并将容器中/home目录与本机CircleWang这个文件夹进行对应。

docker run -it -v /home/CircleWang:/home ubuntu

  我们立马可以看到,在我们本机的home目录下已经自动生成了一个CircleWang的文件夹。

  接下来我们可以使用docker inspect 容器ID 的命令来查看这个容器的基本情况以及相关的数据卷的挂载情况。

  其实到这一步骤已经可以看到数据卷已经挂载成功了,但是下面我们可以测试一下数据是否可以成功共享。

 主机中添加test.txt

 容器内部也出现了test.txt

  如果我们把容器删掉之后,这个CircleWang依然会存在,并且如果容器在停止状态(不是被删掉),我们在主机中更新文件,那么当容器再次启动的时候,我们会发现主机中更新的内容会自动同步过去。注意这里的链接不是软链接,可以看成“容器内部和主机同时能拥有CircleWang这个文件夹,并且共享”,如果此时再主机中rm -r CircleWang(删除这个文件夹)那么在容器中将无法使用/home文件夹。(可以看成我已经把你的实体删除了,容器就无法再操作该实体了),容器时无法删除挂载着的文件夹的。

具名挂载

  我们前面文章中提到了,我们在使用docker run的时候加上参数-v 主机路径:容器内路径,这样可以展现出完整的路径映射,但是还有另外的方式来进行挂载数据卷。格式是:-v 卷名:容器内路径,这种方式其实就是给容器内的那个路径目录取了另一个名字(在主机上可以查看的名字)。

docker run -it -v new_name:/home ubuntu

  这个意思就是我启动ubuntu系统,并且给/home这个文件夹取了一个新名字叫做new_name(在主机中会产生一个叫new_name新的文件夹与该容器中的/home目录绑定)。问题是这个new_name文件夹在哪里?我们可以通过docker volume ls命令来查看本地卷有那些。

 

   可以看到最后一行出现了一个叫new_name的,这就表示我们本地有一个new_name的文件被挂载到了容器中。接下来的问题是这个卷具体在哪里呢?我们可以使用之前提到过的docker volume inspect 具体卷名的命令来查看挂卷的具体情况。

   可以看到第四行中"/var/lib/docker/volumes/new_name/_data"这就是挂载卷在本地的路径,我们可以进本机这个路径看一看。同时我们也可以测试下当我们在容器中/home目录中增加文件的时候,本机路径.../new_name/_data路径下有没有相应的文件。(是有的)

  其实讨论这么多说白了,如果采用具名挂载的方式(即:-v 卷名:容器内路径)这样主机会在/var/lib/docker/volumes/目录下新建一个卷名文件夹并将该文件夹中的_data文件夹与容器内路径进行绑定。

匿名挂载

  与具名挂载方式不同的是,匿名挂载的模式是:-v 容器内路径。这种方式称为匿名挂载,这样挂载的问题是,那这个挂载到底是主机的哪里去了啊。其实刚才我们使用docker volume ls查看本机挂载卷的时候可以发现出现了很多数字字母组合的名称的卷。这些就是匿名挂载的时候,会生成一个文件夹从而绑定对应的容器内路径。

  比如我们使用以下命令来匿名挂载一个容器中/home目录。

docker run -it -v /home ubuntu

  此时我们再使用docker volume ls查看本机挂载卷,会发现新增了一个数字字母组合的卷

   其实在对应的/var/lib/docker/volumes/目录下会创建出一个888a3500..对应的文件夹。

   我们依然可以使用docker volume inspect 具体卷名的方式查看这个卷的挂载情况,例如我就查看一下这个888a3500...的情况。

总结:

  我们可以使用以下三种方式来进行数据卷的挂载。

-v 主机路径:容器路径  # 指定映射的方式
-v 卷名:容器路径     # 具名挂载
-v 容器路径         # 匿名挂载

拓展一:

  如果安装有VScode的docker插件,其实在插件中对应部分可以查看到本机卷挂载情况,并且可以使用右键直接查看到该卷的详细信息。如何VScode安装docker插件可以参看我这篇博文:VScode使用docker

拓展二: 多容器共享数据卷

  在实际开发中可能会遇到多个容器共享数据卷的问题,比如容器1绑定了两个数据卷,容器2也想绑定相同的数据卷从而实现两个容器见能共享数据,当然我们可以在创建容器2的时候按照容器1的配置再输入一遍-v.....,但是当挂载的数据卷越来越多时,我们可以使用--volumes-from 这个参数使得两个容器之间绑定相同的数据卷。完整命令如下:

docker run -it --name 容器2名字 --volumes-from 容器1名字 ubuntu 

  这个命令就是从ubuntu镜像启动一个容器(命名为容器2),并且把容器1中挂载的东西在容器2中同样挂载一遍。此时容器1中所有的挂载卷都会再挂载一个容器叫容器2。这样就实现了多个容器挂载同一个卷,那就意味着这多个容器间可以共享文件了。

 

posted @ 2022-04-12 15:34  Circle_Wang  阅读(217)  评论(0编辑  收藏  举报