`

深入理解 Docker Volume

 
阅读更多

 

深入理解 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 Volume Plugin的内幕,帮助读者更好地理解Docker中的存储机制。 首先,Docker容器对持久化存储的需求是一个关键点。由于生产环境中应用数据的安全、...

    Docker基础-22-volume-数据持久化之data volume.rar

    本教程将深入探讨Docker中的数据持久化方法,特别是关于"data volume"的使用。 一、Docker 数据管理概述 在Docker中,数据管理是一个关键问题,因为容器本身是临时性的,当容器停止或删除时,其内部的数据也会丢失...

    Docker学习视频(讲师马永亮)10集之第6集:存储卷

    在本集"Docker学习视频"中,主讲人马永亮深入讲解了Docker的核心概念之一——存储卷(Data Volume)。存储卷是Docker提供的一种机制,用于在容器之间持久化和共享数据,确保数据独立于容器的生命周期,即使容器被...

    深度解析Docker宿主机与容器间高效文件共享方案及其实现技巧

    最后,文章深入探讨了权限管理和性能优化的方法,帮助用户在实际项目中高效使用Docker文件共享技术。 适合人群:具备一定Docker基础知识的技术人员、软件开发和运维人员。 使用场景及目标:①解决Docker容器与宿主机...

    详解Docker的持久化存储和数据共享

    Docker的持久化存储和数据共享是容器技术中至关重要的概念,它们确保了在容器运行过程中产生的数据得以保存,即使容器被停止或删除。...正确理解和使用这些机制对于在Docker环境中有效地管理和保护数据至关重要。

    bitnami-docker-configmap-reload-源码.rar

    通过深入研究 bitnami-docker-configmap-reload 的源码,开发者不仅可以了解到 Kubernetes 配置管理的最佳实践,还能掌握如何编写监控和通知服务的代码,提升 Kubernetes 环境下的应用运维能力。

    Docker Kubernetes架构设计.pdf

    为了深入理解Kubernetes的架构,还需要了解以下几个核心概念: 1. **Pods**:Kubernetes中最基本的可部署单元。一个Pod可以包含一个或多个容器,这些容器共享存储卷和网络资源,并在同一主机上运行。Pods提供了一种...

    docker_pdf.rar

    在IT行业中,Docker和Kubernetes(简称k8s)是两种非常重要的容器化和编排工具,它们在云计算...通过深入学习这些资料,读者将能够全面理解k8s集群的构建和管理,从而在实际工作中更高效地利用这一强大的容器编排平台。

    容器存储实验手册1

    这里我们将深入探讨两种主要的存储机制:volume 和 bind mount,以及一种特殊形式的 volume——volume container。 首先,我们来看**volume**。Volume 是 Docker 中推荐的数据持久化方式,因为它独立于容器存在,...

    Docker部署微服务应用的架构设计

    本文将深入探讨Docker与微服务的关系,介绍如何利用阿里云容器服务进行微服务应用的架构设计。 首先,让我们理解Docker的核心概念。Docker是一种开源的应用容器引擎,它允许开发者打包他们的应用及其依赖环境到一个...

    docker python api 安装配置的详解

    Docker Python API 是一个强大的工具,它允许开发者通过Python编程接口与Docker守护进程进行交互,从而实现自动化部署、管理容器以及执行各种Docker相关的...希望这个教程对你理解和使用Docker Python API有所帮助!

    docker-compose-kubernetes:docker编写Rails kubernetes的模板

    首先,让我们了解Docker Compose。Docker Compose是一个用于定义和运行多容器Docker应用的工具。通过一个`docker-compose.yml`文件,我们可以配置服务、网络和卷,使得在本地开发环境或者小规模测试环境中轻松地启动...

    Using and Administering Linux.rar

    在Volume 2中,你将深入了解到以下关键知识点: 1. **Linux安装**:如何规划硬盘分区,选择合适的安装类型(如图形化或命令行安装),以及如何配置网络和用户账户。 2. **文件系统和文件管理**:理解Linux的目录...

    交付运维工程师面试题(3).pdf

    交付运维工程师是负责将软件交付给用户,并确保软件的运维和持续运行的专业人员。在技术面试中,交付运维工程师通常会...一个交付运维工程师需要对这些知识点有深入的了解和实践经验,才能在面试中展示自己的专业能力。

    K8S教程深入浅出PDF-资源

    在深入学习K8s之前,需要对以下几个概念有一定的了解: 1. **Docker**:Docker是一种轻量级的虚拟化技术,可以将应用程序及其依赖打包成容器,便于移植和部署。 2. **容器化**:容器化是将应用程序及其运行环境封装...

    kubernetes资料

    这个压缩包文件“kubernetes资料”显然包含了关于Kubernetes的学习资源,可能是文档、教程、示例代码等,帮助我们深入了解和掌握这个强大的云原生技术。 Kubernetes的核心概念包括: 1. **Pod**:Kubernetes的基本...

Global site tag (gtag.js) - Google Analytics