1. 什么是容器数据卷。

Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,
那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

数据卷的特点:

1:数据卷可在容器之间共享或重用数据。

2:卷中的更改可以直接生效。

3:数据卷中的更改不会包含在镜像的更新中。

4:数据卷的生命周期一直持续到没有容器使用它为止。

总结:数据卷的作用。容器的持久化、容器间继承+共享数据。

2. 添加数据卷(也就是映射目录)。

命令如下:也就是运行镜像,并且使用-v参数,把容器的目录和宿主机的目录进行绑定。

 docker run -it -v /宿主机绝对路径目录:/容器内目录  镜像名

例子:运行centos镜像,并且把容器的/containerDataVolume目录和宿主机的/myDataVolume进行绑定同步。

docker run -it -v /myDataVolume:/containerDataVolume centos

说明:

  • 如果不存在指定的目录,那么会创建/containerDataVolume和/myDataVolume目录。
  • 修改宿主机或容器的目录内容,对应另一方的目录都会修改。是一个双向的数据同步。
  • 如果把容器stop,修改宿主机的目录内容,当重启容器之后,修改的内容会马上同步到容器对应的目录/containerDataVolume。

3. 只读映射。

命令如下:

 docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

上面的ro是readonly,表示运行容器后,容器内的目录是只读的。也就是宿主机可以读写宿主机这边对应的目录,但是容器内的对应目录不能读写。例子如下:

docker run -it -v /myDataVolume:/containerDataVolume:ro centos

上面的命令启动容器后,宿主机这边的目录/myDataVolume修改后会同步到容器的目录/containerDataVolume,但是进入容器后并不能修改容器的目录/containerDataVolume。因为定义了容器内的目录是只读的。

4. 用Dockerfile添加数据卷。

  • Dockerfile是什么:

Dockerfile 就是描述docker镜像的一个文件。根据Dockerfile可以使用docker build 命令生成一个新的镜像。可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。

  • -v 主机目录:容器目录 这种目录映射方式,不能在Dockerfile中实现:

docker是运行在宿主机上的,不能保证宿主机都有某个特定的目录。所以出于可移植和分享的考虑,用 -v 主机目录:容器目录 这种方法不能够直接在Dockerfile中实现

  • dockerfile添加数据卷的例子:

一、新建一个文件名字随意(一般就叫Dockerfile)。内容如下:

# volume test
FROM centos
VOLUME ["/containerDataVolume1","/containerDataVolume2"]
CMD echo "finished,--------success1"
CMD /bin/bash

上面的文件内容中:

  1. FROM centos 表示即将创建的镜像是从centos继承过来的。
  2. VOLUME ["/containerDataVolume1","/containerDataVolume2"] 表示在新的镜像里面创建2个数据卷/containerDataVolume1和/containerDataVolume2。
  3. CMD echo "finished,--------success1" 表示输出finished,--------success1。
  4. CMD /bin/bash 表示打开bash终端。

二、使用docker build 根据Dockerfile创建镜像。

创建镜像的命令如下:

docker build -f Dockerfile文件的位置 -t 新的镜像名 .
  • -f :指定要使用的Dockerfile文件的位置;
  • --tag, -t:镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。

  • 命令最后还有一个点。

运行如下命令,就创建一个名字是wk/centos的镜像。使用的Dockerfile是/root/Dockerfile。

[root@localhost ~]# docker build -f /root/Dockerfile -t wk/centos .
Sending build context to Docker daemon  38.97MB
Step 1/4 : FROM centos
 ---> 1e1148e4cc2c
Step 2/4 : VOLUME ["/containerDataVolume1","/containerDataVolume2"]
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in ad1055634422
Removing intermediate container ad1055634422
 ---> dbeb2f24458b
Step 3/4 : CMD echo "finished,--------success1"
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in de271419c5af
Removing intermediate container de271419c5af
 ---> eacb86752e4e
