20. 数据持久化1. 数据持久化概述容器默认情况下数据是临时的当容器删除时数据也会丢失。数据持久化是生产环境中必须解决的问题Docker 提供了多种数据持久化方案。┌─────────────────────────────────────────────────────────────┐ │ Docker 数据持久化方案 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Volume推荐 │ │ │ │ - Docker 管理 │ │ │ │ - 独立于容器生命周期 │ │ │ │ - 支持多种驱动 │ │ │ │ - 适合生产环境 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Bind Mount开发 │ │ │ │ - 宿主机任意路径 │ │ │ │ - 直接访问宿主机文件 │ │ │ │ - 适合开发环境 │ │ │ │ - 配置文件共享 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ tmpfs内存 │ │ │ │ - 内存存储 │ │ │ │ - 速度最快 │ │ │ │ - 临时数据 │ │ │ │ - 敏感信息 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘2. Volume数据卷2.1 创建和管理# 创建数据卷dockervolume create mydata# 列出数据卷dockervolumels# 查看数据卷详情dockervolume inspect mydata# 显示数据卷位置# Mountpoint: /var/lib/docker/volumes/mydata/_data# 删除数据卷dockervolumermmydata# 清理未使用的卷dockervolume prune# 强制清理所有未使用卷dockervolume prune-f2.2 使用数据卷# 使用命名卷dockerrun-d-vmydata:/app/data--nameapp nginx# 使用 --mount 语法推荐dockerrun-d--mountsourcemydata,target/app/data nginx# 只读挂载dockerrun-d--mountsourcemydata,target/app/data,readonly nginx# 使用匿名卷不推荐dockerrun-d-v/app/data nginx# 查看卷使用情况dockerinspect app|grep-A10Mounts2.3 卷驱动# 使用本地驱动默认dockervolume create--driverlocalmydata# 使用 NFS 驱动dockervolume create--driverlocal\--opttypenfs\--optdevice:/path/to/nfs\--optoaddrnfs-server,rw,nfsvers4\nfs-volume# 挂载 NFS 卷dockerrun-d-vnfs-volume:/data nginx# 使用第三方驱动如 Flocker# docker volume create --driver flocker mydata3. Bind Mount3.1 基础用法# 基础语法dockerrun-d-v/host/data:/app/data nginx# 使用 --mount推荐dockerrun-d--mounttypebind,source/host/data,target/app/data nginx# 相对路径dockerrun-d-v$(pwd)/data:/app/data nginx# 只读绑定dockerrun-d--mounttypebind,source/host/config,target/app/config,readonly nginx# 绑定单个文件dockerrun-it--mounttypebind,source/host/config.json,target/app/config.json alpinesh3.2 权限管理# 指定用户 IDdockerrun-d--user1000:1000-v/host/data:/app/data nginx# 修改宿主机目录权限sudochown-R1000:1000 /host/datasudochmod755/host/data# SELinux 标签CentOS/RHELdockerrun-d-v/host/data:/app/data:Z nginx# 私有dockerrun-d-v/host/data:/app/data:z nginx# 共享4. tmpfs 挂载# 使用 tmpfsdockerrun-d--tmpfs/app/tmp:rw,noexec,nosuid,size100m nginx# 使用 --mount 语法dockerrun-d--mounttypetmpfs,destination/app/tmp,tmpfs-size100m nginx# 查看 tmpfs 使用dockerexeccontainer_namedf-h/app/tmp# 适用场景# - 临时文件# - 缓存数据# - Session 存储# - 敏感信息不落盘5. 数据备份与恢复5.1 备份数据卷# 备份卷到 tar 文件dockerrun--rm\-vmydata:/source\-v$(pwd):/backup\alpine\tarczf /backup/mydata-backup.tar.gz-C/source.# 备份 bind mountdockerrun--rm\-v/host/data:/source\-v$(pwd):/backup\alpine\tarczf /backup/data-backup.tar.gz-C/source.# 备份多个卷dockerrun--rm\-vvolume1:/source1\-vvolume2:/source2\-v$(pwd):/backup\alpine\sh-ctar czf /backup/backup.tar.gz /source1 /source25.2 恢复数据卷# 创建新卷dockervolume create newdata# 从备份恢复dockerrun--rm\-vnewdata:/target\-v$(pwd):/backup\alpine\tarxzf /backup/mydata-backup.tar.gz-C/target# 验证恢复dockerrun--rm-vnewdata:/data alpinels-la/data5.3 容器迁移# 导出容器数据CONTAINER_NAMEmyappBACKUP_FILEmyapp-data.tar.gzdockerrun--rm\--volumes-from$CONTAINER_NAME\-v$(pwd):/backup\alpine\tarczf /backup/$BACKUP_FILE/data# 在新宿主机恢复dockercreate-v/data--name>dockerrun--rm\--volumes-from>\-v$(pwd):/backup\alpine\tarxzf /backup/$BACKUP_FILE-C/6. 卷管理策略6.1 命名规范# 推荐命名格式# project-environment-purpose# 示例dockervolume create myapp-prod-dbdockervolume create myapp-prod-logsdockervolume create myapp-prod-uploadsdockervolume create myapp-dev-db6.2 卷标签# 创建带标签的卷dockervolume create\--labelprojectmyapp\--labelenvironmentproduction\--labelbackuptrue\myapp-data# 过滤卷dockervolumels--filterlabelprojectmyappdockervolumels--filterlabelenvironmentproduction# 清理特定标签的卷dockervolume prune--filterlabelprojecttemporary6.3 卷清理策略# 定期清理crontab# 0 2 * * * docker volume prune -f# 清理 24 小时前使用的卷dockervolume prune--filteruntil24h# 查找并删除特定模式的卷dockervolumels-q--filternametemp-|xargsdockervolumerm# 删除所有未使用卷dockervolume prune-a7. 实战示例7.1 MySQL 数据持久化# 创建数据卷dockervolume create mysql-datadockervolume create mysql-logs# 运行 MySQL 容器dockerrun-d\--namemysql\-vmysql-data:/var/lib/mysql\-vmysql-logs:/var/log/mysql\-eMYSQL_ROOT_PASSWORDroot123\mysql:8.0# 测试数据持久化dockerexecmysql mysql-uroot-proot123-eCREATE DATABASE testdbdockerstop mysqldockerstart mysqldockerexecmysql mysql-uroot-proot123-eSHOW DATABASES7.2 WordPress 持久化# 创建卷dockervolume create wordpress-dbdockervolume create wordpress-files# MySQLdockerrun-d\--namewp-mysql\-vwordpress-db:/var/lib/mysql\-eMYSQL_ROOT_PASSWORDroot\-eMYSQL_DATABASEwordpress\mysql:8.0# WordPressdockerrun-d\--namewordpress\-p8080:80\-vwordpress-files:/var/www/html\--linkwp-mysql:mysql\wordpress:latest# 备份dockerrun--rm\-vwordpress-db:/source\-vwordpress-files:/source-files\-v$(pwd):/backup\alpinesh-ctar czf /backup/wordpress-backup.tar.gz /source /source-files7.3 开发环境热重载# 使用 bind mount 实现代码热重载dockerrun-d\--namedev-app\-p3000:3000\-v$(pwd):/app\-v/app/node_modules\node:14\npmrun dev8. 存储对比特性VolumeBind Mounttmpfs位置Docker 管理任意路径内存持久性是是否容器删除保留保留删除备份容易容易N/A跨主机需要驱动需要共享N/A性能好好最快权限自动手动自动适用生产数据开发配置临时数据9. 监控与调试# 查看卷使用情况dockersystemdf# 查看卷详情dockervolume inspect mydata# 查看卷中文件dockerrun--rm-vmydata:/data alpinels-la/data# 查看卷大小dockerrun--rm-vmydata:/data alpinedu-sh/data# 调试卷内容dockerrun--rm-it-vmydata:/data alpinesh10. 最佳实践✅ 推荐做法生产环境使用 Volume开发环境使用 Bind Mount敏感数据使用 Volume 或 tmpfs为卷设置标签便于管理定期备份重要数据卷使用命名卷而非匿名卷❌ 避免事项在容器可写层存储持久数据在生产环境使用 Bind Mount 存储应用数据忽视卷的备份策略删除容器后忘记清理卷11. 常见问题Q1: 容器删除后数据还在吗Volume 数据还在Bind Mount 数据还在容器层数据丢失。Q2: 多个容器可以共享同一个卷吗可以支持多容器读写同一个卷。Q3: 如何迁移卷到另一台主机使用docker volume inspect定位卷位置复制 _data 目录到新主机。12. 小结Volume生产环境推荐Docker 管理Bind Mount开发环境直接访问宿主机tmpfs内存存储临时数据备份恢复使用 Docker 容器配合 tar卷管理标签、清理策略根据场景选择合适的存储方案定期备份重要数据
第四部分-Docker网络与存储——20. 数据持久化
20. 数据持久化1. 数据持久化概述容器默认情况下数据是临时的当容器删除时数据也会丢失。数据持久化是生产环境中必须解决的问题Docker 提供了多种数据持久化方案。┌─────────────────────────────────────────────────────────────┐ │ Docker 数据持久化方案 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Volume推荐 │ │ │ │ - Docker 管理 │ │ │ │ - 独立于容器生命周期 │ │ │ │ - 支持多种驱动 │ │ │ │ - 适合生产环境 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Bind Mount开发 │ │ │ │ - 宿主机任意路径 │ │ │ │ - 直接访问宿主机文件 │ │ │ │ - 适合开发环境 │ │ │ │ - 配置文件共享 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ tmpfs内存 │ │ │ │ - 内存存储 │ │ │ │ - 速度最快 │ │ │ │ - 临时数据 │ │ │ │ - 敏感信息 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘2. Volume数据卷2.1 创建和管理# 创建数据卷dockervolume create mydata# 列出数据卷dockervolumels# 查看数据卷详情dockervolume inspect mydata# 显示数据卷位置# Mountpoint: /var/lib/docker/volumes/mydata/_data# 删除数据卷dockervolumermmydata# 清理未使用的卷dockervolume prune# 强制清理所有未使用卷dockervolume prune-f2.2 使用数据卷# 使用命名卷dockerrun-d-vmydata:/app/data--nameapp nginx# 使用 --mount 语法推荐dockerrun-d--mountsourcemydata,target/app/data nginx# 只读挂载dockerrun-d--mountsourcemydata,target/app/data,readonly nginx# 使用匿名卷不推荐dockerrun-d-v/app/data nginx# 查看卷使用情况dockerinspect app|grep-A10Mounts2.3 卷驱动# 使用本地驱动默认dockervolume create--driverlocalmydata# 使用 NFS 驱动dockervolume create--driverlocal\--opttypenfs\--optdevice:/path/to/nfs\--optoaddrnfs-server,rw,nfsvers4\nfs-volume# 挂载 NFS 卷dockerrun-d-vnfs-volume:/data nginx# 使用第三方驱动如 Flocker# docker volume create --driver flocker mydata3. Bind Mount3.1 基础用法# 基础语法dockerrun-d-v/host/data:/app/data nginx# 使用 --mount推荐dockerrun-d--mounttypebind,source/host/data,target/app/data nginx# 相对路径dockerrun-d-v$(pwd)/data:/app/data nginx# 只读绑定dockerrun-d--mounttypebind,source/host/config,target/app/config,readonly nginx# 绑定单个文件dockerrun-it--mounttypebind,source/host/config.json,target/app/config.json alpinesh3.2 权限管理# 指定用户 IDdockerrun-d--user1000:1000-v/host/data:/app/data nginx# 修改宿主机目录权限sudochown-R1000:1000 /host/datasudochmod755/host/data# SELinux 标签CentOS/RHELdockerrun-d-v/host/data:/app/data:Z nginx# 私有dockerrun-d-v/host/data:/app/data:z nginx# 共享4. tmpfs 挂载# 使用 tmpfsdockerrun-d--tmpfs/app/tmp:rw,noexec,nosuid,size100m nginx# 使用 --mount 语法dockerrun-d--mounttypetmpfs,destination/app/tmp,tmpfs-size100m nginx# 查看 tmpfs 使用dockerexeccontainer_namedf-h/app/tmp# 适用场景# - 临时文件# - 缓存数据# - Session 存储# - 敏感信息不落盘5. 数据备份与恢复5.1 备份数据卷# 备份卷到 tar 文件dockerrun--rm\-vmydata:/source\-v$(pwd):/backup\alpine\tarczf /backup/mydata-backup.tar.gz-C/source.# 备份 bind mountdockerrun--rm\-v/host/data:/source\-v$(pwd):/backup\alpine\tarczf /backup/data-backup.tar.gz-C/source.# 备份多个卷dockerrun--rm\-vvolume1:/source1\-vvolume2:/source2\-v$(pwd):/backup\alpine\sh-ctar czf /backup/backup.tar.gz /source1 /source25.2 恢复数据卷# 创建新卷dockervolume create newdata# 从备份恢复dockerrun--rm\-vnewdata:/target\-v$(pwd):/backup\alpine\tarxzf /backup/mydata-backup.tar.gz-C/target# 验证恢复dockerrun--rm-vnewdata:/data alpinels-la/data5.3 容器迁移# 导出容器数据CONTAINER_NAMEmyappBACKUP_FILEmyapp-data.tar.gzdockerrun--rm\--volumes-from$CONTAINER_NAME\-v$(pwd):/backup\alpine\tarczf /backup/$BACKUP_FILE/data# 在新宿主机恢复dockercreate-v/data--name>dockerrun--rm\--volumes-from>\-v$(pwd):/backup\alpine\tarxzf /backup/$BACKUP_FILE-C/6. 卷管理策略6.1 命名规范# 推荐命名格式# project-environment-purpose# 示例dockervolume create myapp-prod-dbdockervolume create myapp-prod-logsdockervolume create myapp-prod-uploadsdockervolume create myapp-dev-db6.2 卷标签# 创建带标签的卷dockervolume create\--labelprojectmyapp\--labelenvironmentproduction\--labelbackuptrue\myapp-data# 过滤卷dockervolumels--filterlabelprojectmyappdockervolumels--filterlabelenvironmentproduction# 清理特定标签的卷dockervolume prune--filterlabelprojecttemporary6.3 卷清理策略# 定期清理crontab# 0 2 * * * docker volume prune -f# 清理 24 小时前使用的卷dockervolume prune--filteruntil24h# 查找并删除特定模式的卷dockervolumels-q--filternametemp-|xargsdockervolumerm# 删除所有未使用卷dockervolume prune-a7. 实战示例7.1 MySQL 数据持久化# 创建数据卷dockervolume create mysql-datadockervolume create mysql-logs# 运行 MySQL 容器dockerrun-d\--namemysql\-vmysql-data:/var/lib/mysql\-vmysql-logs:/var/log/mysql\-eMYSQL_ROOT_PASSWORDroot123\mysql:8.0# 测试数据持久化dockerexecmysql mysql-uroot-proot123-eCREATE DATABASE testdbdockerstop mysqldockerstart mysqldockerexecmysql mysql-uroot-proot123-eSHOW DATABASES7.2 WordPress 持久化# 创建卷dockervolume create wordpress-dbdockervolume create wordpress-files# MySQLdockerrun-d\--namewp-mysql\-vwordpress-db:/var/lib/mysql\-eMYSQL_ROOT_PASSWORDroot\-eMYSQL_DATABASEwordpress\mysql:8.0# WordPressdockerrun-d\--namewordpress\-p8080:80\-vwordpress-files:/var/www/html\--linkwp-mysql:mysql\wordpress:latest# 备份dockerrun--rm\-vwordpress-db:/source\-vwordpress-files:/source-files\-v$(pwd):/backup\alpinesh-ctar czf /backup/wordpress-backup.tar.gz /source /source-files7.3 开发环境热重载# 使用 bind mount 实现代码热重载dockerrun-d\--namedev-app\-p3000:3000\-v$(pwd):/app\-v/app/node_modules\node:14\npmrun dev8. 存储对比特性VolumeBind Mounttmpfs位置Docker 管理任意路径内存持久性是是否容器删除保留保留删除备份容易容易N/A跨主机需要驱动需要共享N/A性能好好最快权限自动手动自动适用生产数据开发配置临时数据9. 监控与调试# 查看卷使用情况dockersystemdf# 查看卷详情dockervolume inspect mydata# 查看卷中文件dockerrun--rm-vmydata:/data alpinels-la/data# 查看卷大小dockerrun--rm-vmydata:/data alpinedu-sh/data# 调试卷内容dockerrun--rm-it-vmydata:/data alpinesh10. 最佳实践✅ 推荐做法生产环境使用 Volume开发环境使用 Bind Mount敏感数据使用 Volume 或 tmpfs为卷设置标签便于管理定期备份重要数据卷使用命名卷而非匿名卷❌ 避免事项在容器可写层存储持久数据在生产环境使用 Bind Mount 存储应用数据忽视卷的备份策略删除容器后忘记清理卷11. 常见问题Q1: 容器删除后数据还在吗Volume 数据还在Bind Mount 数据还在容器层数据丢失。Q2: 多个容器可以共享同一个卷吗可以支持多容器读写同一个卷。Q3: 如何迁移卷到另一台主机使用docker volume inspect定位卷位置复制 _data 目录到新主机。12. 小结Volume生产环境推荐Docker 管理Bind Mount开发环境直接访问宿主机tmpfs内存存储临时数据备份恢复使用 Docker 容器配合 tar卷管理标签、清理策略根据场景选择合适的存储方案定期备份重要数据