01. 为什么需要数据持久化
容器是无状态的——删掉容器,里面的数据也跟着没了。这跟容器设计的哲学有关:容器应该是用完就丢的。但数据库、上传的文件、配置文件这些数据需要活过容器的生命周期,所以需要持久化。
Docker 提供两种持久化方式:Volume(由 Docker 管理的存储卷)和 Bind Mount(把宿主机目录直接映射进容器)。
Volume 是推荐方式——由 Docker 统一管理,可以跨容器共享、备份、迁移。Bind Mount 更简单直接但依赖宿主机目录结构,换个机器可能就挂了。
还有个 tmpfs Mount——数据存内存里不落盘,容器停了数据就没了,适合存临时敏感数据。
bash
# 创建 volume
docker volume create mydata
# 查看所有 volume
docker volume ls
# 查看 volume 详情
docker volume inspect mydata
# 使用 volume
docker run -d -v mydata:/var/lib/mysql --name db mysql
# 删 volume(确认没容器在用)
docker volume rm mydata02. Volume 用法详解
Volume 是最推荐的持久化方案,Docker 帮你管文件存在哪(默认在 /var/lib/docker/volumes/ 下)。
匿名 Volume——docker run -v /data 不指定名字,Docker 自动生成一个随机名字的 volume。删容器时如果不加 -v 参数,匿名 volume 不会被删(会堆积垃圾)。
具名 Volume——docker run -v mydata:/data 指定一个名字。跨容器共享同一个 volume 很容易:两个容器都用 -v mydata:/data。
Volume 的备份和迁移:可以用一个临时容器挂载 volume,然后 tar 打包导出。或者用 docker volume 的子命令备份到远程(这需要第三方工具配合,原生 Docker 没有)。
bash
# 具名 volume
docker run -d -v dbdata:/var/lib/mysql mysql
# 多个容器共享同一个 volume
docker run -d -v shared:/data --name app1 alpine
docker run -d -v shared:/data --name app2 alpine
# 备份 volume
docker run --rm -v dbdata:/data -v $(pwd):/backup alpine \
tar czf /backup/dbdata.tar.gz /datadocker run -v 后面第一个参数如果不带斜杠就是 volume 名字,带了斜杠 Docker 认为是宿主机路径(Bind Mount)。
03. Bind Mount 用法
Bind Mount 直接把宿主机的一个目录或文件映射进容器。容器里对那个目录的读写直接反映到宿主机上,反之亦然。开发环境特别好用——本地改代码,容器里实时生效。
跟 Volume 的区别:Bind Mount 你指定路径(如 /home/user/project:/app),Volume 由 Docker 管理路径。Bind Mount 更灵活但可移植性差,换台机器路径可能变了。
常见场景:开发环境挂载源代码(改代码容器自动更新)、挂载配置文件(nginx.conf)、挂载宿主机 socket(比如 docker.sock)。
bash
# Bind Mount
docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx
# 只读挂载
docker run -d -v $(pwd)/config:/etc/nginx:ro nginx
# 挂载单个文件
docker run -d -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginx
# docker-compose 里
# volumes:
# - ./html:/usr/share/nginx/html
# - ./config:/etc/nginx:ro挂载文件而非目录时,文件必须在宿主机上已存在。Docker 不会自动创建文件,如果不存在 Docker 会把它当成目录名创建空目录。
04. tmpfs 与内存存储
tmpfs Mount 把数据存内存里,不写磁盘。容器停了数据就没了。适合的场景:临时缓存、敏感信息(不希望落在磁盘上)、需要极速 IO 的数据。
tmpfs 跟 Volume 和 Bind Mount 不同——它不是持久化的,容器删了就没了。
使用方式:docker run --tmpfs /tmp 或者 docker run --mount type=tmpfs,destination=/tmp,tmpfs-size=64M。注意限一下大小,别把宿主机内存吃光了。
bash
# tmpfs
docker run --tmpfs /tmp:rw,size=64M nginx
# --mount 语法(更明确)
docker run --mount type=tmpfs,destination=/tmp,tmpfs-size=64M nginx
# docker-compose 里
# tmpfs:
# - /tmp:size=64M05. Volume 驱动与最佳实践
Docker 的 Volume 支持插件驱动,可以把数据存到远程存储:NFS、云盘(AWS EBS、Azure Disk)、分布式存储(Ceph、GlusterFS)。这对有状态容器(数据库)特别重要——容器挂了换台机器,挂载同一个远程 volume,数据还在。
最佳实践:
1. 数据库、消息队列等有状态服务必须用 Volume
2. 开发环境用 Bind Mount,生产环境用 Volume
3. Volume 定期备份,尤其是数据库的 Volume
4. 清理不再用的 volume:docker volume prune
5. 不要在 container 里存重要的数据,所有需要持久化的都挂载出来
bash
# 清理未使用的 volume
docker volume prune
# 查看 volume 占用空间
docker system df -v
# 使用 NFS volume 驱动
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/path/to/share \
nfs-volumedocker volume prune 会删掉所有没被容器使用的 volume。删之前确认没有重要的数据还在里面。
知识测验
第 1/5 题正确 0
Volume 和 Bind Mount 最大区别?
下一节
下一节 Docker 安全