Docker 存储:镜像层与数据卷的管理应用
存储资源概览
Docker 为容器提供了两类存储资源:
- 由 storage driver 管理的镜像层和容器层。
- Data Volume(数据卷)。
storage driver:镜像与容器的分层存储
在镜像章节中已经了解到 Docker 镜像的分层结构。容器由最上层的可写容器层与下方多个只读镜像层组成,所有数据都存储在这些层中。这种设计最大的特点是 Copy-on-Write:
- 新数据直接写入最上层的容器层。
- 修改现有数据时,先从镜像层复制到容器层,修改后保存在容器层,镜像层保持不变。
- 如果多层中存在同名文件,只有最上层文件对用户可见。

分层结构使镜像和容器的创建、共享与分发变得高效,这一切都依赖于 storage driver。storage driver 负责实现多层数据的堆叠,并为用户提供统一的合并视图。
Docker 支持多种 storage driver,包括 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS。它们均能实现分层架构,但各有特点。
选择建议:优先使用 Linux 发行版默认的 storage driver。默认 driver 经过严格测试,稳定性最好。
使用 docker info 可查看当前系统的 storage driver:
bash
[root@docker ~]# docker info
...
Storage Driver: overlay2
Backing Filesystem: xfs
...
在 CentOS Stream 8 中,默认使用 overlay2,底层文件系统为 XFS,各层数据存放在 /var/lib/docker。
Data Volume:持久化存储方案
对于需要持久化数据的容器(如数据库、日志文件、应用数据),应使用 Data Volume。
Data Volume 本质上是宿主机文件系统中的目录或文件,可以直接挂载到容器的文件系统。其特点如下:
- 是目录或文件,而非未格式化的块设备。
- 容器可以对 volume 进行读写。
- 数据可永久保存,即使容器销毁。
bind mount
bind mount 将宿主机已有的目录或文件挂载到容器中。
示例:将宿主机的 ~/htdocs 挂载到 httpd 容器:
bash
[root@docker ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
通过 -v <host_path>:<container_path> 指定挂载路径。若容器内目标路径已存在,原有数据将被隐藏,取而代之的是宿主机的数据。
权限控制 :可设置为只读模式(ro):
bash
[root@docker ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd
特点:
- 移植性较弱,依赖于宿主机路径。
- 支持目录和文件挂载。
- 适合需要固定路径访问的场景。
docker managed volume
docker managed volume 无需指定宿主机路径,只需指定容器内的挂载点:
bash
[root@docker ~]# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
volume 的实际位置可通过 docker inspect 查看:
bash
[root@docker ~]# docker inspect <container_id>
docker managed volume 位于 /var/lib/docker/volumes/<volume_id>/_data。
如果挂载点目录已存在,原有数据将被复制到 volume 中。
特点:
- 移植性强,不绑定宿主机路径。
- 仅支持目录挂载。
- 适合需要动态管理存储的场景。
数据共享策略
容器与宿主机共享数据
- bind mount:直接挂载宿主机目录。
- docker managed volume :通过
docker cp或直接操作/var/lib/docker/volumes下的目录实现数据同步。
示例:
bash
[root@docker ~]# docker cp ~/htdocs/index.html <container_id>:/usr/local/apache2/htdocs
容器之间共享数据
方式一:共享 bind mount
将同一宿主机目录挂载到多个容器:
bash
[root@docker ~]# docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
[root@docker ~]# docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
方式二:volume container
创建专门提供 volume 的容器:
bash
[root@docker ~]# docker create --name vc_data \
-v ~/htdocs:/usr/local/apache2/htdocs \
-v /other/useful/tools \
busybox
其他容器通过 --volumes-from 共享:
bash
[root@docker ~]# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
方式三:data-packed volume container
将数据打包到镜像中,通过 docker managed volume 共享:
Dockerfile 示例:
dockerfile
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs
构建并启动:
bash
[root@docker ~]# docker build -t datapacked .
[root@docker ~]# docker create --name vc_data datapacked
[root@docker ~]# docker run -d -p 80:80 --volumes-from vc_data httpd
volume 生命周期管理
备份与恢复
volume 本质上是文件系统目录,备份即备份目录内容。例如,本地 Registry 数据位于 /myregistry:
bash
[root@docker ~]# docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2
定期备份 /myregistry 即可。恢复时直接将备份数据复制回该目录。
迁移
升级容器版本时,挂载原有 volume 即可实现数据迁移:
bash
[root@docker ~]# docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:latest
销毁
- bind mount:需手动删除宿主机目录。
- docker managed volume :删除容器时可使用
-v参数一并删除 volume:
bash
[root@docker ~]# docker rm -v <container_name>
若未使用 -v,会遗留孤儿 volume,可通过以下命令管理:
bash
# 列出所有 volume
[root@docker ~]# docker volume ls
# 删除指定 volume
[root@docker ~]# docker volume rm <volume_name>
# 批量删除孤儿 volume
[root@docker ~]# docker volume rm $(docker volume ls -q)
小结
- Docker 提供两类存储:数据层(镜像层与容器层)与 Data Volume。
- storage driver 管理分层存储,支持多种实现,默认选择系统推荐。
- Data Volume 分为 bind mount 与 docker managed volume,分别适用于固定路径与动态管理场景。
- 可通过共享目录、volume container 等方式实现容器间数据共享。
- 合理的 volume 生命周期管理(备份、恢复、迁移、销毁)是数据安全的重要保障。