文章目录
  • 🌟 前言
  • 1. 容器数据卷概念
  • 2. 数据卷挂载
  • 🍑 在命令行挂载数据卷
  • 🍑 通过Dockerfile挂载数据卷
  • 3. 数据卷容器
  • 4. 备份数据卷

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_学习

🌟 前言

在生产环境中使用 Docker 容器,往往需要对数据进行持久化保存,或者多个容器需要共享数据。
 
这时就会使用到容器数据卷,通过容器数据卷管理容器数据是一项使用容器的基本技能。
 
我将会用两篇文章,来详细介绍容器数据卷的使用及其相关内容。

1. 容器数据卷概念

容器技术使用 rootfs 机制与 Namespace,构建出与宿主机隔离开的文件系统。在用户使用 Docker 容器的时候,会产生一系列的数据文件。这些数据文件在 Docker 容器关闭时就会消失,但是其中部分数据是用户希望能够保存的。
 
Docker 将应用与运行环境打包成容器进行运行,用户希望在运行过程中产生的部分数据是可以持久化的,并且容器之间能够实现数据互通。这正是容器数据卷(Docker Volume)要解决的问题。
 
Docker 中的数据可以存储在类似于虚拟机磁盘的介质中,这种介质在 Docker 中称为数据卷。
 
数据卷以目录的形式呈现给 Docker,不仅可用来存储 Docker 应用的数据,还可以支持多个容器间数据共享,并且修改数据卷文件也不会影响镜像。在 Docker 中使用数据卷,就是在系统中挂载一个文件系统。
 
Docker 数据卷所使用的挂载技术,就是 Linux 的绑定挂载。其主要作用是,允许用户将一个目录或文件(并非整个设备),挂载到一个指定的目录上。
 
用户在该挂载点上进行的任何操作都只发生在被挂载的目录或文件上,而原挂载点的内容则会被隐藏起来且不受任何影响。容器利用数据卷与宿主机进行数据共享,从而实现容器间的数据共享与交换。

Docker 数据卷默认存储在宿主机的 /var/lib/Docker/volumes/ 目录下,也可以指定挂载到任意位置。这种挂载仅存储在宿主机的内存中,永远不会写入宿主机的文件系统。如图所示👇

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_数据_02

数据卷的特点如下

  1. 容器启动时初始化,如果容器使用的镜像包含数据卷,这些数据也会复制到数据卷中。
  2. 容器对数据卷的修改是直接生效的。
  3. 数据卷的变化不会影响镜像的更新,数据卷是独立于联合文件系统,镜像是基于联合文件系统,镜像与数据卷不会相互影响。
  4. 数据卷是宿主机中的一个目录,与容器生命周期隔离。

2. 数据卷挂载

🍑 在命令行挂载数据卷

docker createdocker run 命令中,使用 -v 为容器增加一个数据卷,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_面试_03


以上示例使用 docker run 命令运行了一个容器,并通过 -v 参数为容器添加了一个数据卷。下面通过命令查看挂载信息,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_面试_04


从以上示例中可以看到,宿主机已经在 /var/lib/Docker/volumes/ 下自动生成了挂载目录。下面通过命令行手动指定宿主机挂载目录,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_学习_05


以上示例在后台运行了一个被命名为 testNginx 容器,并为它挂载数据卷。下面查看容器 test 的状态及挂载数据信息,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_Docker_06


上述示例中,Mount 信息包含了上面创建的容器的详细挂载信息,Source 指定了本机路径,Destination 指定了容器内部的路径。下面通过示例观察数据卷共享机制,会在宿主机与容器端之间多次切换,建议开启两个终端,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_Docker_07


以上示例创建了一个名为 testNginx 容器,并将容器内的 /app 目录挂载至宿主机的 /web/webapp 路径下。下面分别查看宿主机与容器的根目录下的文件,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_数据_08


从以上示例中可以看到,宿主机的根目录下新建了一个 web 目录,而该目录下没有任何文件。下面在宿主机的 /web 目录下创建文件,并返回容器观察目录内容,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_Docker_09


从以上示例中可以看到,在宿主机的挂载目录下创建的文件也会在容器中出现。下面在容器中创建文件,并返回宿主机观察目录内容,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_学习_10


从以上示例中可以看出,Docker 数据卷能够实现 Docker 容器与宿主机间的数据共享,并且能够将容器中产生的数据永久保存下来,随时在宿主机查看与修改。

在生产环境中,容器服务的配置文件通常采用数据卷的方式挂载至容器内。为了防止容器内的误操作修改配置文件,在挂载时可以进行权限设置。这样就可以达到在宿主机修改代码,在容器内查看修改结果的目的。

下面创建容器并为数据卷设置权限,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_数据_11


以上示例创建了一个名为 volumeNginx 容器,并将挂载数据卷权限设置为 ro 只读。下面查看数据卷是否挂载成功,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_数据_12


从以上示例中可以看到,数据卷已经挂载成功,且宿主机挂载目录中没有任何文件。下面为宿主机目录中添加文件,并返回容器中查看效果,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_面试_13


从以上示例中可以看到,在容器挂载目录中可以查看文件内容。下面在容器挂载目录下的文件中修改内容,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_学习_14


以上示例中,在容器挂载目录中修改文件时发生报错,这是因为在容器中文件为只读类型,无法进行修改。下面在容器挂载目录中创建新的文件,示例代码如下:

ephemeral container 挂载宿主机目录 docker挂载宿主机命令_Docker_15


以上示例中,在容器挂载目录中创建文件时发生报错,这是因为在容器中挂载目录同样为只读类型,无法对其进行实质性的操作。

🍑 通过Dockerfile挂载数据卷

用户创建镜像时,通常会在 Dockerfile 文件中加上 VOLUME[/date] 来创建含有数据卷的镜像,并使用该镜像创建包含数据卷的容器。
 
Dockerfile 可以创建多个数据卷,与使用 docker run 命令创建数据卷不同,Dockerfile 中的数据卷不能映射到已经存在的本地目录。
 
在启动容器时,才会创建 Dockerfile 中指定的数据卷,并且以 Docker 中指定的名称命名。运行同样镜像的容器创建的数据卷是不一样的(可以看到不同容器的数据卷地址也是不一样的)。当容器中的数据卷地址不一样时,容器之间就无法共享数据了。