第二部分-Docker核心原理——11. 容器存储原理

📅 2026/7/5 4:05:16 👁️ 阅读次数 📝 编程学习
第二部分-Docker核心原理——11. 容器存储原理

11. 容器存储原理

1. 容器存储概述

容器存储是 Docker 数据持久化的关键。默认情况下,容器内的数据是临时的,当容器删除时数据也会丢失。Docker 提供了多种存储方案来实现数据持久化和共享。

┌─────────────────────────────────────────────────────────────┐ │ Docker 存储架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 容器 │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ 可写容器层 (Container Layer) │ │ │ │ │ │ - 临时存储,容器删除后丢失 │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ 镜像层 (Image Layers) │ │ │ │ │ │ - 只读,共享存储 │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ Volume │ │ Bind Mount│ │ tmpfs │ │ │ │ 持久卷 │ │ 绑定挂载 │ │ 内存文件 │ │ │ │ │ │ │ │ 系统 │ │ │ │ 数据持久 │ │ 宿主机共享 │ │ 临时存储 │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

2. Docker 存储类型

存储类型存储位置生命周期适用场景
容器层/var/lib/docker随容器删除临时数据
Volume/var/lib/docker/volumes独立于容器数据库、持久数据
Bind Mount宿主机任意路径独立于容器配置共享、开发
tmpfs内存随容器删除敏感数据、缓存

3. Volume(数据卷)

3.1 基础操作

# 创建数据卷dockervolume create myvol# 列出数据卷dockervolumelsdockervolumels-fdangling=true# 过滤未使用的# 查看数据卷详情dockervolume inspect myvol# 使用数据卷运行容器dockerrun-d-vmyvol:/app/data--nameapp nginx# 只读挂载dockerrun-d-vmyvol:/app/data:ro nginx# 删除数据卷dockervolumermmyvol# 清理未使用的数据卷dockervolume prunedockervolume prune-f# 删除所有未使用的卷dockervolume prune-a

3.2 数据卷类型

# 1. 匿名卷(Anonymous Volume)dockerrun-d-v/app/data nginx# 卷名随机生成,不便于管理# 2. 命名卷(Named Volume)dockervolume create app-datadockerrun-d-vapp-data:/app/data nginx# 3. 主机卷(Host Volume)# 已废弃,使用 bind mount 替代

3.3 数据卷驱动

# 查看卷驱动dockervolume inspect myvol|grepDriver# 使用本地驱动(默认)dockervolume create--driverlocalmyvol# 使用 NFS 驱动dockervolume create--driverlocal\--opttype=nfs\--optdevice=:/path/to/nfs\--opto=addr=192.168.1.100,rw,nfsvers=4\nfs-volume# 使用第三方驱动(如 REX-Ray、Flocker)dockervolume create--driverrexray/ebs myvol# 查看支持卷插件的驱动dockerinfo|grep"Plugins"

4. Bind Mount(绑定挂载)

4.1 基础用法

# 挂载宿主机目录dockerrun-d-v/host/data:/app/data nginx# 使用 --mount 语法(推荐)dockerrun-d--mounttype=bind,source=/host/data,target=/app/data nginx# 只读挂载dockerrun-d--mounttype=bind,source=/host/config,target=/app/config,readonly nginx# 挂载单个文件dockerrun-it--mounttype=bind,source=/host/config.txt,target=/app/config.txt alpinesh# 使用 $PWD 相对路径dockerrun-d-v$(pwd)/data:/app/data nginx

4.2 权限管理

# 指定用户 IDdockerrun-d-v/host/data:/app/data--user1000:1000 nginx# 修改挂载目录权限sudochown-R1000:1000 /host/data# 使用 :Z 标志(SELinux)dockerrun-d-v/host/data:/app/data:Z nginx# 使用 :z 标志(共享)dockerrun-d-v/host/data:/app/data:z nginx

5. tmpfs(内存文件系统)

# 使用 tmpfs 挂载dockerrun-d--tmpfs/app/tmp:rw,noexec,nosuid,size=100m nginx# 使用 --mount 语法dockerrun-d--mounttype=tmpfs,destination=/app/tmp,tmpfs-size=100m nginx# 查看 tmpfs 使用dockerexeccontainer_namedf-h/app/tmp# 适用场景:# - 临时文件# - 缓存数据# - 密钥等敏感信息(不写入磁盘)

6. 数据备份与恢复

6.1 备份数据卷

# 备份 Volume 到宿主机dockerrun--rm-vmyvol:/source-v$(pwd):/backup alpine\tarczf /backup/myvol-backup.tar.gz-C/source.# 备份使用 bind mount 的容器dockerrun--rm-v/host/data:/source-v$(pwd):/backup alpine\tarczf /backup/data-backup.tar.gz-C/source.# 使用 docker cp(不建议用于大数据)dockercpcontainer_name:/app/data ./backup/

6.2 恢复数据卷

# 创建新卷dockervolume create myvol-new# 从备份恢复dockerrun--rm-vmyvol-new:/target-v$(pwd):/backup alpine\tarxzf /backup/myvol-backup.tar.gz-C/target# 验证恢复dockerrun--rm-vmyvol-new:/data alpinels-la/data

6.3 容器间数据迁移

# 从旧容器复制数据到新卷dockerrun--rm--volumes-from old-container-vnewvol:/target alpine\cp-a/source/data/. /target/# 使用临时容器迁移dockerrun-it--rm-voldvol:/old-vnewvol:/new alpine\sh-c"cp -a /old/. /new/"

