容器中的数据卷

在容器中怎么样去使用这些所谓的数据存储。

在我们容器中使用我的数据卷呢主要有以下几种方式。

1、容器管理卷,容器管理卷是比较有特点的一种管理方案,他是基于我们docker自管理的,但是在写镜像的时候要去进行标识。到底那个镜像需要去进行我们的自管理,使用命令如下

docker-managerd Volume
    docker run -it --name roc -v MOUNTDIR roc/lamp:v1.0
    docker inspect -f {{.Mounts}} roc

2、容器的绑定卷。也就是个人操作的,也借助的命令如下

Bind-mount Volume
    docker run -it --name roc -v HOSTDIR:VOLUMEDIR roc/lamp:v1.0
    
HOSTDIR:VOLUMEDIR:      #也就需要我们去告诉它,我们的宿主机的某个目录,和我们容器的内部目录实现挂载

3、联合卷,那也就意味着我在启动第一个容器的时候,我可以在启动第二个容器的时候,告诉第二个容器要使用第一个容器的文件挂载,但是使用这种方法要基于我们dockerfile中的容器自管理卷,也就意味着我的第一个启动的镜像,他里面没有定义那个目录需要去持久化,我们是使用不了这个union volume,因为他根本不知道我们那个目录需要去调用使用--volumes-from的话,我们的镜像dockerfile中必须要写了VOLUME参数告诉他那个目录需要做持久化,如果在dockefile中没有指定VOLUME参数就不会实现自动匹配

union volume
    docker ron -it --name roc --volumes-form C

8.2.1 在容器中使用volumes(自管理卷)

8.2.1.1 容器管理卷演示

docker-managerd Volume
    docker run -it --name roc -v MOUNTDIR roc/lamp:v1.0
    docker inspect -f {{.Mounts}} roc

1、我们先启动一个wordpress镜像

[21:25:36 root@docker ~]#docker run --name word -d wordpress

docker run :        #启动一个容器
--name word:        #容器名字为word
-d#放到后台运行
wordpress:          #使用的是wordpress镜像

2、第一个容器启动成功之后我们在启动一个nignx容器。

[21:39:43 root@docker ~]#docker run  --name nginx -d nginx-1.19.1:alpine-3.12

docker run :        #启动一个容器
--name nginx:       #容器名字为nginx
-d#放到后台运行
nginx-1.19.1:alpine-3.12:           #使用的是nginx-1.19.1:alpine-3.12镜像

3、输入docker inspect查看我们nginx容器的信息,并且找到Mouts这一行,发现是空的,也就意味着当前并没有所谓的数据卷去使用或叫数据卷的挂载。

[21:59:49 root@docker ~]#docker inspect nginx

3、我们在通过docker inspect查看我们的wordpress镜像,就会发现有一个Volumes的挂载,/var/www/html这个是我们apache的页面显示根目录,在我们新版中匹配它与我们的宿主机的某个目录与之挂载的对应信息。那怎么演示它对应的目录在哪里呢,首先我们已经知道了他的目录对应挂载在宿主机上的/var/lib/docker

[22:04:38 root@docker ~]#docker inspect wordpress

4、在宿主机上进入到/var/lib/docker下,这里会有一堆的目录,并且存在一个volumes的目录

[22:04:39 root@docker ~]#cd /var/lib/docker/
[22:08:36 root@docker docker]#ls
builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes

5、进入到volumes目录下,会发现这里有很多目录,这些目录是因为我们之前启动了非常多的容器,有些容器在启动的时候就会使用到docker的管理卷。

[22:08:38 root@docker docker]#cd volumes/

#这些都是我们的docker在启动的时候会使用到的一些管理卷
[22:09:20 root@docker volumes]#ls
5d9394b27b8cef11eed3384d0557b058cc74335ac2cf9db96c80765de5478746
aac0ec33d7e09b52eb851bdda1cd13c2660ba3e87795d2689838b06584bac3f3
e956d416798d57fb416d03b4d91c0358b8d7ab17387d79dffb63ffeed6594c89
f69d2e272e260ad0d4fc6436f939b7b7a7f7734ffb66489a347ab44b7dfdab61
metadata.db

