文章目录
- 0. 前言
- 1. 基本概念
- 1. 数据卷(Volume)
- 1.1 详情
- 1.2 适用场景
- 1.3 相关命令
- 2. 主机目录挂载(Mount)
- 2.1 详情
- 2.2 适用场景
- 2.3 相关命令
0. 前言
1. 基本概念
- 容器的读写层管理数据有什么特点(为什么需要volume/bind mounts等方式管理数据)
- 如果容器本身不存在了,那读写层存储的数据也不存在了。
- 容器外很难获取容器内读写层数据。
- 读写层数据与Host(宿主机)紧密相关,没法在其他机器上使用读写层数据。
- 读写层写入数据需要 storage drvier (使用 linux kernel 提供了 union filesystem)来管理文件系统,使得整体读写性能低于其他数据管理方式(如volume/bind mounts等)。
- 为了实现数据存储与共享,有两种方式:
- 数据卷(volumes):
- 数据保存在Host的文件系统中(默认路径
/var/lib/docker/volumes
) - 由Docker管理
- 非Docker进程不应该直接处理这部分数据
- 总体来说,应该尽可能使用 volumes。
- Volumes 的优势:
- 更容易备份与迁移
- 可使用 Docker CLI 来直接管理
- Linux 与 Windows 都能使用
- 更安全地在多个容器间共享
- 可以在云端保存
- IO 性能更高
- 目录挂载(bind mounts)
- 数据可以在Host的任意位置,甚至可能是Host的重要系统文件与目录。
- 非Docker进程也可以使用这些目录。
- 其他基本概念:
- 不管使用哪种方式,对于容器本身来说都是一样的,都是一个目录或一个本地文件。
- volumes/bind mounts/tmpfs mounts 的主要区别在于数据在Host中的位置,如下图。
1. 数据卷(Volume)
- 当将 empty volume 挂在到容器内非空目录时,目录内的文件将复制到 volume 中。
- 如果将非空 volume 挂在到非空目录中,那非空目录中的内容将被隐藏。
1.1 详情
- 由Docker创建并管理,数据保存在Host的固定目录上(默认
/var/lib/docker/volumes
) - volume 和 container 是解耦的,同一个volume可以挂载在多个 contrainer 上。
- volume 可以指定名称,也可以是匿名的(随机名称)
1.2 适用场景
- 多个容器共享数据。
- 宿主机没有固定的文件目录与文件系统。
- 希望将容器数据存储在云(而不是本地)。
- 希望在不同的宿主机之间共享数据。
- 希望更高的读写性能(即IO)。
1.3 相关命令
- 数据卷相关命令:docker volume create/inspect/ls/prune/rm,具体命令查看 官方文档 吧
- 使用数据卷:
- 本质就是在启动 docker 的时候加上数据卷信息,即
docker run
命令中的-v
与--mount
两个选项。 -
-v, --volume
后有三个参数,通过冒号分割,分别是 数据卷名称(必选)、docker路径(必选)以及可选参数。 --mount
:由若干 key-value 对组成,格式为--mount 'key1=value1,key2=value2,key3=value3...'
,key主要包括
-
type
:包括bind/volume/tmpfs
-
source/src
:volume的名称,如果是匿名volume则不需要输入该参数 -
destination/dst/target
:container中的目录地址 -
readonly
:只读参数,该参数没有value -
volume-opt
:其他参数。
- 使用举例
$ docker run -d \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest
$ docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest
docker inspect devtest
# 结果在 Mounts 中
# docker compose 中使用
version: "3.9"
services:
frontend:
image: node:lts
volumes:
- myapp:/home/node/app
volumes:
myapp:
2. 主机目录挂载(Mount)
- 将bind mount挂在到container非空目录时,container目录内原始文件、目录将被隐藏。
2.1 详情
- 本质就是将Host上的一个目录/文件映射到container中。
- container中不需要有对应的目录(猜测意思就是mount在container中的目录)
2.2 适用场景
- 共享Host的一些重要文件(如DNS配置)
- 在Host与Container之间共享源码以及一些相关环境,如maven的jar文件目录。
- 当Host的文件目录固定。
2.3 相关命令
- 与前面的 bind mounts 类似,也是在
docker run
命令中通过-v
或--mount
来指定绑定路径。 -
-v, --volume
:包括三个参数,通过冒号分割,分别是Host路径(必选)、container路径(必选)以及其他可选参数。 --mount
:由若干 key-value 对组成,格式为--mount 'key1=value1,key2=value2,key3=value3...'
,key主要包括
-
type
:包括bind/volume/tmpfs
-
source/src
:volume的名称,如果是匿名volume则不需要输入该参数 -
destination/dst/target
:container中的目录地址 -
readonly
:只读参数,该参数没有value -
bind-propagation
:其他参数。
- 使用举例
$ docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
$ docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest