【AI 总结】Docker Volumes

Volumes | Docker Docs | AI 总结

卷的基础定义与核心特性

  • 本质:卷是 Docker 管理的容器持久化数据存储机制,存储在主机的特定目录(如 /var/lib/docker/volumes/<volume-name>/_data),与主机核心功能隔离,区别于依赖主机目录结构的 “绑定挂载(bind mounts)”。
  • 核心优势:跨 Linux/Windows 容器兼容、支持多容器安全共享、可通过 Docker CLI/API 管理、便于备份迁移、能预填充容器数据、I/O 性能优于容器可写层。
  • 适用场景与禁忌
    • 适用:需持久化容器数据、多容器共享数据、追求高性能 I/O、预填充数据给其他容器的场景。
    • 禁忌:需从主机直接访问文件时(建议用绑定挂载);存储非持久化状态数据时(建议用 tmpfs mount)。

这是一个关于 Docker 卷(Volumes) 的定义和特性的描述。

具体来说,这段话解释了 Docker 卷的三个核心要点:

1. 卷(Volume)是容器持久化数据存储机制

  • 容器本身是 “易失的”(ephemeral),即容器删除后,其内部的数据也会随之消失。
  • 卷(Volume) 是为了解决这个问题而设计的,它允许数据在容器生命周期之外持久存在。

2. 存储位置:受限且由 Docker 管理

  • 在 Linux 系统中,卷通常存储在 /var/lib/docker/volumes/ 目录下。
  • 这意味着卷是由 Docker 引擎完全管理的,用户不需要(也不建议)手动去修改这些目录下的文件,从而保证了数据的安全性。

3. 与 “绑定挂载(Bind Mounts)” 的区别

  • 绑定挂载:直接将宿主机上的任意目录或文件挂载到容器中(例如把 /home/user/my-app 挂载到容器)。它高度依赖宿主机的目录结构。
  • 卷(Volumes):是逻辑上的对象,与宿主机的特定目录结构解耦。它是 Docker 推荐的持久化数据方式,因为它更安全、更易于备份和迁移,且支持在多个容器之间共享。

总结:如果你想在 Docker 中安全、标准地保存数据(比如数据库文件、日志等),你应该优先选择 Volumes 而不是直接挂载宿主机的文件夹。

这段话是在介绍 Docker 数据持久化方案中 tmpfs mount 的使用场景。

什么是 tmpfs mount

tmpfs mount 是 Docker 提供的三种挂载方式之一(另外两种是 VolumesBind Mounts)。它的核心特点是:数据只存储在宿主机的内存(RAM)中,而不会写入磁盘。

为什么这里建议用它存储 “非持久化状态数据”?

  1. 安全性(Security):由于数据永远不会写入宿主机的磁盘,一旦容器停止,内存中的数据就会被释放。这非常适合存储敏感信息(如密码、密钥或临时令牌),防止这些信息在磁盘上留下痕迹。
  2. 高性能(Performance):读写内存的速度远快于读写磁盘(甚至是 SSD)。对于需要频繁读写的临时缓存或状态文件,使用 tmpfs 可以极大地提高 I/O 性能。
  3. 防止宿主机磁盘膨胀:一些程序会产生大量的临时日志或中间文件,如果这些数据不需要保留,使用 tmpfs 可以避免它们占用宿主机的存储空间。

总结对比

挂载方式存储位置是否持久化典型用途
Volumes 宿主机文件系统(Docker 管理)数据库数据、长期存储
Bind Mounts 宿主机任意位置源码同步、配置文件共享
tmpfs mount 仅内存密钥、高速缓存、临时状态

一句话总结: tmpfs mount 就是给容器开辟的一块 “临时内存盘”,关机或容器停止后数据即刻消失。

卷的生命周期与关键概念

  • 生命周期:卷独立于容器生命周期,容器销毁后卷仍存在;无运行容器使用时,卷不会自动删除,需通过 docker volume prune 清理未使用卷。
  • 卷的分类
    • 命名卷:用户自定义名称(如 my-vol),可重复使用,便于管理。
    • 匿名卷:Docker 自动生成随机唯一名称,容器删除时若用 --rm flag,匿名卷会随之删除;默认不与其他容器自动共享,需通过卷 ID 手动挂载。
  • 挂载对容器现有数据的影响
    • 非空卷挂载到容器目录:容器原有文件被 “遮蔽”,需重建容器移除挂载才能恢复。
    • 空卷挂载到容器目录:容器目录原有文件默认复制到卷中;可通过 volume-nocopy 选项禁用复制。