6、那我们现在将docker这些管理卷全部清空为了更好的进行演示。所以我们先将刚才启动的这两个容器都给删除

[22:09:23 root@docker volumes]#docker rm -f $(docker ps -a -q)

7、删除完了这些容器之后会发现这些卷依旧存在,也就意味着我们得到了一个关键点就是,当我们使用了容器的子管理卷之后,在默认删除容器之后,这些管理卷并不会被删除

[22:12:17 root@docker volumes]#ls
5d9394b27b8cef11eed3384d0557b058cc74335ac2cf9db96c80765de5478746
aac0ec33d7e09b52eb851bdda1cd13c2660ba3e87795d2689838b06584bac3f3
e956d416798d57fb416d03b4d91c0358b8d7ab17387d79dffb63ffeed6594c89
f69d2e272e260ad0d4fc6436f939b7b7a7f7734ffb66489a347ab44b7dfdab61

8、为了方便后面实验的演示,所有我这里删除所有的容器卷

[22:14:42 root@docker volumes]#rm  -fr *
[22:14:45 root@docker volumes]#ls

9、现在再来启动一下刚才我们启动这么两个容器。

#启动nginx容器
22:14:45 root@docker volumes]#docker run --name nginx -d nginx-1.19.1:alpine-3.12 

#启动wordpress容器
[22:15:36 root@docker volumes]#docker run --name word -d wordpress

10、再次ls命令查看一下,就会发现又出来一个目录,但是为什么我明明启动了两个容器只出现了一个目录呢?原因就是我们在dockerfile中声明需要容器自管理卷的只有wordpress镜像,因为我们在写nginx的dockerfile时没有指明需要容器的自管理卷,所以他就不会与之创建。

[22:15:42 root@docker volumes]#ls /var/lib/docker/volumes/
dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92

11、进入到wordpress容器自管理卷,查看他的特点,进入自管理卷目录下,发现有个data目录。并且查看_data目录会发现这些都是wordpress的配置文件

#进入容器自管理卷
[22:16:54 root@docker volumes]#cd dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92/
[22:19:13 root@docker dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92]#ls
_data

#查看_data目录
[22:19:14 root@docker dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92]#ls _data/
index.php        wp-admin              wp-content         wp-load.php      wp-signup.php
license.txt      wp-blog-header.php    wp-cron.php        wp-login.php     wp-trackback.php
readme.html      wp-comments-post.php  wp-includes        wp-mail.php      xmlrpc.php
wp-activate.php  wp-config-sample.php  wp-links-opml.php  wp-settings.php

12、我们在这个目录下touch一个文件,以做个标记。

#进入_data目录
[22:24:09 root@docker dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92]#cd _data/

#创建一个zhangguiyuan的文件
[22:24:11 root@docker _data]#touch zhangguiyuan

13、我们在进入到容器内部,进行观察。就会发现一个zhangguiyuan的文件。也就意味着是,如果我告诉这个镜像,需要自管理那个目录的话,他就意味着再去启动容器到镜像的时候,他会把这个目录与我们的/var/lib/docker/volumes创建一个随机目录与之挂载。那这样的话,如果里面我写了很多有意义的数据。

[22:24:17 root@docker _data]#docker exec -it word bash
root@c22a4f3d04f6:/var/www/html# ls
index.php    wp-admin          wp-content     wp-load.php      wp-signup.php
license.txt  wp-blog-header.php    wp-cron.php    wp-login.php     wp-trackback.php
readme.html  wp-comments-post.php  wp-includes    wp-mail.php      xmlrpc.php
wp-activate.php  wp-config-sample.php  wp-links-opml.php  wp-settings.php  zhangguiyuan

14、在容器中写入多个数据,这里创建了100个txt文件

#创建100个txt文件
root@c22a4f3d04f6:/var/www/html# touch {1..100}.txt

#通过ls查看已经创建成功
root@c22a4f3d04f6:/var/www/html# ls
1.txt    21.txt  34.txt  47.txt  6.txt   72.txt  85.txt  98.txt            wp-load.php
10.txt   22.txt  35.txt  48.txt  60.txt  73.txt  86.txt  99.txt            wp-login.php
100.txt  23.txt  36.txt  49.txt  61.txt  74.txt  87.txt  index.php         wp-mail.php
11.txt   24.txt  37.txt  5.txt   62.txt  75.txt  88.txt  license.txt           wp-settings.php
12.txt   25.txt  38.txt  50.txt  63.txt  76.txt  89.txt  readme.html           wp-signup.php
13.txt   26.txt  39.txt  51.txt  64.txt  77.txt  9.txt   wp-activate.php       wp-trackback.php
14.txt   27.txt  4.txt   52.txt  65.txt  78.txt  90.txt  wp-admin          xmlrpc.php
15.txt   28.txt  40.txt  53.txt  66.txt  79.txt  91.txt  wp-blog-header.php    zhangguiyuan
16.txt   29.txt  41.txt  54.txt  67.txt  8.txt   92.txt  wp-comments-post.php  {1.100}.txt
17.txt   3.txt   42.txt  55.txt  68.txt  80.txt  93.txt  wp-config-sample.php
18.txt   30.txt  43.txt  56.txt  69.txt  81.txt  94.txt  wp-content
19.txt   31.txt  44.txt  57.txt  7.txt   82.txt  95.txt  wp-cron.php
2.txt    32.txt  45.txt  58.txt  70.txt  83.txt  96.txt  wp-includes
20.txt   33.txt  46.txt  59.txt  71.txt  84.txt  97.txt  wp-links-opml.php

#最后退出该镜像
root@c22a4f3d04f6:/var/www/html# exit

15、现在我们将删除这个word容器,并且会发现在容器中创建的目录依然在,这样的话我们的数据就能够得到保存了,这个是我们docker自管理卷的一个特性,那也就意味着我们通过dockerfile自己去制作镜像的时候,我们怎么样让他达到这么一个自管理卷的效果,那给大家做一个演示

#删除word容器
[22:32:14 root@docker _data]#docker rm -f word

#会发现我们刚才在容器中创建的目录依然在
[22:32:27 root@docker _data]#ls
100.txt      21.txt  34.txt  47.txt  5.txt   72.txt  85.txt  98.txt                wp-links-opml.php
10.txt       22.txt  35.txt  48.txt  60.txt  73.txt  86.txt  99.txt                wp-load.php
{1.100}.txt  23.txt  36.txt  49.txt  61.txt  74.txt  87.txt  9.txt                 wp-login.php
11.txt       24.txt  37.txt  4.txt   62.txt  75.txt  88.txt  index.php             wp-mail.php
12.txt       25.txt  38.txt  50.txt  63.txt  76.txt  89.txt  license.txt           wp-settings.php
13.txt       26.txt  39.txt  51.txt  64.txt  77.txt  8.txt   readme.html           wp-signup.php
14.txt       27.txt  3.txt   52.txt  65.txt  78.txt  90.txt  wp-activate.php       wp-trackback.php
15.txt       28.txt  40.txt  53.txt  66.txt  79.txt  91.txt  wp-admin              xmlrpc.php
16.txt       29.txt  41.txt  54.txt  67.txt  7.txt   92.txt  wp-blog-header.php    zhangguiyuan
17.txt       2.txt   42.txt  55.txt  68.txt  80.txt  93.txt  wp-comments-post.php
18.txt       30.txt  43.txt  56.txt  69.txt  81.txt  94.txt  wp-config-sample.php
19.txt       31.txt  44.txt  57.txt  6.txt   82.txt  95.txt  wp-content
1.txt        32.txt  45.txt  58.txt  70.txt  83.txt  96.txt  wp-cron.php
20.txt       33.txt  46.txt  59.txt  71.txt  84.txt  97.txt  wp-includes

8.2.1.2 通过编写dockefile来演示实现容器自管理卷

1、首先我们先写一个dockerfile,这里并没有用到我们容器的自管理卷

[22:38:02 root@docker ~]#vim Dockerfile

#这是我们的基础镜像
FROM centos:7.6.1810

#创建一个/tmp/下的1.txt文件,这个文件的作用是后面我为了让这个容器能够位于前台工作,就可以直接tail -f 这个1.txt文件即可
RUN touch /tmp/1.txt

#创建一个data目录
RUN mkdir /data/

#接下来我们就通过CMD tail这个1.txt文件
CMD tail -f /tmp/1.txt

