Dockerfile 中的 volume 与 docker run -v 的区别

简介: Dockerfile 中的 volume 与 docker run -v 的区别

Dockerfile 之 volume

定义镜像启动时容器内需要持久化的路径

docker run 之 -v 参数

启动镜像时指定需要持久化的路径

乍一看,没啥区别,请听我一一道来

敲黑板

如果 Dockerfile 内指定了 volume,并且 docker run -v 参数指向了和 volume 配置的路径一致时, -v 参数会将宿主机路径下的文件覆盖掉 volume 配置的路径下的文件

如果 Dockerfile 内指定了 volume,并且 docker run -v 参数没有指向和 volume 配置的路径一致时,-v 参数会将容器内的文件映射到宿主机上,而 Dockerfile 指定的 volume 仍然被指向 docker 数据存储路径下的 volumes 路径下

如何确定镜像内是否有指定 volume

docker inspect <镜像id> | grep Volumes -A 1
如果有指定 volume ,则会返回容器内的路径,例如:
            "Volumes": {
                "/var/log": {}
--
            "Volumes": {
                "/var/log": {}
如果没有指定 volume ,则会返回如下内容
            "Volumes": null,
            "WorkingDir": "",
--
            "Volumes": null,
            "WorkingDir": "",

实践出真知

docker 安装时,默认的数据存储路径在 /var/lib/docker ,如果自己的 docker 在安装时,设置了数据存储路径,需要替换掉文档内展示的 /var/lib/docker ,否则会找不到目录

准备一个 Dockerfile

FROM centos:7
VOLUME /var/log
RUN echo '/usr/bin/sleep 315360000' > start.sh && \
    chmod +x start.sh
CMD ["/usr/bin/bash","start.sh"]
生成新的镜像
docker build -t centos:volume_test .

有 volume 参数,docker run 时不加 -v 参数

启动带有 volume 的镜像
docker run -d --name test_volume centos:volume_test
查看 volume 默认挂载的路径
docker inspect test_volume | grep Source
有一个单独的 volumes 目录来提供给容器使用
"Source": "/var/lib/docker/volumes/05e5ce2c4e8fbdd13313c2ea643bb3a6732308085686fb58a2a885872fe54b88/_data",
查看目录下的文件
ls -l /var/lib/docker/volumes/05e5ce2c4e8fbdd13313c2ea643bb3a6732308085686fb58a2a885872fe54b88/_data
可以看到,默认的 centos 容器的 /var/log 目录下有这些内容,等下后面我们验证一下 -v 参数的小细节,验证是否会覆盖容器内的内容
total 40
-rw------- 1 root utmp     0 Nov 13  2020 btmp
-rw-r--r-- 1 root root   193 Nov 13  2020 grubby_prune_debug
-rw-r--r-- 1 root root 23944 Nov 13  2020 lastlog
-rw------- 1 root root  5248 Nov 13  2020 tallylog
-rw-rw-r-- 1 root utmp     0 Nov 13  2020 wtmp
-rw------- 1 root root  1430 Nov 13  2020 yum.log
删除容器,查看目录是否还存在

下面的方式比较暴力,练习环境无所谓,重要环境需要 one two three 然后再 go [ 三思而后行 ]

docker rm -f test_volume
查看之前的 volume 映射的路径,可以看到,文件信息都还存在
ls -l /var/lib/docker/volumes/05e5ce2c4e8fbdd13313c2ea643bb3a6732308085686fb58a2a885872fe54b88/_data

有 volume 参数,docker run 时加 -v 参数


-v 挂载的路径和 volume 的路径一致时

启动带有 volume 的镜像
mkdir -p /data/log
docker run -d -v /data/log:/var/log --name test_volume_v centos:volume_test
造点数据,方便验证
echo 'test' > /data/log/test.log
再次查看,可以看到,映射到我们指定的路径了
docker inspect test_volume_v | grep Source
验证一下我们之前的敲黑板
docker exec -it test_volume_v ls -l /var/log
此时,只剩下我们前面造的数据了,之前的那些文件都被宿主机的 /data/log 给覆盖了
total 4
-rw-r--r-- 1 root root 5 Jul 24 06:36 test.log

-v 挂载的路径和 volume 的路径不一致时

启动容器之前,我们先去查看 /var/lib/docker/volume 目录下的情况
ls -l /var/lib/docker/volumes/
因为我的是新环境,所以目录下很干净,只有一个前面实验生成的数据目录
total 24
drwx-----x 3 root root     19 Jul 24 14:42 05e5ce2c4e8fbdd13313c2ea643bb3a6732308085686fb58a2a885872fe54b88
brw------- 1 root root 253, 0 Jul 24 14:18 backingFsBlockDev
drwx-----x 3 root root     19 Jul 24 14:34 log
-rw------- 1 root root  32768 Jul 24 14:42 metadata.db
启动一个新的容器,这里图省事,就挂在给容器内的 /etc 目录了, 实际生产不可取!!!
mkdir -p /data/etc
docker run -d -v /data/etc:/etc --name test_volume_vo centos:volume_test
查看挂载的路径
docker inspect test_volume_vo | grep Source
可以看到,有两个路径,一个是 -v 参数挂载的,一个是 volume 指定的
"Source": "/data/etc",
"Source": "/var/lib/docker/volumes/364e98d44e8a3a4f5bef17a8206e3b3920db85113d45f1d7db6485a932d1c1bf/_data",
可以看到,和第一个实验展现的结果是一样的
ls -l /var/lib/docker/volumes/364e98d44e8a3a4f5bef17a8206e3b3920db85113d45f1d7db6485a932d1c1bf/_data
查看容器内的 /etc 目录
docker exec -it test_volume_vo ls -l /etc
可以看到有三个文件 [ 如果本地造了数据,也会出现在容器内,容器内的文件和宿主机文件是共存的 ]
total 12
-rw-r--r-- 1 0 0  13 Jul 24 06:51 hostname
-rw-r--r-- 1 0 0 174 Jul 24 06:51 hosts
-rw-r--r-- 1 0 0  73 Jul 24 06:51 resolv.conf
看一下宿主机的路径,验证文件是否和容器内的一致
ls -l /data/etc/
删除容器,验证两个不同的目录映射的数据是否都还存在

下面同样是暴力执法,未成年请在家长的陪同下验证

docker rm -f test_volume_vo
最终的结果就不用多展示了,两个数据映射目录都是存在的

总结

书写 Dockerfile 的时候,最好是提前考虑是否有数据持久化的场景,是否需要配置 volume 来保证数据的安全

启动一个 docker 时,最好是先 inspect 过滤一下是否配置了 volume ,避免 -v 参数覆盖了容器内的文件

目录
相关文章
|
3月前
|
Kubernetes 调度 虚拟化
Kubernetes和Docker有什么区别
【10月更文挑战第18天】Kubernetes和Docker有什么区别
|
22天前
|
NoSQL Java Linux
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
205 75
|
7天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
56 11
|
20天前
|
存储 Kubernetes Docker
Kubernetes(k8s)和Docker Compose本质区别
理解它们的区别和各自的优势,有助于选择合适的工具来满足特定的项目需求。
103 19
|
2月前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
1590 12
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
1月前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
70 9
|
2月前
|
应用服务中间件 PHP nginx
Docker-compose 编排lnmp(dockerfile) 完成Wordpress
通过使用Docker Compose,我们可以轻松编排LNMP环境并部署WordPress。本文详细介绍了各组件的Dockerfile和配置文件编写,并通过docker-compose.yml文件实现了整个环境的自动化部署。这种方法不仅简化了部署过程,还提高了环境的可移植性和一致性。希望本文能帮助你更好地理解和使用Docker Compose来管理和部署复杂的应用程序。
143 3
|
2月前
|
安全 Linux 虚拟化
LXD如何使用,跟Docker的区别都有什么?优点和缺点都有什么?
【10月更文挑战第28天】LXD如何使用,跟Docker的区别都有什么?优点和缺点都有什么?
215 1
|
3月前
|
存储 关系型数据库 MySQL
|
3月前
|
Docker 容器
docker中使用Dockerfile自动创建数据卷
【10月更文挑战第12天】
43 5