Docker 持久化存储 Volumes

Docker卷是容器数据持久化的推荐方式,提供跨平台兼容性和安全性。--mount比-v更详细,适合指定卷驱动程序选项和服务创建。创建和管理卷包括创建、列出、检查和删除。使用-v或--mount可挂载卷到容器,支持只读模式。删除容器不会自动删除匿名卷,使用volumeprune可清理未使用卷。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


简介

官方文档: https://docs.docker.com/storage/volumes/

卷是持久化Docker容器生成和使用的数据的首选机制。虽然绑定挂载依赖于主机的目录结构和操作系统,但卷完全由Docker管理。与绑定挂载相比,卷具有以下几个优势:

  • 卷比绑定挂载更容易备份或迁移。
  • 可以使用Docker CLI命令或Docker API管理卷。
  • 卷可以在Linux和Windows容器上工作。
  • 可以在多个容器之间更安全地共享卷。
  • 卷驱动程序允许将卷存储在远程主机或云提供商上,以加密卷的内容或添加其他功能。
  • 新卷的内容可以由容器预先填充。

在这里插入图片描述


如何选择 -v 和 --mount

一般来说,--mount 更加明确和详细。最大的区别是-v 语法将所有选项组合在一个字段中,而--mount语法将它们分开。

  • 如果需要指定卷驱动程序选项,则必须使用 --mount
  • 创建服务时,使用 --mount

-v或–volume

由三个字段组成,用冒号(:)分隔。字段必须按正确的顺序排列,并且每个字段的含义不同。

docker run -d --name vtest  -v myvol2:/app:ro nginx:latest
#								[1]    [2] [3]
  • [1]: 对于命名卷,第一个字段是卷的名称,并且在给定的主机上是唯一的。对于匿名卷,第一个字段被省略,由docker 生成。
  • [2]: 第二个字段是容器中要挂载的目录或文件路径。
  • [3]: 第三个字段是可选的,是一个逗号分隔的选项列表,如ro。

–mount

