本地目录挂载
这种挂载存在一些匿名卷
本地目录挂载(Bind Mount)是 Docker 中的一种机制,它允许你将宿主机的文件或目录挂载到容器内的指定路径。这使得容器可以直接访问和修改宿主机上的文件或目录,通常用于数据共享、持久化存储或使用宿主机上的配置文件。
本地目录挂载的特点:
- 双向同步:容器和宿主机之间的数据是双向同步的,容器内对挂载目录的修改会直接反映在宿主机上,反之亦然。
- 持久化:与 Docker 卷类似,挂载的目录可以实现数据持久化,但与 Docker 卷不同,绑定挂载完全由宿主机的文件系统管理。
- 灵活性:允许你选择宿主机上的任何路径进行挂载,适合需要直接操作宿主机文件的场景。
使用 docker run
挂载本地目录
挂载的时候使用的是绝对路径
可以在创建容器时使用 --mount
或 -v
(--volume
)选项将宿主机的目录或文件挂载到容器内。
1. 使用 --mount
这是推荐的现代方式,语法清晰,适合复杂的挂载场景。
docker run -d --mount type=bind,source=<宿主机路径>,target=<容器路径> <镜像名>
type=bind
:表示使用绑定挂载。source=<宿主机路径>
:宿主机上的目录或文件路径。target=<容器路径>
:容器内的挂载点路径。
示例:
将宿主机的 /home/user/data
目录挂载到容器的 /app/data
目录:
docker run -d --mount type=bind,source=/home/user/data,target=/app/data nginx
2. 使用 -v
这是早期的方式,仍然广泛使用,但在处理更复杂的挂载场景时可读性不如 --mount
高。
docker run -d -v <宿主机路径>:<容器路径> <镜像名>
示例:
将宿主机的 /home/user/data
目录挂载到容器的 /app/data
目录:
docker run -d -v /home/user/data:/app/data nginx
挂载本地目录的常见参数
-
只读挂载:你可以使用
readonly
参数将宿主机的目录以只读模式挂载到容器,防止容器对目录进行写操作。示例:
docker run -d --mount type=bind,source=/home/user/config,target=/app/config,readonly nginx
-
挂载文件而非目录:你也可以挂载单个文件,而不仅仅是目录。
示例:
docker run -d --mount type=bind,source=/home/user/config/app.conf,target=/etc/app.conf nginx
-
临时文件系统(
tmpfs
)挂载:除了绑定宿主机目录,你还可以使用tmpfs
将临时文件系统挂载到容器内,所有数据都会保存在内存中。示例:
docker run -d --mount type=tmpfs,target=/app/tmp nginx
查看挂载的卷和目录
你可以使用 docker inspect
查看容器的详细信息,包括哪些目录被挂载:
docker inspect <容器ID或容器名>
这将返回 JSON 格式的输出,其中包含卷和挂载信息。
匿名卷
在 Docker 中,绑定挂载(Bind Mount)有时会涉及匿名卷的概念,尤其是当你使用 docker run
命令时,默认情况下 Docker 会为某些情况创建匿名卷,这些匿名卷可能会引起混淆。让我们来解释一下匿名卷的情况以及如何避免它们。
匿名卷的产生
匿名卷是在容器启动时,由 Docker 自动创建的未命名的卷。它们通常用于保存容器的持久化数据,但因为没有明确的名称,所以这些卷不易管理和跟踪。
什么时候会创建匿名卷?
匿名卷通常在以下情况下自动创建:
-
没有明确指定挂载目标:当 Docker 容器的某个路径(例如
/var/lib/mysql
)需要持久化存储时,如果没有为该路径明确指定挂载卷,Docker 会自动创建一个匿名卷。示例:
docker run -d mysql:latest
在这个例子中,MySQL 容器会在
/var/lib/mysql
保存数据库数据。因为没有明确为这个路径指定卷,Docker 会自动创建一个匿名卷并将其挂载到容器的/var/lib/mysql
。 -
使用
VOLUME
指令的镜像:如果镜像的Dockerfile
中包含了VOLUME
指令,并且你没有明确指定挂载路径,Docker 也会为这个路径创建匿名卷。示例: 在使用
VOLUME /data
指令构建的镜像时,如果你不手动指定挂载卷,Docker 将为/data
创建一个匿名卷。
如何避免匿名卷
为了避免 Docker 自动创建匿名卷,你可以明确指定数据卷或绑定挂载。这使你能更好地管理卷,避免不必要的匿名卷占用磁盘空间。
1. 使用命名卷
命名卷可以通过 Docker 命令明确指定,并且可以轻松管理和追踪。
示例:
docker run -d -v my_named_volume:/var/lib/mysql mysql:latest
在这个例子中,my_named_volume
是我们手动创建的卷,它将挂载到容器的 /var/lib/mysql
目录。这样可以避免 Docker 创建匿名卷。
2. 使用绑定挂载(Bind Mount)
通过绑定宿主机上的目录到容器中的路径,确保你完全控制数据的存储位置。
示例:
docker run -d --mount type=bind,source=/home/user/mysql-data,target=/var/lib/mysql mysql:latest
在这个例子中,宿主机上的 /home/user/mysql-data
目录被挂载到容器的 /var/lib/mysql
,确保了数据直接存储在宿主机指定的目录中,而不会创建匿名卷。
如何管理匿名卷
如果系统中已经产生了匿名卷,你可以通过以下步骤来查看和清理它们:
1. 查看匿名卷
使用 docker volume ls
可以列出所有卷,包括匿名卷。匿名卷通常没有名称,Docker 会生成一个随机的 ID 作为名称。
docker volume ls
输出示例:
DRIVER VOLUME NAME
local my_named_volume
local 1d9ae6879ec2d4d39172a8bb8a0a2b16f291d6eae1a2fdce93613fd74c446f9f # 匿名卷
2. 删除匿名卷
你可以通过 docker volume prune
删除所有未使用的卷,包括匿名卷:
docker volume prune
Docker 会提示你确认删除所有未使用的卷,输入 y
以继续。
如果你想手动删除某个特定的匿名卷,可以使用 docker volume rm <卷ID>
命令删除它:
docker volume rm 1d9ae6879ec2d4d39172a8bb8a0a2b16f291d6eae1a2fdce93613fd74c446f9f