Step 4/4 : CMD /bin/bash
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in 00bde01e437c
Removing intermediate container 00bde01e437c
 ---> f700fad120f8
Successfully built f700fad120f8
Successfully tagged wk/centos:latest

使用docker images 可以看到刚刚创建好的镜像。

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
wk/centos           latest              f700fad120f8        About a minute ago   202MB

运行刚刚创建的镜像wk/centos,进入这个centos容器后可以看到创建了文件目录containerDataVolume1和containerDataVolume2

[root@localhost ~]# docker run -it wk/centos
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@37aa7d20e166 /]# ll
total 12
-rw-r--r--.   1 root root 12076 Dec  5 01:37 anaconda-post.log
lrwxrwxrwx.   1 root root     7 Dec  5 01:36 bin -> usr/bin
drwxr-xr-x.   2 root root     6 Mar 13 02:38 containerDataVolume1
drwxr-xr-x.   2 root root     6 Mar 13 02:38 containerDataVolume2

退出容器后,使用 docker inspect 容器ID 可以看到下面Mounts的内容。在Source、Destination可以看到容器的目录和宿主机的哪个目录映射。Source、Destination 对应的目录是同步的,修改其中一个另一个也会同步。

"Mounts": [
            {
                "Type": "volume",
                "Name": "ff9ef0ac17ea2bf3fe83a241a4bc7eba661472149e1e227d40ba7f4cf2844860",
                "Source": "/var/lib/docker/volumes/ff9ef0ac17ea2bf3fe83a241a4bc7eba661472149e1e227d40ba7f4cf2844860/_data",
                "Destination": "/containerDataVolume1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "a59169b80b6c94436bba25048214a1228754af082efaec5765e962a0bb472cf2",
                "Source": "/var/lib/docker/volumes/a59169b80b6c94436bba25048214a1228754af082efaec5765e962a0bb472cf2/_data",
                "Destination": "/containerDataVolume2",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

5. 容器卷的继承。容器之间数据共享。

在运行容器的时候,类似于一种继承关系。子容器的数据卷会继承父容器的数据卷。孙容器的数据卷也会继承爷爷辈。也就是父、子、孙容器中的数据卷目录映射到宿主机的同一个目录。

测试例子如下:接着上面用Dockfile创建的镜像wk/centos。

  • 运行一个容器,取名testParent。
docker run -it --name testParent wk/centos
  • 运行一个容器,取名testChild。并使用 --volumes-from testParent 指定这个容器的数据卷继承testParent的数据卷。
docker run -it --name testChild --volumes-from testParent wk/centos
  • 运行一个容器,取名testGrandson。并使用 --volumes-from testChild 指定这个容器的数据卷继承testChild的数据卷。
docker run -it --name testGrandson --volumes-from testChild wk/centos
  • 使用docker inspect 分别查看上面这3个容器的信息。
docker inspect testParent 
docker inspect testChild
docker inspect testGrandson

Mounts下面可以看到它们的数据卷的name是一样的,容器内的路径映射到宿主机Source下的路径也是一样的。修改其中任何容器的对应目录下的数据,都会在其他容器中看到。修改宿主机的映射目录,也可以同步到每个容器。这就是--volumes-from 参数的作用。可以使得容器的映射目录相同。可以多个容器共享数据。

"Mounts": [
            {
                "Type": "volume",
                "Name": "3ff95763b7a8cee196b0a794e60145c055c565bfb6ea85c414dfd9098cbb4521",
                "Source": "/var/lib/docker/volumes/3ff95763b7a8cee196b0a794e60145c055c565bfb6ea85c414dfd9098cbb4521/_data",
                "Destination": "/containerDataVolume1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "6e34389e99bf6c32ea4bac213f838d59fe367101127af6cd950952c380bd4201",
                "Source": "/var/lib/docker/volumes/6e34389e99bf6c32ea4bac213f838d59fe367101127af6cd950952c380bd4201/_data",
                "Destination": "/containerDataVolume2",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

results matching ""

    No results matching ""