2、制作成镜像

[23:02:27 root@docker ~]#docker build -t test:v1.0 .

docker build:       #制作镜像
-t test:v1.0:       #新镜像名
.                    #当前目录下的dockerfile文件

3、 运行这个test:v1.0镜像为容器

[23:02:29 root@docker ~]#docker run --name test1 -d test:v1.0 

4、通过docker ps -a查看发现test1镜像正在前台运行,原因是我们在启动这个容器的时候tail -f 了1.txt文件,tail -f是把他放到了前台的这么一个守护进程。所以这个容器不会退出。

[23:04:42 root@docker ~]#docker ps -a

5、通过docker exec进入到这个容器内部

[23:05:15 root@docker ~]#docker exec  -it test1 bash

6、进入之后我们到容器的/data/目录下,并创建一个1文件

#进入到test1容器
[23:05:15 root@docker ~]#docker exec  -it test1 bash

#在容器中进入到/data目录下
[root@5c81ae1ef092 /]#  cd data/

#通过查看该目录没有任何东西
[root@5c81ae1ef092 data]# ls

#创建一个1文件
[root@5c81ae1ef092 data]# touch 1

#退出容器
[root@5c81ae1ef092 data]# exit 

7、回到宿主机的/var/lib/docker/volumes目录下,发现这里还是只有一个上面的word镜像的数据卷,也就意味着我自己做的这个centos镜像并没有新创建出来一个新的数据卷。那假如我们想给这个centos镜像所谓的数据持久化的话,我们必须得采用下面的另一种方式,也就是引用到dockerfile中的volumes参数了

#进入到容器的数据卷目录下
[23:09:22 root@docker ~]#cd /var/lib/docker/volumes/

#会发现一个wordpress镜像的数据卷
[23:09:36 root@docker volumes]#ls
dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92

8、修改我们的这个centos镜像的dockerfile文件,在dockerfile中我们加上volumes参数。

[09:03:40 root@docker ~]#vim Dockerfile 

#这是我们的基础镜像
FROM centos:7.6.1810

#创建一个/tmp/下的1.txt文件,这个文件的作用是后面我为了让这个容器能够位于前台工作,就可以直接tail -f 这个1.txt文件即可
RUN touch /tmp/1.txt

#创建一个data目录
RUN mkdir /data/

#给容器一个自管理卷,自动挂载到data目录下
VOLUME /data                                #加上volume参数实现容器的自管理卷                                                                                    

#接下来我们就通过CMD tail这个1.txt文件
CMD tail -f /tmp/1.txt

9、然后再将这个dockerfile文件重新制作一个新的centos镜像。

[09:05:06 root@docker ~]#docker build -t test:v2.0 .

docker build:           #制作新镜像
-t test:v2.0:           #新镜像名为test:v2.0版本
.                       #dockerfile文件在当前目录下

10、启动test:v2.0镜像。

[09:06:05 root@docker ~]#docker run --name test2 -d test:v2.0

docker run :        #运行容器
--name test2:       #容器名叫test2
-d#放到后台运行
test:v2.0:          #使用的是test:v2.0镜像

11、去到/var/lib/docker/volumes目录下,通过ls查看就会多了一个容器自管理卷

#进入到/var/lib/docker/volumes/目录下
[09:07:59 root@docker ~]#cd /var/lib/docker/volumes/

#查看volumes目录
[09:09:58 root@docker volumes]#ls

12、进入到f1598这个容器自管理卷目录中,进入_data目录中会发现。

#进入到容器自管理卷中
[09:09:59 root@docker volumes]#cd f1598f0863f81aea2bb71dba8263f595935d44263fe3779fe370c24d75372245/

#通过查看多了一个date目录
[09:11:34 root@docker f1598f0863f81aea2bb71dba8263f595935d44263fe3779fe370c24d75372245]#ls
_data

#在进入到_data目录下
[09:11:35 root@docker f1598f0863f81aea2bb71dba8263f595935d44263fe3779fe370c24d75372245]#cd _data/

#通过查看看_data目录中得内容是空的
[09:16:03 root@docker _data]#ls

13、进入test2容器中得data目录下,通过查看是空的。但是我们给他1到66的txt文件

