【Docker】6. Docker数据卷配置

738 阅读4分钟

数据卷

英文译为:Volume,实现宿主机系统与容器之间的文件共享

数据卷和前文中cp命令不同,cp命令的作用只是单纯的将宿主机和容器内的文件进行相互复制,从整个隔离的角度上来说,两者之间没有任何关系。

如果我想让宿主机和某个容器共享一个目录,那么我就可以通过对宿主机的改变直接影响到容器内部。

数据卷特点

  • 数据卷可以在容器之间共享和重用。
  • 对数据卷的修改会立即影响到相关容器。
  • 对数据卷的修改不会影响到相关镜像(镜像是只读的)。
  • 数据卷默认会一直存在,即使容器被删除(除非手动删除数据卷)

数据卷本质

当宿主机中某个文件夹挂载了容器中某个文件夹之后,无论容器文件夹的内容是否复制一份进入宿主机,容器文件夹中的内容在数据卷没有删除之前都不会发生改变。因为在挂载数据卷之后,容器就再也不会读取该文件夹中的数据,而是会读取宿主机中映射的文件夹的数据

数据卷操作

1. 自定义挂载数据卷

必须在启动容器时挂载数据卷。

docker run -p 宿主机端口:容器内服务监听端口 -d --name 容器名称 -v 宿主机目录:容器内目录 镜像名:镜像版本 | 镜像ID

注意:

  • 宿主机目录和容器内目录必须都是绝对路径。
  • 如果宿主机目录或者容器内目录中有文件,会全部清空。
  • 如果使用自定义挂载数据卷,Docker会给该数据卷起一个随机数据卷名称。
  • 如果数据卷还在,原挂载容器已经被删除,若想获取数据卷中的数据,只需再挂载一个容器到该数据卷上即可。

如果想要宿主机可以修改数据卷内容,但是容器不能修改数据卷内容:

docker run -p 宿主机端口:容器内服务监听端口 -d --name 容器名称 -v 宿主机目录:容器内目录:ro 镜像名:镜像版本 | 镜像ID

ro指的是read only。

一个容器可以挂载若干个数据卷,只需添加若干组 -v 宿主机目录:容器内目录即可:

docker run -p 宿主机端口:容器内服务监听端口 -d --name 容器名称 -v 宿主机目录1:容器内目录1 -v 宿主机目录2:容器内目录2 镜像名:镜像版本 | 镜像ID

2. 自动挂载数据卷(建议使用)

如果在上述命令中的宿主机目录填写了一个类似于"aa"这样的东西,那么Docker遍历了整个宿主机系统都没有发现有aa的目录路径,那么Docker就会将"aa"当作数据卷的名称,在Docker的volumes文件夹中自动创建aa目录,并将aa目录与指定的容器内目录相映射

自动数据卷有一个巨大的好处在于,由于在创建之前aa这个目录在宿主机中没有,那么如果容器内目录中原来有文件,Docker会将容器内文件全部拷贝到aa这个目录中

docker run -p 宿主机端口:容器内服务监听端口 -d --name 容器名称 -v 数据卷名称:容器内目录 镜像名:镜像版本 | 镜像ID

3. 查看全部数据卷

docker volume ls

4. 查看数据卷详细信息

docker volume inspect 数据卷名称

5. 创建数据卷

docker volume create 数据卷名称

6. 删除未使用数据卷

docker volume prune

7. 删除指定数据卷

docker volume rm 数据卷名称

数据卷应用场景

自定义挂载数据卷:当我们想对容器内的文件进行写操作时,建议自定义挂载数据卷。

自动挂载数据卷

如果我们不想动容器内的文件,也就是不对容器内的文件进行写操作,但是我们想把容器中的资源保存在宿主机中,这时可以自动挂载数据卷。

例如,我们在使用MySQL、Redis时,MySQL的数据是保存在容器内的,很不安全,当容器被删除,容器中的所有数据都会丢失。所以我们希望在MySQL启动的时候就将数据全部持久化一份到宿主机中,这样对容器的数据修改不会影响到宿主机的数据,假设容器被删除了,那么我完全可以再创建一个容器开启MySQL,然后MySQL挂载宿主机的目录,就可以让MySQL获取原来的数据启动了,这样保证了在任何情况下数据都不会丢失。