Docker 学习笔记:存储篇
Docker 学习笔记:存储篇
本笔记聚焦 Docker 存储的两种机制:镜像层与 Data Volume。详细讲解 bind mount、docker managed volume、volume container 和 data-packed volume container 的用法,以及 volume 的备份、恢复、迁移与销毁。
22. Docker 的两类存储资源
Docker 为容器提供两种存放数据的资源:
- 由 storage driver 管理的镜像层与容器层
- Data Volume(数据卷)
22.1 storage driver 与分层结构
- 镜像由多个只读层堆叠,容器在最上面添加一个可写层。
- Copy-on-Write 特性:
- 新增数据直接写入容器层。
- 修改数据时,先将镜像层数据复制到容器层,再修改。
- 删除数据时,在容器层创建 whiteout 文件遮挡下层。
- 不同 storage driver(如 overlay2、aufs、devicemapper 等)实现分层存储,推荐使用 Linux 发行版默认 driver。
bash
$ docker info | grep "Storage Driver"
Storage Driver: overlay2
适用场景:无状态应用,如 busybox 工具箱,数据不需要持久化。
23. Data Volume 之 bind mount
Data Volume 是宿主机文件系统中的目录或文件,直接挂载到容器内,具有以下特点:
- 数据可永久保存,即使容器被删除。
- 可被多个容器共享。
23.1 bind mount 操作
将宿主机目录 $HOME/htdocs 挂载到 httpd 容器的 /usr/local/apache2/htdocs:
bash
$ mkdir ~/htdocs
$ echo '<html><body><h1>This is a file in host file system!</h1></body></html>' > ~/htdocs/index.html
$ docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
$ curl 127.0.0.1:80
<html><body><h1>This is a file in host file system!</h1></body></html>
更新内容(在宿主机修改文件):
bash
$ echo "updated index page!" > ~/htdocs/index.html
$ curl 127.0.0.1:80
updated index page!
容器删除后,bind mount 数据仍然保留:
bash
$ docker stop <容器ID> && docker rm <容器ID>
$ cat ~/htdocs/index.html
updated index page!
23.2 只读 bind mount
bash
$ docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd
$ docker exec -it <容器ID> bash
root@xxx:/usr/local/apache2# echo "test" > htdocs/index.html
bash: htdocs/index.html: Read-only file system
23.3 绑定单个文件
bash
$ docker run -d -p 80:80 -v ~/htdocs/index.html:/usr/local/apache2/htdocs/new_index.html httpd
$ curl 127.0.0.1:80/new_index.html
updated index page!
注意:宿主机源文件必须存在,否则会被当作目录创建。
特点:
- 路径可任意指定。
- 会隐藏容器内原有挂载点内容,替换为宿主机内容。
- 移植性较弱(依赖宿主机特定路径)。
24. Data Volume 之 docker managed volume
使用 -v 只指定容器内路径,不指定宿主机路径,Docker 会自动在 /var/lib/docker/volumes/ 下创建 volume。
bash
$ docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
$ docker inspect <容器ID>
"Mounts": [
{
"Type": "volume",
"Name": "1cc915096121dea197bbbb93fc90e6491d530e0c9e2ace1de07e2a635e569d16",
"Source": "/var/lib/docker/volumes/1cc915096121dea197bbbb93fc90e6491d530e0c9e2ace1de07e2a635e569d16/_data",
"Destination": "/usr/local/apache2/htdocs",
...
}
]
特点:
- 路径由 Docker 自动管理,移植性好。
- 容器原有数据会被复制到 volume 中(若挂载点有数据)。
- 不支持单个文件,只能是目录。
- 读写权限不可控(均为读写)。
常用命令:
bash
$ docker volume ls # 列出所有 volume
$ docker volume inspect <volume名> # 查看 volume 详情
$ docker volume prune # 删除所有未使用的 volume
bind mount 与 docker managed volume 对比
| 特性 | bind mount | docker managed volume |
|---|---|---|
| volume 位置 | 任意指定 | /var/lib/docker/volumes/... |
| 对已有 mount point 影响 | 隐藏并替换 | 原有数据复制到 volume |
| 是否支持单个文件 | 支持 | 不支持(仅目录) |
| 权限控制 | 可设只读 | 无控制,均为读写 |
| 移植性 | 弱,依赖 host path | 强,无需指定 host 目录 |
25. 如何共享数据
25.1 容器与宿主机共享数据
bind mount 直接共享;docker managed volume 可通过 docker cp 或直接操作 /var/lib/docker/volumes/ 目录传输数据。
bash
$ docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
$ docker cp ~/htdocs/index.html <容器ID>:/usr/local/apache2/htdocs
$ curl 127.0.0.1:80
updated index page!
25.2 容器之间共享数据(bind mount)
创建三个 httpd 容器,都挂载同一宿主机目录:
bash
$ docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
$ docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
$ docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
$ echo "shared by bind mount" > ~/htdocs/index.html
$ curl 127.0.0.1:<web1端口>
shared by bind mount
26. 用 volume container 共享数据
volume container 是专门为其他容器提供 volume 的容器,其本身不必运行。
26.1 创建 volume container
bash
$ docker create --name vc_data \
-v ~/htdocs:/usr/local/apache2/htdocs \
-v /other/useful/tools \
busybox
此容器挂载了两个 volume:一个 bind mount,一个 docker managed volume。
26.2 其他容器使用 --volumes-from
bash
$ docker run --name web1 -d -p 80 --volumes-from vc_data httpd
$ docker run --name web2 -d -p 80 --volumes-from vc_data httpd
$ docker run --name web3 -d -p 80 --volumes-from vc_data httpd
$ docker inspect web1 # 查看 Mounts,与 vc_data 的 volume 相同
优点:
- 解耦容器与宿主机路径,所有 volume 定义集中在 volume container。
- 挂载点一致,配置规范。
27. data-packed volume container
将数据直接打包进镜像,并通过 VOLUME 指令自动创建 docker managed volume,使数据完全自包含。
27.1 构建 data-packed 镜像
dockerfile
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs
bash
$ echo "This content is from a data packed volume container!" > htdocs/index.html
$ docker build -t datapacked .
27.2 使用 data-packed volume container
bash
$ docker create --name vc_data datapacked
$ docker run -d -p 80:80 --volumes-from vc_data httpd
$ curl 127.0.0.1:80
This content is from a data packed volume container!
优点:移植性极强,不依赖宿主机任何数据。
适用场景:静态数据(配置、网页文件等)。
28. volume 生命周期管理
28.1 备份
volume 实质是宿主机目录,备份即备份对应目录文件。
28.2 恢复
将备份数据拷贝回原 volume 目录即可。
28.3 迁移
bash
# 停止原容器
$ docker stop <容器ID>
# 使用相同 volume 挂载启动新版本容器
$ docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:latest
28.4 销毁
-
bind mount:Docker 不会删除,需宿主机手动处理。
-
docker managed volume:
-
删除容器时加
-v:docker rm -v <容器ID>(前提是无其他容器使用该 volume)。 -
孤儿 volume 的清理:
bash
$ docker volume ls $ docker volume rm <volume名> $ docker volume prune # 批量删除未使用的 volume
-
29. 知识点速查表
29.1 两种存储资源对比
| 类型 | 管理方式 | 持久性 | 适用场景 |
|---|---|---|---|
| 镜像层与容器层 | storage driver (overlay2 等) | 容器删除即丢失 | 无状态应用 |
| Data Volume | bind mount / docker managed volume | 持久 | 数据库、日志、配置等有状态数据 |
29.2 Data Volume 类型对比
| 特性 | bind mount | docker managed volume |
|---|---|---|
| 创建方式 | -v 宿主机路径:容器路径 |
-v 容器路径 |
| 位置 | 任意指定 | /var/lib/docker/volumes/<id>/_data |
| 移植性 | 弱 | 强 |
| 权限控制 | 支持只读 | 不支持 |
| 单文件挂载 | 支持 | 不支持 |
29.3 数据共享方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| bind mount 多容器挂载 | 直接、灵活 | 依赖宿主机路径,移植性差 |
| volume container | 解耦路径,配置集中 | 需额外容器 |
| data-packed volume container | 完全自包含,可移植性最高 | 仅适合静态数据 |
29.4 常用 volume 管理命令
| 命令 | 功能 |
|---|---|
docker volume ls |
列出所有 volume |
docker volume create <name> |
创建命名 volume |
docker volume inspect <name> |
查看 volume 详情 |
docker volume rm <name> |
删除 volume |
docker volume prune |
删除所有未使用的 volume |
docker run -v <宿主机路径>:<容器路径> |
bind mount |
docker run -v <容器路径> |
docker managed volume |
docker run --volumes-from <容器> |
使用其他容器的 volume |
docker rm -v <容器> |
删除容器并删除其独占 volume |
存储章节到此结束,接下来将进入容器监控与日志管理的学习。
更多推荐

所有评论(0)