深入理解 Docker Volume
如果想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的。Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并重新启动通过该镜像启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为 Union File System (联合文件系统)。
为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。
我们可以通过两种方式来初始化Volume,这两种方式有些细小而又重要的差别。我们可以在运行时使用 -v
来声明Volume:
$ docker run -it --name container-test -h CONTAINER -v /data debian /bin/bash root@CONTAINER:/# ls /data root@CONTAINER:/#
上面的命令会将 /data
挂载到容器中,并绕过联合文件系统,我们可以在主机上直接操作该目录。任何在该镜像 /data
路径的文件会将被复制到Volume。我们可以使用 docker inspect
命令找到Volume在主机上的存储位置:
$ docker inspect -f {{.Volumes}} container-test
你会看到类似的输出:
map[/data:/var/lib/docker/vfs/dir/cde167197ccc3e138a14f1a4f...b32cec92e79059437a9]
这说明Docker把在 /var/lib/docker
下的某个目录挂载到了容器内的 /data
目录下。让我们从主机上添加文件到此文件夹下:
$ sudo touch /var/lib/docker/vfs/dir/cde167197ccc3e13814f...b32ce9059437a9/test-file
进入我们的容器内可以看到:
$ root@CONTAINER:/# ls /data test-file
只要将主机的目录挂载到容器的目录上,那改变就会立即生效。我们可以在Dockerfile中通过使用 VOLUME
指令来达到相同的目的:
FROM debian:wheezy VOLUME /data
但还有另一件只有 -v
参数能做到而Dockerfile是做不到的事是在容器上挂载指定的主机目录。例如:
$ docker run -v /home/adrian/data:/data debian ls /data
该命令将挂载主机的 /home/adrian/data
目录到容器内的 /data
目录上。任何在 /home/adrian/data
目录的文件都将会出现在容器内。这对于在主机和容器之间共享文件是非常有帮助的,例如挂载需要编译的源代码。为了保证可移植性(并不是所有的系统的主机目录都是可以用的),挂载主机目录不需要从Dockerfile指定。当使用 -v
参数时,镜像目录下的任何文件都不会被复制到Volume中。(译者注:Volume会复制到镜像目录,镜像不会复制到卷)
数据共享
如果要授权一个容器访问另一个容器的Volume,我们可以使用 -volumes-from
参数来执行 docker run
。
$ docker run -it -h NEWCONTAINER --volumes-from container-test debian /bin/bash root@NEWCONTAINER:/# ls /data test-file root@NEWCONTAINER:/#
值得注意的是不管container-test是否运行,它都会起作用。只要有容器连接Volume,它就不会被删除。
数据容器
常见的使用场景是使用纯数据容器来持久化数据库、配置文件或者数据文件等。 官方的文档 上有详细的解释。例如:
$ docker run --name dbdata postgres echo "Data-only container for postgres"
该命令将会创建一个包含已经在Dockerfile里定义过Volume的postgres镜像,运行 echo
命令然后退出。当我们运行 docker ps
命令时, echo
可以帮助我们识别某镜像的用途。我们可以用 -volumes-from
命令来其它容器的Volume:
$ docker run -d --volumes-from dbdata --name db1 postgres
使用数据容器的两个注意点:
- 不要运行数据容器,这纯粹是在浪费资源。
- 不要为了数据容器而使用“最小的镜像”,如
busybox
或scratch
,只使用数据库镜像本身就可以了。你已经拥有该镜像,所以并不需要占用额外的空间。
备份
如果你在用数据容器,那做备份相当容易:
$ docker run --rm --volumes-from dbdata -v $(pwd):/backup debian tar cvf /backup/backup.tar /var/lib/postgresql/data
该示例应该会将Volume里所有的东西压缩为一个tar包(官方的postgres Dockerfile在/var/lib/postgresql/data目录下定义了一个Volume)
权限与许可
通常你需要设置Volume的权限或者为Volume初始化一些默认数据或者配置文件。要注意的关键点是,在Dockerfile的 VOLUME
指令后的任何东西都不能改变该Volume,比如:
FROM debian:wheezy
RUN useradd foo
VOLUME /data
RUN touch /data/x
RUN chown -R foo:foo /data
该Docker file如预期那样运行,我们本来希望 touch
命令在镜像的文件系统上运行,但是实际上它是在一个临时容器的Volume上运行。如下所示:
FROM debian:wheezy
RUN useradd foo
RUN mkdir /data && touch /data/x
RUN chown -R foo:foo /data
VOLUME /data
Docker可以将镜像中Volume下的文件挂载到Volume下,并设置正确的权限。如果你指定Volume的主机目录将不会出现这种情况。
如果你没有通过 RUN
指令设置权限,那么你就需要在容器启动时使用 CMD
或 ENTRYPOINT
指令来执行(译者注:CMD指令用于指定一个容器启动时要运行的命令,与RUN类似,只是RUN是镜像在构建时要运行的命令)。
删除Volumes
这个功能可能会更加重要,如果你已经使用 docker rm
来删除你的容器,那可能有很多的孤立的Volume仍在占用着空间。
Volume只有在下列情况下才能被删除:
- 该容器可以用
docker rm -v
来删除且没有其它容器连接到该Volume(以及主机目录是也没被指定为Volume)。注意,-v
是必不可少的。 -
docker run
中使用rm
参数
除非你已经很小心的,总是像这样来运行容器,否则你将会在 /var/lib/docker/vfs/dir
目录下得到一些僵尸文件和目录,并且还不容易说出它们到底代表什么。
相关推荐
本文将基于有容云技术实施团队的原创分享内容,深入探讨Docker Volume Plugin的内幕,帮助读者更好地理解Docker中的存储机制。 首先,Docker容器对持久化存储的需求是一个关键点。由于生产环境中应用数据的安全、...
本教程将深入探讨Docker中的数据持久化方法,特别是关于"data volume"的使用。 一、Docker 数据管理概述 在Docker中,数据管理是一个关键问题,因为容器本身是临时性的,当容器停止或删除时,其内部的数据也会丢失...
在本集"Docker学习视频"中,主讲人马永亮深入讲解了Docker的核心概念之一——存储卷(Data Volume)。存储卷是Docker提供的一种机制,用于在容器之间持久化和共享数据,确保数据独立于容器的生命周期,即使容器被...
最后,文章深入探讨了权限管理和性能优化的方法,帮助用户在实际项目中高效使用Docker文件共享技术。 适合人群:具备一定Docker基础知识的技术人员、软件开发和运维人员。 使用场景及目标:①解决Docker容器与宿主机...
Docker的持久化存储和数据共享是容器技术中至关重要的概念,它们确保了在容器运行过程中产生的数据得以保存,即使容器被停止或删除。...正确理解和使用这些机制对于在Docker环境中有效地管理和保护数据至关重要。
通过深入研究 bitnami-docker-configmap-reload 的源码,开发者不仅可以了解到 Kubernetes 配置管理的最佳实践,还能掌握如何编写监控和通知服务的代码,提升 Kubernetes 环境下的应用运维能力。
为了深入理解Kubernetes的架构,还需要了解以下几个核心概念: 1. **Pods**:Kubernetes中最基本的可部署单元。一个Pod可以包含一个或多个容器,这些容器共享存储卷和网络资源,并在同一主机上运行。Pods提供了一种...
在IT行业中,Docker和Kubernetes(简称k8s)是两种非常重要的容器化和编排工具,它们在云计算...通过深入学习这些资料,读者将能够全面理解k8s集群的构建和管理,从而在实际工作中更高效地利用这一强大的容器编排平台。
这里我们将深入探讨两种主要的存储机制:volume 和 bind mount,以及一种特殊形式的 volume——volume container。 首先,我们来看**volume**。Volume 是 Docker 中推荐的数据持久化方式,因为它独立于容器存在,...
本文将深入探讨Docker与微服务的关系,介绍如何利用阿里云容器服务进行微服务应用的架构设计。 首先,让我们理解Docker的核心概念。Docker是一种开源的应用容器引擎,它允许开发者打包他们的应用及其依赖环境到一个...
Docker Python API 是一个强大的工具,它允许开发者通过Python编程接口与Docker守护进程进行交互,从而实现自动化部署、管理容器以及执行各种Docker相关的...希望这个教程对你理解和使用Docker Python API有所帮助!
首先,让我们了解Docker Compose。Docker Compose是一个用于定义和运行多容器Docker应用的工具。通过一个`docker-compose.yml`文件,我们可以配置服务、网络和卷,使得在本地开发环境或者小规模测试环境中轻松地启动...
在Volume 2中,你将深入了解到以下关键知识点: 1. **Linux安装**:如何规划硬盘分区,选择合适的安装类型(如图形化或命令行安装),以及如何配置网络和用户账户。 2. **文件系统和文件管理**:理解Linux的目录...
交付运维工程师是负责将软件交付给用户,并确保软件的运维和持续运行的专业人员。在技术面试中,交付运维工程师通常会...一个交付运维工程师需要对这些知识点有深入的了解和实践经验,才能在面试中展示自己的专业能力。
在深入学习K8s之前,需要对以下几个概念有一定的了解: 1. **Docker**:Docker是一种轻量级的虚拟化技术,可以将应用程序及其依赖打包成容器,便于移植和部署。 2. **容器化**:容器化是将应用程序及其运行环境封装...
这个压缩包文件“kubernetes资料”显然包含了关于Kubernetes的学习资源,可能是文档、教程、示例代码等,帮助我们深入了解和掌握这个强大的云原生技术。 Kubernetes的核心概念包括: 1. **Pod**:Kubernetes的基本...