卷的操作语法与核心命令

挂载语法:–mount vs –volume

语法类型 格式示例 核心差异
--mount(推荐) docker run --mount type=volume,src=<卷名>,dst=<容器路径>,[选项] 更明确,支持所有选项(如卷驱动、子目录挂载),Swarm 服务必须用此语法
--volume(-v) docker run -v <卷名>:<容器路径>:[选项] 简洁,仅支持 readonlyvolume-nocopy 等基础选项

核心操作命令

  • 创建卷docker volume create <卷名>(如 docker volume create my-vol)。
  • 查看卷列表docker volume ls
  • 查看卷详情docker volume inspect <卷名>(显示挂载路径、驱动、选项等)。
  • 删除卷docker volume rm <卷名>;删除所有未使用卷:docker volume prune
  • 启动带卷的容器
    示例(--mount):docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
    示例(-v):docker run -d --name devtest -v myvol2:/app nginx:latest

卷的进阶使用场景与配置

与 Docker Compose 结合

  • 基础配置:在 compose.yaml 中通过 volumes 节点定义卷,服务自动使用该卷,首次运行 docker compose up 时创建卷,后续复用。
    1
    2
    3
    4
    5
    6
    7
    services:
    frontend:
    image: node:lts
    volumes:
    - myapp:/home/node/app
    volumes:
    myapp: # 自动创建命名卷
  • 引用外部已创建卷:需在 volumes 节点添加 external: true,指定卷已存在(如 docker volume create myapp 创建的卷)。

Docker Compose 是 Docker 官方提供的工具,用于定义和运行多容器 Docker 应用程序。它使用 YAML 文件来配置应用程序的服务、网络和卷,然后使用一个命令来启动和停止应用程序。

1. 核心定义

  • 多容器编排:普通的 Docker 命令通常一次只能管理一个容器。而现代应用往往由多个部分组成(例如:一个 Web 前端 + 一个后端 API + 一个数据库)。Docker Compose 允许你通过一个配置文件来统一管理这些相互关联的容器。
  • 声明式配置:你使用 YAML 文件(通常命名为 compose.yamldocker-compose.yml)来定义应用的所有服务、网络和卷。

2. 为什么需要它?

如果你不使用 Docker Compose,启动一个包含数据库的项目可能需要运行多条复杂的命令:

1
2
3
4
# 启动数据库
docker run -d --name db -e MYSQL_ROOT_PASSWORD=pass mysql
# 启动应用并连接到数据库
docker run -d --name app --link db:db -p 8080:8080 my-app-image

使用 Docker Compose 后,你只需要在一个 compose.yaml 文件中写好配置,然后运行:

1
docker compose up

Docker Compose 就会自动按照顺序创建网络、挂载卷并启动所有容器。

这里的含义是:

  • 自动化:你不需要手动运行 docker volume create myapp
  • 持久化:当你运行 docker compose up 时,Compose 会自动创建名为 myapp 的卷并挂载到 frontend 服务中。即使你删除了容器,只要卷还在,数据就不会丢失。

总结:Docker Compose = 配置文件 (YAML) + 一键启动命令。它是开发和测试环境中管理复杂容器应用的标准工具。

只读卷挂载

  • 场景:容器仅需读取卷数据,防止误修改。
  • 语法:--mount 添加 readonly,或 -v 添加 ro
    示例:docker run -d --name nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly nginx:latest

卷子目录挂载

  • 场景:多容器共享同一卷的不同子目录(如分别存储日志)。
  • 要求:子目录需提前在卷中创建。
  • 语法:--mount 添加 volume-subpath=<子目录>
    示例:
    1
    docker run -d --name=app1 --mount src=logs,dst=/var/log/app1,volume-subpath=app1 app1:latest
    挂载 logs 卷的 app1 子目录。