由多个键值对组成,用逗号分隔,每个键值对由一个<key>=<value>元组组成。--mount语法比-v或--volume更详细,但键的顺序并不重要。

  • type 键:值可以为 bind volume tmpfs
  • source 键: 值为挂载的来源,对于命名卷,是卷的名称。对于匿名卷,此字段被省略。也可以写成为 src
  • destination 键: 值为要挂载到容器中的目录或文件的路径,也可以写成 dst 或者 target
  • readonly 选项如果存在,会以只读方式挂载到容器。也可以写成 ro
    docker run -d \
      --name=nginxtest \
      --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
      nginx:latest
    
  • volume-opt 可以指定多次,选项名称和其值组成的键值对。

    从外部CSV解析器中转义值
    如果卷驱动程序接受以逗号分隔的列表作为选项,则必须从外部CSV解析器中转义该值。要转义volume-opt,用双引号(“)将volume-opt括起来,并用单引号(')将整个mount参数括起来。
    例如,本地驱动程序接受挂载选项作为o参数中逗号分隔的列表。此示例演示了转义列表的正确方法。

    docker service create \
        --mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
        --name myservice \
        <IMAGE>
    

创建和管理卷

  • 创建卷
    docker volume create my-vol
    
  • 列出卷
    docker volume ls
    local               my-vol
    
  • 查看卷详情
    docker volume inspect my-vol
    [
        {
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
            "Name": "my-vol",
            "Options": {},
            "Scope": "local"
        }
    ]
    
  • 删除卷
    docker volume rm my-vol
    

启动带有卷的容器

如果用一个不存在的卷启动一个容器,Docker会创建该卷。以下示例将卷 myvol2 挂载到容器中的 /app/ 中。

  • --mount
    docker run -d \
      --name devtest \
      --mount source=myvol2,target=/app \
      nginx:latest
    
    
  • -v
    docker run -d \
      --name devtest \
      -v myvol2:/app \
      nginx:latest
    

【注】:--mount-v 示例产生的效果一样。

  • 使用 docker inspect devtest 查看docker 是否创建了卷,并正确挂载到容器中。
    "Mounts": [
        {
            "Type": "volume",
            "Name": "myvol2",
            "Source": "/var/lib/docker/volumes/myvol2/_data",
            "Destination": "/app",
            "Driver": "local",
            "Mode": "",
            "RW": true,
            "Propagation": ""
        }
    ],
    

    这表明挂载是一个卷,并且源路径和目标路径正确,权限是读写。

  • 删除容器和卷
    docker container stop devtest
    docker container rm devtest
    docker volume rm myvol2
    

使用Docker Compose的卷

  • 下面的示例展示了一个带有卷的Docker Compose服务:
    services:
      frontend:
        image: node:lts
        volumes:
          - myapp:/home/node/app
    volumes:
      myapp:
    

第一次运行docker compose up会创建一个卷。当随后运行该命令时,Docker会重用相同的卷。

  • 也可以使用docker volume create直接在Compose 外部创建一个卷,然后在docker-Compose.yml内部引用它,如下所示:
    services:
      frontend:
        image: node:lts
        volumes:
          - myapp:/home/node/app
    volumes:
      myapp:
        external: true
    
    

使用卷启动服务

启动服务并定义卷时,每个服务容器都使用自己的本地卷。如果使用本地卷驱动程序,则任何容器都无法共享此数据。但是,有些卷驱动程序确实支持共享存储。
以下示例启动一个具有四个副本的nginx服务,每个副本使用一个名为myvol2的本地卷。

docker service create -d \
  --replicas=4 \
  --name devtest-service \
  --mount source=myvol2,target=/app \
  nginx:latest
  

使用 docker service ps devtest-service 服务来验证服务是否正在运行:

docker service ps devtest-service

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
4d7oz1j85wwn        devtest-service.1   nginx:latest        moby                Running             Running 14 seconds ago

删除服务以停止正在运行的任务:

docker service rm devtest-service

删除该服务不会删除该服务创建的任何卷。删除卷是一个单独的步骤。

docker service create 不支持 -v 或者 --volume ,必须使用 --mount


使用只读卷

设置权限

  • --mount

    docker run -d \
      --name=nginxtest \
      --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
      nginx:latest
    
  • -v

    docker run -d \
      --name=nginxtest \
      -v nginx-vol:/usr/share/nginx/html:ro \
      nginx:latest
    
    

    有多个权限选项时,用逗号隔开。

  • 使用 docker inspect nginxtest, 查看详情,只看 Mount 部分就好。

    "Mounts": [
        {
            "Type": "volume",
            "Name": "nginx-vol",
            "Source": "/var/lib/docker/volumes/nginx-vol/_data",
            "Destination": "/usr/share/nginx/html",
            "Driver": "local",
            "Mode": "",
            "RW": false,
            "Propagation": ""
        }
    ],
    

备份、恢复或迁移数据卷

备份卷

  • 创建一个容器 dbstore

    docker run -v /dbdata --name dbstore ubuntu /bin/bash
    
  • 备份

    • 创建一个新容器并从 dbstore 容器挂载卷。
    • 将本地目录挂载到容器 /backup
    • /dbdata 的内容打包到 /backup/backup.tar 中。
      docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
      

      当命令执行结束容器停止时,dbdata 备份完成。

  • 从备份还原卷
    使用刚刚创建的备份,可以将其恢复到同一个容器,或者恢复到另一个容器。

    • 恢复到另一个容器 dbstore2
      docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
      
      docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
      

删除卷

自动删除匿名卷

删除容器时并不会自动删除匿名卷,运行容器时使用 --rm 选项自动删除匿名卷。

docker run --rm -v /foo -v awesome:/bar busybox top

--rm 可以自动删除 /foo 的匿名卷,但是命名卷 awesome 不会被删除。

如果其它容器使用 --volumes-from 绑定了匿名卷,容器删除时,匿名卷会被保留,不会被删除。


删除所有未使用卷

  • 删除所有未使用的卷释放空间
docker volume prune



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值