Docker 中的持久化存储(如数据库数据)该怎么管理?
用 Docker volume 管理持久数据:docker volume create 创建,docker run -v 卷名:/容器路径 挂载,容器删了数据还在;备份可用临时容器打包。数据库类有状态服务必须挂卷。
标准做法:用命名卷(named volume)——docker volume create mydata 创建,docker run -v mydata:/var/lib/mysql 挂载到容器的数据目录。卷数据存在宿主机由 Docker 管理的目录里,容器删除、重建、升级都不受影响;数据库、上传目录这类有状态数据必须放卷里,否则容器一删全丢。
基本用法
# 创建卷
docker volume create mysqldata
# 挂载使用
docker run -d --name mysql \
-v mysqldata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
mysql:8
# 查看与定位
docker volume ls
docker volume inspect mysqldata # 看宿主机上的实际路径
不写 docker volume create 直接在 -v 名字:/路径 里用新名字,Docker 会自动创建命名卷。
三种挂载方式对比
| 方式 | 写法 | 适用 |
|---|---|---|
| 命名卷 | -v mysqldata:/var/lib/mysql |
数据库等应用数据,首选 |
| 绑定挂载 | -v /host/dir:/container/dir |
要直接看到/编辑宿主机文件(配置、代码热更) |
| tmpfs | --tmpfs /run |
敏感临时数据,不落盘 |
备份与迁移
用临时容器打包卷内容:
# 备份
docker run --rm -v mysqldata:/data -v $(pwd):/backup \
alpine tar -czf /backup/mysqldata.tar.gz -C /data .
# 恢复到(另一台机器的)新卷
docker run --rm -v mysqldata:/data -v $(pwd):/backup \
alpine sh -c "cd /data && tar -xzf /backup/mysqldata.tar.gz"
数据库类数据建议用其自身工具备份(mysqldump/pg_dump),卷打包只适合停机冷备。
清理
docker volume ls -f dangling=true # 看无主卷
docker volume prune # 清掉没被任何容器用的卷(谨慎)
观测云对照
有状态容器重点盯指标。 数据库容器的磁盘用量、连接数、慢查询由 DataKit 采集,卷容量水位提前告警;日志目录也卷化后,容器升级日志不丢。
常见问题(FAQ)
Q:容器删了卷还在吗?
A:在。卷独立于容器生命周期,要 docker volume rm 才删。
Q:卷能挂给多个容器吗?
A:可以,多个容器共享同一卷;但数据库类应用多数不支持多实例同时写同一数据目录,共享前确认应用语义。
Q:compose 里怎么定义卷?
A:顶层 volumes: 声明,服务里 - 卷名:/路径 引用;compose 会自动加项目名前缀。