6.Docker容器数据卷

 

1. 什么是容器数据卷

先来看看Docker的理念:

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

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

2. 容器数据卷能做什么

  1. 容器数据的持久化
  2. 容器之间继承和共享数据

3. 添加数据卷的方式

3.1 直接使用命令添加

  • 语法:

docker run -it -v /宿主机目录:/容器内目录 centos /bin/bash

–privileged=true: 防止出现Permission denied

1
2
3
4
5
6
[root@localhost software]# docker run -it -d -p 9995:8080 -v /usr/local/software/tomcat_p_9995/:/usr/local/tomcat/webapps --privileged=true tomcat:8.5
1f53c5b786b9a57843e5fa714afb7d7b8151614b5c2f602029c14d1a229a417a
[root@localhost software]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f53c5b786b9 tomcat:8.5 "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:9995->8080/tcp hardcore_volhard
[root@localhost software]#
  • 查看容器卷是否挂载成功

"Source", "Destination"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost docs]# docker inspect 1f53c5b786b9
[
{
"Id": "1f53c5b786b9a57843e5fa714afb7d7b8151614b5c2f602029c14d1a229a417a",
...
"Mounts": [
{
"Type": "bind",
"Source": "/usr/local/software/tomcat_p_9995",
"Destination": "/usr/local/tomcat/webapps",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
...
}
]

3.2 使用DockerFile添加

1.创建文件夹docker

1
# mkdir docker

2.在文件夹docker中创建名为Dockerfile的文件

1
# vim Dockerfile

3.编写Dockerfile的文件

VOLUME ["/usr/local/tomcat/webapps"]是容器内的路径

1
2
3
4
5
6
#基于tomcat:8.5构造一个镜像
FROM tomcat:8.5
#加入容器卷
VOLUME ["/usr/local/tomcat/webapps"]
CMD echo "finished,--------success1"
CMD /bin/bash

4.使用Dockerfile生成自定义镜像

1
[root@localhost docker]# docker build -t mytomcat01:1.0 .

output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM tomcat:8.5
---> 0eed806285b5
Step 2/4 : VOLUME /usr/local/tomcat/webapps
---> Running in e9e49a42c671
---> cb2c0e6605ec
Removing intermediate container e9e49a42c671
Step 3/4 : CMD echo "finished,--------success1"
---> Running in eba00d668afc
---> fb505e1a2e79
Removing intermediate container eba00d668afc
Step 4/4 : CMD /bin/bash
---> Running in 773a1ba24d77
---> b14e2098d46d
Removing intermediate container 773a1ba24d77
Successfully built b14e2098d46d

查看生成的镜像

1
2
3
4
5
6
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat01 1.0 b14e2098d46d 4 seconds ago 533 MB
docker.io/tomcat 8.5 0eed806285b5 11 days ago 533 MB
docker.io/nginx latest f35646e83998 4 weeks ago 133 MB
docker.io/hello-world latest bf756fb1ae65 10 months ago 13.3 kB

5.使用docker inspect 容器ID查看容器卷

运行一个docker实例

1
# docker run -it -d -p 9991:8080 mytomcat01:1.0 /bin/bash
1
# docker inspect 1ea64d3c6cfa

output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
"Mounts": [
{
"Type": "volume",
"Name": "49928ccb30e83351c4f84ae9f50d272f275d3d2baa50a419b03e523a3fbcc96c",
"Source": "/var/lib/docker/volumes/49928ccb30e83351c4f84ae9f50d272f275d3d2baa50a419b03e523a3fbcc96c/_data",
"Destination": "/usr/local/tomcat/webapps",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "1ea64d3c6cfa",
"Domainname": "",
...

"Source": "/var/lib/docker/volumes/49928ccb30e83351c4f84ae9f50d272f275d3d2baa50a419b03e523a3fbcc96c/_data": 宿主机路径

"Destination": "/usr/local/tomcat/webapps": docker容器内路径

6.docker build命令

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
[root@localhost docker]# docker build --help

Usage: docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
--build-arg list Set build-time variables (default [])
--cache-from stringSlice Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--help Print usage
--isolation string Container isolation technology
--label list Set metadata for an image (default [])
-m, --memory string Memory limit
--memory-swap string Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt stringSlice Security options
--shm-size string Size of /dev/shm, default value is 64MB
-t, --tag list Name and optionally a tag in the 'name:tag' format (default [])
--ulimit ulimit Ulimit options (default [])
-v, --volume list Set build-time bind mounts (default [])

4,数据卷容器

4.1,作用

数据卷容器: 实现容器之间的数据共享

不同的容器都指向宿主机中的同一个路径,删除其中的一个容器不影响指向的宿主机中的路径

4.2,实例

  1. 创建Dockerfile

使用Dockerfile构造镜像,生成一个自定义的centos

1
2
3
4
5
6
# 基于centos构造一个镜像
FROM centos
# 加入容器卷
VOLUME ["/usr/local/mydata"]
CMD echo "finished successfully"
CMD /bin/bash
1
[root@localhost docker]# docker build -t mycentos01:1.0 .

output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME /usr/local/mydata
---> Running in 415dbf119a9b
---> db4f8cdb476f
Removing intermediate container 415dbf119a9b
Step 3/4 : CMD echo "finished successfully"
---> Running in 79454fdd84c2
---> a3a51fa2bd36
Removing intermediate container 79454fdd84c2
Step 4/4 : CMD /bin/bash
---> Running in 43561372addb
---> 9aea850e12d7
Removing intermediate container 43561372addb
Successfully built 9aea850e12d7
1
2
3
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos01 1.0 9aea850e12d7 5 seconds ago 215 MB
  1. 使用自己创建的镜像启动一个容器
1
2
3
4
[root@localhost docker]# docker run -it --name=centos1 mycentos01:1.0 /bin/bash

[root@localhost docker]# docker run -it -d --name=centos3 --volumes-from centos2 mycentos01:1.0 /bin/bash

--volumes-from: 继承

使用自己创建的镜像启动第二个容器继承第一个

1
[root@localhost docker]# docker run -it -d --name=centos2 --volumes-from centos1 mycentos01:1.0 /bin/bash

使用自己创建的镜像启动第三个容器继承第二个

1
[root@localhost docker]# docker run -it -d --name=centos3 --volumes-from centos2 mycentos01:1.0 /bin/bash

output:

1
2
3
4
5
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00bc4c3a9b49 mycentos01:1.0 "/bin/bash" 4 seconds ago Up 3 seconds centos3
43dabcee22ec mycentos01:1.0 "/bin/bash" About a minute ago Up About a minute centos2
4a0a0d288acf mycentos01:1.0 "/bin/bash" 4 minutes ago Up 4 minutes centos1
  1. 测试方法

进入centos1,在mydata里面创建个centos1.txt

1
2
3
4
5
[root@localhost docker]# docker exec -it centos1 /bin/bash
[root@4a0a0d288acf mydata]# touch centos1.txt
[root@4a0a0d288acf mydata]# echo "make file in centos1" > centos1.txt
[root@4a0a0d288acf mydata]# cat centos1.txt
make file in centos1

进入centos2,查看mydata里面也有centos1.txt,在centos2的mydata里面创建centos2.txt

1
2
3
4
5
6
7
8
9
10
11
[root@localhost docker]# docker exec -it centos2 /bin/bash
[root@43dabcee22ec /]# cd /usr/local/mydata/
[root@43dabcee22ec mydata]# ls
centos1.txt
[root@43dabcee22ec mydata]# cat centos1.txt
make file in centos1
[root@43dabcee22ec mydata]# echo "make file in centos2" > centos2.txt
[root@43dabcee22ec mydata]# ls
centos1.txt centos2.txt
[root@43dabcee22ec mydata]# cat centos2.txt
make file in centos2

进入centos3查看mydata里面的数据,可以找到centos1.txt和centos2.txt

1
2
3
4
5
6
7
[root@localhost docker]# docker exec -it centos3 /bin/bash
[root@00bc4c3a9b49 /]# cd /usr/local/mydata/
[root@00bc4c3a9b49 mydata]# ls
centos1.txt centos2.txt
[root@00bc4c3a9b49 mydata]# echo "make file in centos3" > centos3.txt
[root@00bc4c3a9b49 mydata]# ls
centos1.txt centos2.txt centos3.txt

在centos1里也可以找到centos2.txt和centos3.txt

1
2
3
4
[root@localhost docker]# docker exec -it centos1 /bin/bash
[root@4a0a0d288acf /]# cd /usr/local/mydata/
[root@4a0a0d288acf mydata]# ls
centos1.txt centos2.txt centos3.txt

删除os1之后情况,centos2和centos3的mydata里面的数据不会发生变化,因为不同的容器都指向宿主机中的同一个路径,删除其中的一个容器不影响其他容器指向的宿主机中的路径

1
2
3
4
5
6
7
8
9
10
[root@localhost docker]# docker rm -f centos1
centos1
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00bc4c3a9b49 mycentos01:1.0 "/bin/bash" 15 minutes ago Up 15 minutes centos3
43dabcee22ec mycentos01:1.0 "/bin/bash" 16 minutes ago Up 16 minutes centos2
[root@localhost docker]# docker exec -it centos2 /bin/bash
[root@43dabcee22ec /]# cd /usr/local/mydata/
[root@43dabcee22ec mydata]# ls
centos1.txt centos2.txt centos3.txt