Docker 之五 Docker 数据卷与数据卷容器

前言

容器在运行期间产生的数据不会写在镜像里面,重新用此镜像创建并启动新的容器就会初始化镜像,加一个全新的容器可写层来保存数据。生产环境中使用 Docker 的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,Docker 提供数据卷和数据卷容器来解决;另外还可以通过 commit 提交一个新的镜像来保存产生的数据,也可以通过 “docker cp” 命令在宿主机与容器之间互相拷贝数据文件。

容器中管理数据主要的两种方式

数据卷(Data Volumes):容器内数据直接映射到本地主机环境。
数据卷容器(Data Volume Containers):使用特定容器维护数据卷。

数据卷的功能介绍

  • 绕过 “写时复制” 系统,以达到本地磁盘 IO 的性能。
  • 绕过 “写时复制” 系统,有些文件不需要在 docker commit 打包进镜像文件。
  • 实现容器内部数据的持久化。
  • 数据卷可以在容器间共享和重用数据。
  • 数据卷可以在宿主机和容器间共享数据。
  • 数据卷数据改变是直接修改的。
  • 数据卷是持续性的,直到没有容器使用它们;即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。

Docker 通过命令的方式添加数据卷

1
2
3
4
5
6
7
8
9
10
11
# 创建宿主机的文件共享目录,即使不手动在宿主机上创建数据卷目录,Docker也会自动创建
# mkdir -p /host/datavolume

# 为容器添加一个数据卷,即将宿主机的/host/datavolume目录挂载到容器中的/datavolume目录,容器默认具有/datavolume目录的读写权限,以下命令的作用类似Linux的mount命令
# docker run -it -v /host/datavolume:/datavolume --name="cenots7" centos

# 为容器添加一个数据卷,同时指定容器仅拥有/datavolume目录的只读权限
# docker run -it -v /host/datavolume:/datavolume:ro --name="cenots7" centos

# 查看数据卷的创建情况
# docker inspect cenots7

Docker 通过编写 Dockerfile 的方式添加数据卷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 创建Dockerfile文件,并添加以下文件内容
# vi ~/dockerfile
FROM centos
VOLUME ["/dataVolume1","//dataVolume2"]
CMD /bin/bash

# 通过dockerfile文件构建新的Docker镜像,peter是命名空间,centos7是新镜像的名称
# docker build -f ~/dockerfile -t peter/centos7 .

# 查看刚构建的Docker镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
peter/centos7 latest e6d3ad991247 50 seconds ago 202MB

# 基于刚构建的Docker镜像,新建并启动容器
# docker run -it --name="centos7" peter/centos7

# 查看容器内通过dockerfile添加的容器卷
# ls -al /
drwxr-xr-x 2 root root 6 Dec 31 11:15 dataVolume1
drwxr-xr-x 2 root root 6 Dec 31 11:15 dataVolume2

# 查看宿主机中数据卷的挂载目录,该挂载目录由Docker分配
# docker inspect centos7
"Mounts": [
{
"Type": "volume",
"Name": "b6c0574c8e2105ebb736857f050d106dd4d3b35617c40110b69d85c22c900de1",
"Source": "/var/lib/docker/volumes/b6c0574c8e2105ebb736857f050d106dd4d3b35617c40110b69d85c22c900de1/_data",
"Destination": "/dataVolume2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "0ad49fc76fc6af73ebc62efc88c3976cb44edd1b48aed3d26995e7759044972a",
"Source": "/var/lib/docker/volumes/0ad49fc76fc6af73ebc62efc88c3976cb44edd1b48aed3d26995e7759044972a/_data",
"Destination": "/dataVolume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]

Docker 数据卷容器的使用

容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止;即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 首先创建Dockerfile文件
# vi ~/dockerfile
FROM centos
VOLUME ["/dataVolume1","/dataVolume2"]
CMD /bin/bash

# 通过Dockerfile文件构建新的Docker镜像
# docker build -f ~/dockerfile -t peter/centos7 .

# 基于刚构建的Docker镜像,新建并启动容器
# docker run -it --name="centos-1" peter/centos7

# 基于上面的centos-1容器,再创建另一个容器centos-2,同时指定centos-1容器作为数据卷容器
# docker run -it --name="centos-2" --volumes-from centos-1 peter/centos7

# 查看centos-2容器内的容器卷
# ls -al /
drwxr-xr-x 2 root root 6 Dec 31 11:15 dataVolume1
drwxr-xr-x 2 root root 6 Dec 31 11:15 dataVolume2