目录
一、产生原因
数据持久化问题
docker将运用与运行的环境打包形成容器运行,容器中产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了。 为了能保存数据在Docker中我们使用数据卷。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
数据卷特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
二、相关命令
1.简单例子
docker run -it -v 主机目录:容器目录
docker run -it -v /home/zhunian/testVolume:/home centos /bin/bash
在容器目录下创建test.java文件,再去主机目录下查看是否有该文件。
查看容器内部情况
docker inspect 容器id
2.常用命令
#创建数据卷
➜ ~ docker volume create my-vol
my-vol
#查看所有的数据卷
➜ ~ docker volume ls
DRIVER VOLUME NAME
local my-vol
#查看指定数据卷内部信息
➜ ~ docker volume inspect my-vol
[
{
"CreatedAt": "2022-04-13T18:47:34+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
#删除数据卷
➜ ~ docker volume rm my-vol
my-vol
#删除容器时候一起删除数据卷
docker rm -v 容器id
➜ ~ docker volume rm my-vol
my-vol
➜ ~ docker volume create my-vol
my-vol
#删除没有使用的数据卷(没有容器使用)
➜ ~ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
my-vol
Total reclaimed space: 0B
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷
mount命令
$ docker run -d -P \
--name web \
# -v /src/webapp:/opt/webapp:ro \
--mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \
training/webapp \
python app.py
加了readonly之后,就挂载为只读了。如果你在容器内/src/webapp目录新建文件,会显示如下错误
/src/webapp # touch new.txt
touch: new.txt: Read-only file system
3.具名挂载和匿名挂载
匿名挂载:指定数据卷的时候,不指定容器路径对应的主机路径。映射的主机路径就是默认的路径/var/lib/docker/volumes/中自动生成一个随机命名的文件夹。
# 匿名
➜ ~ docker run -d -P --name nginx01 -v /etc/nginx nginx
6bafee66436f3a45712916807890eb816bcb7c66ef0ad3d5d617c5af9992ebed
➜ ~ docker volume ls
DRIVER VOLUME NAME
local 0c7c80ceaa1e21318533b4e9d29de7a2b8a0264b70e0a0b1558dfa0a73aa76bd
#具名
➜ ~ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
df39c371c583c9b6edcf447d93e86064a75f5ff4b8a0e1b542651f6a6b220a7d
➜ ~ docker volume ls
DRIVER VOLUME NAME
local 0c7c80ceaa1e21318533b4e9d29de7a2b8a0264b70e0a0b1558dfa0a73aa76bd
local juming-nginx
#查看数据集内部信息
➜ ~ docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-04-13T19:01:33+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
匿名挂载,具名挂载,指定路径挂载的命令区别
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
指定数据卷映射的相关参数:
ro —— readonly 只读。设置了只读则只能操作宿主机的路径,不能操作容器中的对应路径。
rw —— readwrite 可读可写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
4.dockfile文件设置数据卷
# dockerfile文件构建镜像
# dockerfile文件
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#构建镜像
➜ dockfileTest docker build -t nginx:v2 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in cfa7f559e03d
Removing intermediate container cfa7f559e03d
---> 8d4db309bbe7
Step 3/4 : CMD echo "----end----"
---> Running in d545cf1da7ce
Removing intermediate container d545cf1da7ce
---> 7e59b4e08c9f
Step 4/4 : CMD /bin/bash
---> Running in d92788e5339a
Removing intermediate container d92788e5339a
---> 5a30ed51cbdd
Successfully built 5a30ed51cbdd
Successfully tagged nginx:v2
➜ dockfileTest docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 5a30ed51cbdd About a minute ago 231MB
# 查看一下镜像里面的信息 Volumes
➜ dockfileTest docker inspect 5a30ed51cbdd
[
{
......
"ContainerConfig": {
"Hostname": "d92788e5339a",
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"/bin/sh\" \"-c\" \"/bin/bash\"]"
],
"ArgsEscaped": true,
"Image": "sha256:7e59b4e08c9f7507a86baebbb6cb4a5bbf7b94ce2c6eb7f2aacf2f0477af0a7c",
"Volumes": {
"volume01": {},
"volume02": {}
},
},
# 运行镜像
➜ dockfileTest docker run -it nginx:v2 /bin/bash
[root@0ad3587947d9 /]# pwd
/
# 镜像里有volume01和volume02文件夹
[root@0ad3587947d9 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
#查看容器ID
➜ dockfileTest docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ad3587947d9 nginx:v2 "/bin/bash" About a minute ago Up About a minute flamboyant_mayer
#查看容器信息 Mounts
➜ dockfileTest docker inspect 0ad3587947d9
[
{
......
"Mounts": [
{
"Type": "volume",
"Name": "17efdc1bdfe52fd8029c8314985b6466349f95ee9c275099a5360ffeb1cc9b1b",
"Source": "/var/lib/docker/volumes/17efdc1bdfe52fd8029c8314985b6466349f95ee9c275099a5360ffeb1cc9b1b/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "f47318e80edc6b7ccc3b697debaa1cd54c2bae9105f810047fa4238b16f6150d",
"Source": "/var/lib/docker/volumes/f47318e80edc6b7ccc3b697debaa1cd54c2bae9105f810047fa4238b16f6150d/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
因为dockerfile中没有指定宿主机目录,所以属于匿名挂载,在/var/lib/docker/volumes/目录下生成了随机命名的路径。
5.容器数据卷
主要是参数--volumes-from
#启动容器1
➜ ~ docker run -it --name nginx1 nginx:v2
# 启动容器2
➜ ~ docker run -it --name nginx2 --volumes-from nginx1 nginx:v2
[root@daa21ba081ac /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@daa21ba081ac /]# cd volume01
[root@daa21ba081ac volume01]# ls
[root@daa21ba081ac volume01]# touch test.java
[root@daa21ba081ac volume01]# echo 'hello word' > test.java
#进入容器1 查看 Volume01目录下是否有内容
➜ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
daa21ba081ac nginx:v2 "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes nginx2
18ae65037620 nginx:v2 "/bin/sh -c /bin/bash" 5 minutes ago Up 4 minutes nginx1
➜ ~ docker exec -it 18ae65037620 /bin/bash
[root@18ae65037620 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@18ae65037620 /]# cd volume01
[root@18ae65037620 volume01]# ls
test.java
[root@18ae65037620 volume01]# cat test.java
hello word
[root@18ae65037620 volume01]#