Docker容器数据卷

什么是数据卷

先来回顾下Docker的理念:

  • 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
  • 容器之间希望有可能共享数据

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

一句话:有点类似我们Redis里面的rdb和aof文件

Docker容器数据卷作用

  • 容器持久化
  • 容器间继承+共享数据

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

数据卷实践

直接命令添加

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

  1. 命令挂载数据卷;

  1. 检查数据卷是否挂载成功

docker inspect 容器id

inspect可以查看容器详细的信息,包括挂载的数据卷位置,数据卷文件访问属性(可读写等)。

容器和宿主机间数据的共享

现在容器内部创建文件,写入内容,转到宿主机检查数据卷文件夹有无文件存在。

容器退出后主机修改数据卷文件同步问题

进行测试,先docker stop $(docker ps -q)退出容器,然后在宿主机的数据卷目录修改内容,重新启动容器,可以看到修改的内容已同步。

设置数据卷权限

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

ro:read only只读权限

测试,删除原来数据:

inspect查看容器信息:

Dockerfile添加

类比于从Hello.javaHello.class的关系,imagesDockerfile,images就相当于是对镜像源码级别的藐视。

Dockerfile中有多个指令,其中,可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。

VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]

说明:

出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。

1.创建一个目录,并在该目录下编写dockerfile

1
2
3
4
5
6
7
8
9
# volume test
# 继承自Centos镜像
FROM centos
# 创建两个数据卷
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
# 构建容器后输出语句
CMD echo "finished,--------success1"
# 启动容器后进入容器的命令行终端
CMD /bin/bash

2.build后生成镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -f : 指定dockerfile所在的目录和文件(如果是标准的Dockerfile命名且处于该目录下可以直接build -t)
[dw@dk mydocker]$ sudo docker build -f /mydocker/Dockerfile -t hj/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ["/dataVolumeContainer1", "dataVolumeContainer2"]
---> Running in 9f0fed014d89
Removing intermediate container 9f0fed014d89
---> 2636cab73bad
Step 3/4 : CMD echo "finished, --------success1"
---> Running in 8d36003f5e25
Removing intermediate container 8d36003f5e25
---> 07c279ee7fdb
Step 4/4 : CMD /bin/bash
---> Running in 6d653a9c7d6d
Removing intermediate container 6d653a9c7d6d
---> c811306dd0c4
Successfully built c811306dd0c4
Successfully tagged hj/centos:latest
[dw@dk mydocker]$
1
2
3
4
5
6
[dw@dk mydocker]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hj/centos latest c811306dd0c4 54 seconds ago 209MB
atguigu/mytomcat 1.2 3195c86b5066 3 days ago 669MB
tomcat latest c43a65faae57 3 weeks ago 667MB
centos latest 300e315adb2f 6 months ago 209MB

3.检验

找到容器对应的映射:

在container2对应的主机目录下创建了一个文件。

查看虚拟机目录下是否有:

注意:

数据卷容器

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。

类似活动硬盘上挂活动硬盘,实现数据的传递依赖。类似与redis的继承,父类有了,子类也会有。

案例实践

1.先启动一个父容器dc01

以上一步新建的镜像hj/centos为模板并运行容器dc01/dc02/dc03。

hj/centos已具有两个容器卷。

dc02和dc03继承自dc01。父到子,子到父都可共享。

删除dc01后,dc02、dc03都可以访问,无影响。那么在dc02创建文件,dc03会有吗?

可以看到有。

那么目前我再创建一个容器dc04继承自dc03,删除dc03后数据仍然会有。说明数据卷的生命周期一直持续到没有容器使用它们为止。


上一篇 Docker镜像

下一篇预告 DockerFile