#进入test2容器
[09:16:04 root@docker _data]#docker exec -it test2 bash

#在容器中进入data目录
[root@8e50175f4ff4 /]# cd /data/
[root@8e50175f4ff4 data]# ls

#创建1到66的txt文件
[root@8e50175f4ff4 data]# touch {1..66}.txt

14、回到宿主机,并且进入到当前容器的自管理卷中的_data目录下观察就会发现多了1到66个txt文件,也就是我们自定义的这么一个容器目录就已经实现了持久化了

#进入到centos镜像的自管理卷下
[09:21:54 root@docker ~]#cd /var/lib/docker/volumes/f1598f0863f81aea2bb71dba8263f595935d44263fe3779fe370c24d75372245/_data/

#通过观察就会多了1到66个txt文件
[09:22:17 root@docker _data]#ls
10.txt  16.txt  21.txt  27.txt  32.txt  38.txt  43.txt  49.txt  54.txt  5.txt   65.txt
11.txt  17.txt  22.txt  28.txt  33.txt  39.txt  44.txt  4.txt   55.txt  60.txt  66.txt
12.txt  18.txt  23.txt  29.txt  34.txt  3.txt   45.txt  50.txt  56.txt  61.txt  6.txt
13.txt  19.txt  24.txt  2.txt   35.txt  40.txt  46.txt  51.txt  57.txt  62.txt  7.txt
14.txt  1.txt   25.txt  30.txt  36.txt  41.txt  47.txt  52.txt  58.txt  63.txt  8.txt
15.txt  20.txt  26.txt  31.txt  37.txt  42.txt  48.txt  53.txt  59.txt  64.txt  9.txt

15、删除这个test2容器,会发现这个容器卷依然存在。从而实现了数据持久化。

#删除test2这个容器
[09:46:18 root@docker _data]#docker rm -f test2

#然后查看数据依旧在,从而实现了数据的持久化保存
[09:48:20 root@docker _data]#ls
10.txt  16.txt  21.txt  27.txt  32.txt  38.txt  43.txt  49.txt  54.txt  5.txt   65.txt
11.txt  17.txt  22.txt  28.txt  33.txt  39.txt  44.txt  4.txt   55.txt  60.txt  66.txt
12.txt  18.txt  23.txt  29.txt  34.txt  3.txt   45.txt  50.txt  56.txt  61.txt  6.txt
13.txt  19.txt  24.txt  2.txt   35.txt  40.txt  46.txt  51.txt  57.txt  62.txt  7.txt
14.txt  1.txt   25.txt  30.txt  36.txt  41.txt  47.txt  52.txt  58.txt  63.txt  8.txt
15.txt  20.txt  26.txt  31.txt  37.txt  42.txt  48.txt  53.txt  59.txt  64.txt  9.txt

8.2.1.3 通过命令删除docker自管理卷。

但是这时候可能有些朋友又有疑问了,那我们每次删除容器的话,他的自管理卷还依旧存放在宿主机上也不会自动删除。这是不是也太费事了,没事是不是还需要定时过来清空?但是首先容器的自管理卷在我们定义镜像的时候就回去定义这个目录,就代表了这个目录下面的数据是非常重要的。默认不删除这是一个非常合理的选项,假如这是一个mysql数据库默认删除还得了啊,所以默认不删除是一个合理选项,但是我们就是想删除怎么办呢?其实命令里面是有的。

1、比如我们再启动一个容器。这里启动一个test2镜像

[09:56:02 root@docker ~]#docker run --name test2 -d test:v2.0

docker run:         #启动容器
--name test2:       #容器名为test2
-d:                 #放到后台运行
test:v2.0:          #使用的镜像是test:V2.0

2、启动成功以后呢,我们的/var/lib/docker/volumes目录下又多了一个卷

[09:56:26 root@docker ~]#ll /var/lib/docker/volumes/
total 0
drwxr-xr-x 3 root root 19 Aug 13 09:56 3f2b3143c17b0f86cb70c4bcbe81b02a44cc7e88927ef5aa3df65bd92bb4f9c6

3、我们想在删除容器的同时删除他的容器自管理卷。只需使用docker rm -f -v后面跟容器名。

#这是删除test2容器的同时删除了他的容器自管理卷
[09:59:55 root@docker ~]#docker rm -f -v test2 

4、再次通过ls 查看/var/lib/docker/volumes/目录就会发现刚才我们的test2容器的自管理卷目录已经自动删除

[10:03:24 root@docker ~]#ll /var/lib/docker/volumes/
total 0
drwxr-xr-x 3 root root 39 Aug 12 22:22 dc2b7bd5d745f42ad5b0335829541bc0dc6cd6269e583f02a83882d29a076a92
drwxr-xr-x 3 root root 19 Aug 13 09:07 f1598f0863f81aea2bb71dba8263f595935d44263fe3779fe370c24d75372245

8.2.2 容器中的绑定卷

容器的绑定卷。也就是个人操作的,也借助的命令如下

Bind-mount Volume
    docker run -it --name roc -v HOSTDIR:VOLUMEDIR roc/lamp:v1.0
    
HOSTDIR:VOLUMEDIR:      #也就需要我们去告诉它,我们的宿主机的某个目录,和我们容器的内部目录实现挂载

8.2.2.1 容器中的绑定卷演示

1、首先我们将现在启动的所有容器都将其删除,给一个干净的环境

[10:20:22 root@docker ~]#docker rm -f $(docker ps -a -q)

2、 然后我们在将/var/lib/docker/volumes目录下将所有的容器卷删除

[10:20:36 root@docker ~]#cd /var/lib/docker/volumes/
[10:21:37 root@docker volumes]#rm -fr *

3、现在我们去启动test1镜像,这个版本的容器是不带我们的容器自管理卷的

[10:21:44 root@docker volumes]#docker run --name test1 -d test:v1.0 

4、在/var/lib/docker/volumes/目录下ls 查看时没有容器自管理卷的,那如果像这种不在自管理卷的镜像,但是我又想让他用怎么办呢?那就需要我们在启动的时候自己添加

[10:22:35 root@docker volumes]#ls

5、这时候我创建一个test目录,和容器与之对应的管理卷

[10:26:00 root@docker volumes]#mkdir /data/test/

6、我们再次启动一个容器叫做test11,并且通过-v 选项。我想把我们宿主机的/data/test/,与之挂载到容器中的/data/目录中实现绑定。

[10:28:28 root@docker volumes]#docker run --name test11 -v /data/test/:/data/ -d test:v1.0 

docker run:     #启动容器
--name test11:  #容器名叫做test11
-v /data/test/:/data/:      #将宿主机的/data/test/目录绑定挂载到容器中的/data/中
 -d#放到后台运行
 test:V1.0      #使用的镜像

7、再到宿主机的/data/test目录下创建一个我的名字,zhangguiyuan文件

[10:32:02 root@docker volumes]#cd /data/test/
[10:34:06 root@docker test]#touch zhangguiyuan

8、创建成功之后我们在进入到test11容器中,通过查看/data目录下就会多了一个zhangguiyuan的文件,这就说明我们宿主机的/data/test目录与容器内部的/data目录已经完成绑定

#进入到test11容器中
[10:34:09 root@docker test]#docker exec -it test11 bash

#查看容器中的/data目录下多了一个zhangguiyuan的文件
[root@bd97b4af8e5c /]# ll /data/
total 0
-rw-r--r-- 1 root root 0 Aug 13 02:34 zhangguiyuan

8.2.2.2 容器自管理卷和-v选项绑定目录优先级测试

那现在问题来了,如果我们既在dockerfile中写了volum参数,也就是声明了容器自管理卷的使用。但是我们在启动容器的时候有加了-v选项指定了他的绑定目录,它到底那个会生效呢

1、首先我们到/var/lib/docker/volumes目录下,查看现在是没有任何文件

#进入到/var/lib/docker/volumes/目录中
[10:40:07 root@docker test]#cd /var/lib/docker/volumes/

#查看
[10:40:13 root@docker volumes]#ls

2、现在起一个test2容器,并且也制定了-v 选项,而且这个test2的dockerfile文件中明确指定了使用volum参数。理论上这个test2 容器的data目录会放到/var/lib/docker/volumes目录中,但是我在启动容器的时候又声明了需要使用宿主机的/data/test目录随之绑定。那这种情况下我们的/var/lib/docker/volumes目录中还有对容器的data目录进行绑定吗?

