Docker 匿名卷、命名卷与绑定挂载 您所在的位置:网站首页 volumes文件 Docker 匿名卷、命名卷与绑定挂载

Docker 匿名卷、命名卷与绑定挂载

#Docker 匿名卷、命名卷与绑定挂载| 来源: 网络整理| 查看: 265

1 容器删除,容器内数据丢失

如果仅仅将数据存储在容器中,那么就会遇到一个问题:一旦容器被删除,所存储的数据将全部丢失。

2 卷

容器具有独立的文件系统,一般情况下与本机没有任何关联。Docker 使用卷实现容器内数据的持久保存。

Volumes are folders on your host machine hard drive, which are mounted(“made available”, mapped) into containers. 卷是主机文件夹,被映射到容器中。

在这里插入图片描述 这两个文件夹中的任意一个发生变化,都会反映到另一个文件夹。容器既可以写入数据到卷,也可以从卷中读出数据。

卷分为匿名卷和命名卷。

2.1 匿名卷 (Anonymous Volumes)

在 Dockerfile 中,匿名卷的指令格式: VOLUME ["folder_name"],folder_name 为容器内的文件夹( / 路径)。 以下是一个 node app 的 Dockerfile:

FROM node WORKDIR /app COPY package.json . RUN npm install COPY . . EXPOSE 80 VOLUME ["/app/feedback"] CMD [ "node", "server.js" ]

docker 将匿名卷隐藏存放在本地的未知路径。

如果容器启动时使用了 --rm 选项,容器停止时,容器被自动删除,匿名卷也会自动被删除。 反之,如果没有--rm选项,即使使用命名 docker container rm my_container 删除了容器,匿名卷不会被自动删除。每次创建新的容器,都会重新创建新的匿名卷。 重启容器则使用已有附加的匿名卷。

可以在Dockerfile 中指定创建匿名卷,也可以在创建容器时指定匿名卷。

要删除匿名卷,使用命令 docker volume rm 或者 prune.

2.2 命名卷 (Named Volumes)

与匿名卷相反,命名卷不会被附加到具体容器上,如果容器被删除,命名卷会保留。 同匿名卷,被 docker 隐藏存放在本地的未知路径,不易寻找,不应访问或者编辑命名卷。

不能在 Dockerfile 内创建命名卷,只能在运行容器时指定,使用-v 选项,v 即 volume,语法格式: -v 任意名称:容器内路径, 例如: docker container run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback feedback-node:volumes

2.3 与卷相关的命令

docker volume --help 列举与卷相关的命令:

Commands: create Create a volume inspect Display detailed information on one or more volumes ls List volumes prune Remove all unused local volumes rm Remove one or more volumes

docker volume ls 列出所有卷

3 绑定挂载 (由开发者管理,可用于代码调试)

绑定挂载也是映射本地文件夹到运行的容器,与卷不同的是,可以直接修改本地文件夹,修改直接反映到容器。应用可以是,将app 的源代码文件夹进行绑定挂载,编辑源代码,容器中的 image 自动被修改。 从而避免 1. 修改代码 -> 2. stop 容器 -> 3. 重新 build image ->4. 重新启动容器 这一重复的开发过程。

在这里插入图片描述 绑定挂载同样在运行容器时指定,同命名卷,不能在 Dockerfile 中指定。命令格式:

-v 绝对路径:容器内文件夹

对于如下的 Dockerfile,源代码被copy到 WORKDIR /app,

FROM node WORKDIR /app COPY package.json . RUN npm install COPY . . EXPOSE 80 CMD [ "node", "server.js" ]

因此冒号右边是 /app,对于 windows 系统,命令如下:

docker container run -p 3000:80 --name feedback-app --rm -v feedback:/app/feedback -v ${PWD}:/app feedback-node:volumes

也可以不用 ${PWD}而是 copy 整个路径,例如 vs code explorer 里,右键"copy path",

-v D:\temp\data-volumes-01-starting-setup:/app 使用 -v "D:\temp\data-volumes-01-starting-setup:/app" 即加双引号更好,以防止特殊字符使命令不起作用。

如果本地文件夹没有 node_modules, 此命令将无法启动容器,原因是,本地文件夹没有 node_modules,绑定挂载使得本地的文件完全覆盖了 /app 里的文件,app 缺少依赖包,无法运行。 解决方法是,使用匿名卷。 使用绑定挂载,本地文件夹将覆盖容器文件夹,而不是反过来,毕竟,容器删除或修改本地源代码是不能容忍的。 为了防止容器内的 node_modules 因为本地没有而被删除,使用匿名卷,上述命令修改如下:

docker container run -d -p 3000:80 --name feedback-app --rm -v feedback:/app/feedback -v ${PWD}:/app -v /app/node_modules feedback-node:volumes

此命令中使用了:

命名卷:容器删除后保存数据, -v feedback:/app/feedback绑定挂载:代码调试, -v ${PWD}:/app,还需要步骤3的匿名卷因为步骤2,使用绑定挂载,本地文件夹覆盖了容器内的文件夹,容器内新生成的node_modules被删除,因此增加匿名卷 -v /app/node_modules

当卷存在冲突时,docker指定路径越长越具体优先级越高,/app/node_modules路径比/app长,因此,匿名卷的由 npm install 生成的文件夹 node_modules 将覆盖绑定挂载的空的 app/node_modules。

将绑定挂载设定为容器只能读取,无法写入,在路径后加 :ro,同时为了保证源代码中的 temp 文件夹允许容器写入,增加匿名卷 -v /app/temp:

docker container run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback -v ${PWD}:/app:ro -v /app/temp -v /app/node_modules feedback-node:volumes

容器正在运行,此时VS code 修改代码,例如 MySite 改成,MySite!!!!!,保存,然后浏览器页面刷新,就可以看到对应的界面已经被修改: 在这里插入图片描述

4 命名卷、匿名卷与绑定挂载三者比较

在这里插入图片描述

匿名卷,不管是在 Dockerfile 中指定,还是在命令行指定,都可以锁定容器中已经存在的某些数据。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有