卷驱动与外部存储集成

  • 核心能力:通过卷驱动(如 rclonelocal)将卷挂载到外部存储(NFS、CIFS/Samba、块设备等),实现跨主机数据共享。
  • 常见配置示例:
    • NFSv4 卷(服务级):
      1
      docker service create -d --name nfs-service --mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,"volume-opt=o=addr=10.0.0.10,rw,nfsvers=4,async"' nginx:latest
    • CIFS/Samba 卷(本地):
      1
      docker volume create --driver local --opt type=cifs --opt device=//uxxxxx.your-server.de/backup --opt o=addr=uxxxxx.your-server.de,username=uxxxxxxx,password=*****,file_mode=0777,dir_mode=0777 --name cifs-volume

卷的备份、恢复与迁移

  • 备份卷:通过 --volumes-from 挂载目标卷,将卷内容压缩为 tar 包;示例:
    1
    docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
    备份 dbstore 容器的 /dbdata 卷到本地 backup.tar
  • 恢复卷:在新容器中挂载目标卷,解压 tar 包;示例:
    1
    docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
    恢复到 dbstore2 容器的 /dbdata 卷。

这条命令是一个非常经典且巧妙的 Docker 用法,通常用于 备份容器中的卷(Volume)数据

下面是对该命令 docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata 每一个部分的详细解析:

1. docker run

这是 Docker 的基础命令,用于创建一个新的容器并运行一个命令。

2. --rm

  • 作用:在容器退出时自动删除它。
  • 原因:这个容器只是为了执行备份操作(一个临时任务),备份完成后我们就不再需要它了。使用 --rm 可以保持系统的干净,避免留下大量停止状态的无用容器。

3. --volumes-from dbstore

  • 作用:让当前新创建的容器挂载来自另一个名为 dbstore 容器的所有卷。
  • 核心逻辑:假设 dbstore 容器有一个卷挂载在 /dbdata 目录下。通过这个参数,新容器(ubuntu)也能访问到这个 /dbdata 目录及其中的数据。

4. -v $(pwd):/backup

  • 作用:将宿主机(Host)当前所在的目录($(pwd))挂载到容器内的 /backup 目录。
  • 目的:这是为了给备份文件找一个 “出口”。容器内生成的备份文件存放在 /backup 下,实际上就直接写到了宿主机的当前目录下。

5. ubuntu

  • 作用:指定运行该命令所使用的镜像。
  • 选择原因:这里使用了一个轻量级的 ubuntu 镜像,因为它包含了我们需要用到的 tar 工具。其实任何带有 tar 命令的镜像(如 alpine)都可以。

6. tar cvf /backup/backup.tar /dbdata

这是在 ubuntu 容器启动后执行的实际命令:

  • tar: Linux 下常用的归档打包工具。
  • c (create): 创建一个新的归档文件。
  • v (verbose): 详细模式,在终端列出正在处理的文件。
  • f (file): 指定归档文件的名称。
  • /backup/backup.tar: 告诉 tar 把打包后的文件放在 /backup 目录下,命名为 backup.tar。由于之前做了 -v 挂载,这个文件会出现在宿主机的当前目录。
  • /dbdata: 告诉 tar 需要备份哪个目录。这个目录正是通过 --volumes-from dbstore 从目标容器 “借” 过来的数据目录。

总结:这个命令到底做了什么?

  1. 启动一个临时的 Ubuntu 容器
  2. dbstore 容器 那里把数据挂载过来(位于 /dbdata)。
  3. 宿主机当前目录 挂载进去(位于 /backup)。
  4. 在容器里执行 tar 打包,把 /dbdata 压缩成 backup.tar 并放到 /backup 里。
  5. 命令结束,容器自动销毁,而宿主机当前目录下就多了一个 backup.tar 备份文件。

这种方式的优点是不需要停止 dbstore 容器,也不需要知道卷在宿主机上的具体物理位置(由 Docker 自动管理)。

卷的清理与注意事项

  • 匿名卷清理:创建容器时加 --rm flag,容器删除时自动删除关联匿名卷(如 docker run --rm -v /foo busybox top)。
  • 注意事项
    • 卷的绑定传播固定为 rprivate(递归私有),不可配置。
    • 若卷驱动选项含逗号分隔值(如 NFS 挂载参数),需用双引号包裹选项,避免解析错误。
    • 块设备挂载需谨慎,需提前创建文件系统(如 ext4),并通过 volume-opt 指定设备路径和类型。

【AI 总结】Docker Volumes
https://blog.lllllan.cn/docker/storage/volumes/
作者
lllllan
发布于
2026年1月10日
许可协议