[10:45:43 root@docker volumes]#docker run  --name test2 -v /data/test/:/data/ -d test:v2.0 

3、对/var/lib/docker/volumes/查看,并没有新建出容器的自管理卷目录。

#进入 /var/lib/docker/volumes/目录
[10:47:00 root@docker ~]#cd /var/lib/docker/volumes/

#通过ls查看
[10:47:02 root@docker volumes]#ls

4、再进入到宿主机的/data/test/目录下,创建一个ZGY文件

#进入到/data/test/
[10:47:03 root@docker volumes]#cd /data/test/

#创建一个ZGY文件
[10:47:40 root@docker test]#touch ZGY

5、进入到test2容器中观察,并且cd 到容器中/data下。就会发现不仅有ZGY文件还有zhangguiyuan文件,也就意味着当我们在dockerfile中定义了volume参数容器的自管理目录,但是又在启动的时候通过-v 参数去指定了我们的绑定卷,那这时候它会按照管理员的自绑定卷先生效。原因是 -v 选项自绑定卷优先级更高

#进入容器test2
[10:47:52 root@docker test]#docker exec -it test2 bash

#在容器中查看data目录
[root@c376a6da56ba /]# ll /data/
total 0
-rw-r--r-- 1 root root 0 Aug 13 02:47 ZGY
-rw-r--r-- 1 root root 0 Aug 13 02:34 zhangguiyuan

8.2.2.3 多个容器共享同一个目录实现方案

这时候我们想实现,如果现在有两个容器,一个是test1容器一个是test2容器,这两个容器想要某个目录进行共享,怎么做?

我们可以拿当前宿主机的某个目录,比如就拿/data/test目录为例子。我们将这个宿主机的/data/test分别对test1容器和test2容器进行绑定,通过这样的方式,两个容器之间的目录就实现了共享作用。

1、首先删除我们现在正在运行的所有容器。给他一个干净的环境

[11:07:56 root@docker test]#docker rm -f $(docker ps -a -q)

2、启动test1容器,并且绑定在我们宿主机的/data/test目录下

[11:08:05 root@docker test]#docker run  --name test1 -v /data/test/:/data -d test:v1.0

docker run:         #运行容器
--name test1:       #容器名叫做test1
-v /data/test/:/data:   #将宿主机的/data/test/目录绑定在容器的/data中
-d                  #放到后台运行
test:v1.0:          #使用的是我们的test:v1.0镜像

3、启动test2容器,也绑定在我们的宿主机/data/test目录下。

[11:09:22 root@docker test]#docker run --name test2 -v /data/test/:/data -d test:v2.0

4、进入到test1容器中的 data 目录下创建一个zzz110的文件

#进入test1容器
[11:11:34 root@docker test]#docker exec -it test1 bash

#在容器中进入到 data目录下
[root@59f17dacb8a0 /]# cd /data/

#这是宿主机/data/test目录中原有的文件
[root@59f17dacb8a0 data]# ls
ZGY  zhangguiyuan

#创建一个zzz110的文件
[root@59f17dacb8a0 data]# touch ZZZ110

#退出容器
[root@59f17dacb8a0 data]# exit

5、进入到test2容器的data目录下,通过观察会发现多了一个ZZZ110文件

#进入到test2容器中
[11:14:16 root@docker test]#docker exec -it test2 bash

#进入data目录中
[root@56ab82c9f484 /]# cd /data/

#通过ls查看多了一个ZZZ110文件
[root@56ab82c9f484 data]# ls
ZGY  ZZZ110  zhangguiyuan

总结:

通过这样的方法就实现了容器之间的共享作用,如果有多个目录需要挂载到容器中,我们只需要加多个 -v 即可。但是这样会借助到我们宿主机的某个目录与之做交换。那如果我们既不想去借助到宿主机的某个目录,又想实现我们容器之间的共享怎么办。这时候就需要使用到另一个命令了union volume

8.2.3 容器中的联合卷使用演示(union volume)

