Docker 存储架构与数据管理详解
·
Docker 存储架构与数据管理详解
Docker 分层存储结构
容器分层架构
Docker 容器采用分层结构设计,如图所示:
┌─────────────────┐
│ 容器层 (可读写) │ ← 容器运行时层
├─────────────────┤
│ 镜像层 (只读) │ ← 依赖的基础镜像层
│ 镜像层 (只读) │
│ 镜像层 (只读) │
└─────────────────┘
分层结构特点:
- 容器层:最上层,可读可写
- 镜像层:下层,只读不可修改
- 写时复制 (Copy-on-Write):核心机制
写时复制机制详解
- 容器新生成的数据直接存储在可读可写的容器层(可写层)。
- 修改容器中已有数据时,会先从镜像层复制数据到容器层,修改后的数据仅保存在容器层,镜像层数据保持不变。
- 若多个镜像层存在同名文件,容器中仅显示最上层镜像层的文件内容。
写时复制流程:
- 创建新文件 → 直接写入容器层
- 修改现有文件 → 从镜像层复制到容器层后修改
- 删除文件 → 在容器层创建删除标记
- 多层同名文件 → 只显示最上层内容
联合挂载技术
OverlayFS 存储驱动
Docker 镜像的分层设计极大提升了镜像构建、容器创建、共享和分发的效率。每个镜像层(layer)存储在 /var/lib/docker/volume/<storage-driver>/ 目录,其中 storage-driver 支持多种类型(如 AUFS、OverlayFS、VFS、Brtfs 等)。
# 查看 Docker 存储驱动
[root@hrz3 ~]# docker info | grep "Storage Driver"
Storage Driver: overlay2
支持的存储驱动:
- AUFS:Ubuntu 系统默认
- OverlayFS:CentOS 7.1+ 默认
- VFS、Btrfs:其他文件系统
OverlayFS 工作原理
┌─────────────────┐
│ merged │ ← 向用户呈现的统一视图
├─────────────────┤
│ upper │ ← 容器层(可写)
├─────────────────┤
│ lower │ ← 镜像层(只读)
└─────────────────┘
技术特点:
- 建立在现有文件系统之上(ext4、xfs)
- 不直接管理磁盘空间
- 通过目录合并呈现统一视图
overlay2比overlay更高效
环境要求:
- Docker 版本 17.06.02+
- 宿主机文件系统:ext4 或 xfs
数据卷(Data Volume)机制
数据持久化需求
默认存储的问题:
- 容器停止后数据丢失
- 数据难以从容器中提取
- 不支持多容器数据共享
Volume 解决方案:
- 绕过联合文件系统
- 以正常文件/目录形式存在
- 支持数据持久化
Volume 类型对比
| 特性 | Bind Mounts | Docker Managed Volume |
|---|---|---|
| 数据流向 | 宿主机 → 容器 | 容器 → 宿主机 |
| 数据位置 | 宿主机指定路径 | /var/lib/docker/volumes/ |
| 移植性 | 差 | 好 |
| 管理方式 | 手动管理 | Docker 自动管理 |
Bind Mounts 绑定挂载
基本使用示例
# 1. 创建宿主机目录和测试文件
[root@hrz3 ~]# mkdir html
[root@hrz3 ~]# echo "Hello world" > html/index.html
# 2. 创建容器并绑定挂载目录
[root@hrz3 ~]# docker run --name mynginx -itd -p 80:80 -v /root/html:/usr/share/nginx/html nginx:latest
4118d7894ac4a6bebeeefbd708218fcd29d8c67764959bb5a6505a0213b5d9da
# 3. 验证数据访问
[root@hrz3 ~]# curl http://192.168.100.30:80
Hello world
数据实时同步
# 修改宿主机文件,容器内实时同步
[root@hrz3 ~]# echo "Hello luoqi! " > html/index.html
[root@hrz3 ~]# curl http://192.168.100.30:80
Hello luoqi!
数据持久化验证
# 删除容器,宿主机数据保留
[root@hrz3 ~]# docker rm -f mynginx
mynginx
[root@hrz3 ~]# cat html/index.html
Hello luoqi!
只读权限控制
# 创建只读挂载,增强安全性
[root@hrz3 ~]# docker run --name mynginx -itd -p 80:80 -v /root/html/index.html:/usr/share/nginx/html/index.html:ro nginx:latest
9cc13099b8c45bc49d7f96d62ec1428b0fa7599e2ae6b2b72613d1697c6321af
# 容器内尝试修改(失败)
[root@hrz3 ~]# docker exec -it mynginx /bin/bash
root@9cc13099b8c4:/# cd /usr/share/nginx/html/
root@9cc13099b8c4:/usr/share/nginx/html# echo Hello World! > index.html
bash: index.html: Read-only file system
Bind Mounts 局限性:
- 依赖宿主机特定路径
- 容器移植性差
- 需要预先准备数据
Docker Managed Volume 管理卷
自动卷管理
# 让 Docker 自动管理数据卷
[root@hrz3 ~]# docker run --name mynginx2 -itd -p 80:80 -v /usr/share/nginx/html nginx:latest
查看卷信息
# 查看容器挂载详情
[root@hrz3 ~]# docker inspect mynginx2
...
"Mounts": [
{
"Type": "volume",
"Name": "111dd931a67c1e612a7a0d83d6e6cef27392a173ff3ec0534c505089987e90d3",
"Source": "/var/lib/docker/volumes/111dd931a67c1e612a7a0d83d6e6cef27392a173ff3ec0534c505089987e90d3/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...
# 查看卷中实际数据
[root@hrz3 ~]# cd /var/lib/docker/volumes/111dd931a67c1e612a7a0d83d6e6cef27392a173ff3ec0534c505089987e90d3/_data/
[root@hrz3 _data]# ls
50x.html index.html
数据同步验证
# 修改卷数据,容器内实时同步
[root@hrz3 _data]# echo Hello World > /var/lib/docker/volumes/111dd931a67c1e612a7a0d83d6e6cef27392a173ff3ec0534c505089987e90d3/_data/index.html
[root@hrz3 _data]# curl 192.168.100.30
Hello World
手动卷管理
# 创建命名卷
[root@hrz3 ~]# docker volume create myvol
[root@hrz3 ~]# docker volume ls
DRIVER VOLUME NAME
local myvol
# 使用命名卷创建容器
[root@hrz3 ~]# docker run --name mynginx3 -itd -p 8080:80 -v myvol:/usr/share/nginx/html nginx:latest
容器间数据共享方案
方案一:多容器挂载同一 Volume
# 创建三个 Nginx 容器共享同一数据源
[root@hrz3 ~]# docker run --name apache1 -itd -p 8081:80 -v /root/html:/usr/share/nginx/html nginx:latest
36c48b6f31852d04bae1c73af75b37946bb968bbc430e15109c6ddcac81c7e4a
[root@hrz3 ~]# docker run --name apache2 -itd -p 8082:80 -v /root/html:/usr/share/nginx/html nginx:latest
fe85b12aee3e03c5ab460a5be855339740002cda509ea04fa3e05baf99e11130
[root@hrz3 ~]# docker run --name apache3 -itd -p 8083:80 -v /root/html:/usr/share/nginx/html nginx:latest
9bd97444240d23a5e26ec71ab43b4328706716fa2e9a42b4e79b7f2db56d5c43
# 验证数据一致性
[root@hrz3 ~]# curl 192.168.100.30:8081
Hello luoqi!
[root@hrz3 ~]# curl 192.168.100.30:8082
Hello luoqi!
[root@hrz3 ~]# curl 192.168.100.30:8083
Hello luoqi!
方案二:Volume Container 卷容器
创建专门的数据卷容器,提供统一的数据管理。
# 1. 创建数据卷容器(不运行)
[root@hrz3 ~]# docker create --name mydata -v /root/html:/usr/share/nginx/html busybox
# 2. 其他容器共享数据卷
[root@hrz3 ~]# docker run --name mynginx1 -itd -p 8081:80 --volumes-from mydata nginx
[root@hrz3 ~]# docker run --name mynginx2 -itd -p 8082:80 --volumes-from mydata nginx
[root@hrz3 ~]# docker run --name mynginx3 -itd -p 8083:80 --volumes-from mydata nginx
# 3. 验证数据共享
[root@hrz3 ~]# echo welcome to luoqi > /root/html/index.html
[root@hrz3 ~]# curl 192.168.100.30:8081
welcome to luoqi
[root@hrz3 ~]# curl 192.168.100.30:8082
welcome to luoqi
[root@hrz3 ~]# curl 192.168.100.30:8083
welcome to luoqi
Volume Container 优势:
- 解耦容器与宿主机路径依赖
- 统一管理数据卷配置
- 提高容器可移植性
方案三:Data-Packed Volume Container
将数据打包到镜像中,实现完全自包含。
创建包含数据的镜像
# Dockerfile - 构建数据打包镜像
FROM busybox:latest
ADD html /usr/share/nginx/html
VOLUME /usr/share/nginx/html
CMD ["/bin/bash"]
构建和使用过程
# 1. 准备数据文件
[root@hrz3 ~]# echo Hello World > html/index.html
# 2. 构建包含数据的镜像
[root@hrz3 ~]# docker build -t my_hy /root
# 3. 创建数据卷容器
[root@hrz3 ~]# docker create --name my_data my_hy
# 4. 使用数据卷容器
[root@hrz3 ~]# docker run --name mynginx1 -itd -p 8080:80 --volumes-from my_data nginx
# 5. 验证数据访问
[root@hrz3 ~]# curl http://127.0.0.1:8080
Hello World
Data-Packed Volume Container 优势:
- 完全自包含,不依赖外部存储
- 极佳的移植性
- 适合静态数据场景(配置、静态资源)
存储扩展支持
外部存储系统
Docker 支持多种外部存储系统:
- NFS:网络文件系统
- Ceph:分布式存储
- iSCSI:网络存储协议
- 云存储:AWS EBS、Azure Disk 等
# 使用外部存储插件
[root@hrz3 ~]# docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/path/to/directory \
nfs-volume
总结与最佳实践
数据共享方法对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 多容器挂载 | 简单直接 | 依赖宿主机路径 | 开发环境 |
| Volume Container | 解耦依赖、统一管理 | 仍需外部存储 | 生产环境 |
| Data-Packed | 完全自包含、移植性好 | 数据更新复杂 | 静态配置 |
核心架构要点
- 分层结构:容器 = 可写层 + 多个只读镜像层
- 写时复制:修改时从镜像层复制到容器层
- 联合挂载:OverlayFS 实现目录合并
- 数据持久化:Volume 绕过联合文件系统
存储选择策略
- 开发调试:使用 Bind Mounts(实时同步)
- 生产环境:使用 Docker Managed Volume(自动管理)
- 配置分发:使用 Data-Packed Volume Container(完全自包含)
- 多容器共享:使用 Volume Container(统一管理)
通过合理运用 Docker 存储机制,可以构建高效、可靠、可移植的容器化应用架构。
更多推荐


所有评论(0)