7. 数据卷管理最佳实践

7.1 命名规范

# 推荐命名格式:<项目>-<环境>-<用途>-<版本># 示例:# - myapp-prod-db-data# - myapp-prod-logs# - myapp-dev-config

7.2 数据卷标签

# 创建带标签的卷dockervolume create\--labelproject=myapp\--labelenvironment=production\--labelbackup=true\myapp-data# 根据标签过滤dockervolumels--filterlabel=project=myappdockervolumels--filterlabel=backup=true

7.3 数据卷清理策略

# 定期清理未使用的卷(cron)# 0 2 * * * docker volume prune -f# 清理特定标签的卷dockervolume prune--filterlabel=temp=true# 查找并删除特定模式的卷dockervolumels-q--filtername=temp-|xargsdockervolumerm

8. 容器存储原理

8.1 容器存储位置

# Docker 数据根目录dockerinfo|grep"Docker Root Dir"# /var/lib/docker# 容器数据目录结构ls-la/var/lib/docker/# ├── containers/ # 容器配置和日志# ├── image/ # 镜像元数据# ├── overlay2/ # 镜像层数据# └── volumes/ # 数据卷# 查看容器存储路径CONTAINER_ID=$(dockerinspect-f'{{.Id}}'container_name)ls-la/var/lib/docker/containers/$CONTAINER_ID/

8.2 写时复制(Copy-on-Write)

# 验证 CoW 机制# 1. 启动容器dockerrun-it--nametestalpinesh# 2. 容器内创建文件/# echo "test data" > /data.txt/# exit# 3. 查看容器层变化CONTAINER_ID=$(dockerinspect-f'{{.Id}}'test)UPPER_DIR=$(dockerinspect-f'{{.GraphDriver.Data.UpperDir}}'test)ls-la$UPPER_DIR/# 4. 镜像层只读dockerrun-it--rmalpinesh/# touch /test.txt # 这会在容器层,不是镜像层

9. 数据卷对比

特性VolumeBind Mounttmpfs
位置Docker 管理任意位置内存
持久性
容器删除后保留保留删除
备份容易容易不需要
跨主机需要驱动需要共享存储不支持
性能最快
权限管理自动手动N/A

10. 实战演练

# 1. 创建 WordPress 数据卷dockervolume create wordpress-dbdockervolume create wordpress-files# 2. 启动 MySQL 容器dockerrun-d\--namemysql\-vwordpress-db:/var/lib/mysql\-eMYSQL_ROOT_PASSWORD=root\-eMYSQL_DATABASE=wordpress\mysql:8.0# 3. 启动 WordPress 容器dockerrun-d\--namewordpress\-p8080:80\-vwordpress-files:/var/www/html\--linkmysql:mysql\wordpress:latest# 4. 验证数据持久化dockerstop wordpress mysqldockerstart mysql wordpress# 数据依然存在# 5. 备份数据库卷dockerrun--rm-vwordpress-db:/source-v$(pwd):/backup alpine\tarczf /backup/wordpress-db-backup.tar.gz-C/source.# 6. 清理测试dockerrm-fwordpress mysqldockervolume prune

11. 存储驱动配置

# /etc/docker/daemon.json{"storage-driver":"overlay2","storage-opts":["overlay2.override_kernel_check=true","overlay2.size=20G"],"data-root":"/data/docker","exec-root":"/data/docker-exec"}# 更改 Docker 数据目录sudosystemctl stopdockersudomv/var/lib/docker /data/dockersudoln-s/data/docker /var/lib/dockersudosystemctl startdocker

12. 常用命令速查

操作命令
创建卷docker volume create
列出卷docker volume ls
查看卷docker volume inspect
删除卷docker volume rm
清理卷docker volume prune
备份卷docker run --rm -v vol:/source -v .:/backup alpine tar czf /backup/backup.tar.gz -C /source .
恢复卷docker run --rm -v vol:/target -v .:/backup alpine tar xzf /backup/backup.tar.gz -C /target

13. 常见问题

Q1: Volume 数据在哪里存储?

# 默认位置/var/lib/docker/volumes/<volume-name>/_data

Q2: 如何查看容器使用的卷?

dockerinspect container_name|grep-A10"Mounts"dockerinspect-f'{{json .Mounts}}'container_name|jq

Q3: 多个容器可以共享同一个卷吗?

# 可以,使用相同的卷挂载dockerrun-d-vshared-data:/data--nameapp1 nginxdockerrun-d-vshared-data:/data--nameapp2 nginx

Q4: 如何迁移 Volume 到另一台主机?

# 源主机备份dockerrun--rm-vmyvol:/source-v$(pwd):/backup alpine\tarczf /backup/myvol.tar.gz-C/source.# 目标主机恢复dockervolume create myvoldockerrun--rm-vmyvol:/target-v$(pwd):/backup alpine\tarxzf /backup/myvol.tar.gz-C/target

14. 小结

  • Volume:Docker 管理,数据持久化,推荐使用
  • Bind Mount:宿主机路径,开发调试
  • tmpfs:内存存储,临时数据
  • 容器层数据随容器删除而丢失
  • Volume 独立于容器生命周期
  • 支持卷驱动实现远程存储
  • Volume 备份恢复简单高效
  • 合理使用标签管理数据卷