联合卷,那也就意味着我在启动第一个容器的时候,我可以在启动第二个容器的时候,告诉第二个容器要使用第一个容器的文件挂载,但是使用这种方法要基于我们dockerfile中的容器自管理卷,也就意味着我的第一个启动的镜像,他里面没有定义那个目录需要去持久化,我们是使用不了这个union volume,因为他根本不知道我们那个目录需要去调用,使用--volumes-from的话,我们的镜像dockerfile中必须要写了VOLUME参数告诉他那个目录需要做持久化,如果在dockefile中没有指定VOLUME参数就不会实现自动匹配

union volume
    docker ron -it --name roc --volumes-form C

1、首先我们删除所有正在运行的容器。给他一个干净的环境

[11:36:38 root@docker test]#docker rm -f $(docker ps -a -q)

2、进入到/var/lib/docker/volumes/目录下,也是空的

[11:36:48 root@docker test]#cd /var/lib/docker/volumes/
[11:37:18 root@docker volumes]#ls

3、启动一个test2容器,使用的也是test:v2.0镜像版本,因为这个镜像中的dockerfile文件指定了volume的参数,也就是实现了docker自管理卷的使用

[11:37:54 root@docker volumes]#docker run --name test2 -d test:v2.0

4、在宿主机中的/var/lib/docker/volumes/目录下ls查看就多了一个容器自管理卷。

[11:39:53 root@docker volumes]#ls
c85806cad0104b72fd0d989883de17cde5f39deeba13fe8dc150b780dcc18db4

5、我们在启动一个test22 但是在他启动的时候给他一个选项 --volumes-from指定从我们的test2容器中来实现文件联合卷挂载

[11:40:06 root@docker volumes]#docker run --name test22 --volumes-from test2 -d test:v2.0

docker run :                #运行容器
--name test22:              #容器名为test22
--volumes-from test2:       #容器使用联合卷的方式实现文件共享
-d#放到后台运行
test:v2.0:                  #使用的镜像时test:v2.0

6、在宿主机上的/var/lib/docker/volumes/中查看还是是一个容器自管理卷,按理说不应该对吧,因为我们使用的test2镜像的dockerfile中声明volum参数他会创建一个随机目录与之绑定,那为什么会这样呢,原因是我们加了一句话--volumes-from test2

--volumes-from test2这个参数的含义就是,我们先启动了第一个容器,第一个容器会在我们的/var/lib/docker/volumes/目录下创建一个随机容器自管理卷,然后我们在启动第二个容器的时候,写了--volumes-from test2这个参数它会自动去匹配,当前test2的持久化挂载卷是c85806cad0104b72fd0d989883de17cde5f39deeba13fe8dc150b780dcc18db4,然后我们在test22这个容器使用的dockerfile中声明了 /data文件需要做持久化,所以他就会两端一起匹配。还是那句话如果想使用--volumes-from的话,我们的镜像dockerfile中必须要写了VOLUME参数告诉他那个目录需要做持久化,如果在dockefile中没有指定VOLUME参数就不会实现自动匹配

[11:43:21 root@docker volumes]#ls
c85806cad0104b72fd0d989883de17cde5f39deeba13fe8dc150b780dcc18db4

7、我们进入到test2容器中的/data/目录下创建一个我的名字的文件

#进入到test2容器中
[14:31:33 root@docker ~]#docker exec -it test2 bash

#然后再进入到/data/目录下
[root@fd99947901b1 /]# cd /data/

#通过查看什么文件都没有
[root@fd99947901b1 data]# ls

#最后创建一个我的名字的文件
[root@fd99947901b1 data]# touch zhangguiyuan

#退出容器
[root@fd99947901b1 data]# exit

8、进入到我们的test22容器中,并且进入到/data目录下,查看已经有了zhangguiyuan文件

#进入到 test 22
[14:45:49 root@docker ~]#docker exec -it test22 bash

#进入到容器的/data/目录中
[root@d2f548192829 /]# cd /data/

#通过查看存在了zhangguiyuan文件
[root@d2f548192829 data]# ls
zhangguiyuan

总结:通过联合卷的方式就可以不用借助到我们的宿主机,也能完成我们容器之间的共享,以上就是我们整个数据卷中容器中的一些使用方式,以及容器自管理卷的一些特性。

点赞