如何删除现有容器的挂载?
How to remove a mount for existing container?
我正在学习 docker 并阅读他们的章节 "Manage data in containers"。在"Mount a host directory as a data volume"。他们提到了以下段落:
In addition to creating a volume using the -v flag you can also mount a directory from your Docker engine’s host into a container.
$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
This command mounts the host directory, /src/webapp, into the container at /opt/webapp. If the path /opt/webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.
实验 1
然后当我尝试运行这个命令并尝试检查容器时,我发现实际上那个容器甚至没有运行。然后我使用 docker logs web
并发现这个错误:
can't open file 'app.py': [Errno 2] No such file or directory
I assume that the /src/webapp mount overlays on the /opt/webapp, which there is no content.
问题 1
我怎样才能删除这个挂载并检查内容是否仍然如引用所说?
实验二
当我尝试 运行
$ docker 运行 -d -P --name web2 -v newvolume:/opt/webapp training/webapp python app.py
我发现容器 运行 正确。然后我使用 docker exec -it web2 /bin/bash
并发现所有现有内容仍在 /opt/webapp 内。我还可以在此处添加更多文件。所以在这种情况下,看起来体积不是叠加而是合并。如果我使用 docker inspect web
并检查 Mounts,那么我会看到该卷是在 /var/lib/docker/volumes/newvolume/_data
下创建的
问题 2
如果我给出一个名称而不是主机目录绝对路径,那么该卷将不会覆盖容器目录 /opt/webapp 而是将两个目录连接在一起?
另一种解决方案是使用 docker cli 提交容器(或导出它)并在不进行映射的情况下重新创建它。
Question 1 How can I remove this mount and check if the content is still there as the quote said?
您将创建一个没有卷装载的新容器。例如
$ docker run -d -P --name web training/webapp python app.py
(理论上可以执行一些特权操作来删除 运行 容器上的挂载,但在容器内你通常不会有这个权限,养成这样的习惯是个好习惯将容器视为临时容器。)
Question 2 If I give a name instead of a host-dir absolute path, then the volume will not overlay the container-dir /opt/webapp but connect the two dir together?
差不多。命名卷发生的事情是 docker 在卷为空时提供初始化步骤并且使用该卷安装创建容器。初始化步骤将该目录中的图像内容复制到卷中,包括递归的所有文件和目录、所有权和权限。这对于 运行 容器非常有用,因为非根用户具有容器内的用户需要能够写入的卷目录。初始化发生后,具有相同命名卷的未来容器将跳过初始化,即使图像内容已更改,例如如果您在图像中添加新内容。
我正在学习 docker 并阅读他们的章节 "Manage data in containers"。在"Mount a host directory as a data volume"。他们提到了以下段落:
In addition to creating a volume using the -v flag you can also mount a directory from your Docker engine’s host into a container.
$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
This command mounts the host directory, /src/webapp, into the container at /opt/webapp. If the path /opt/webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.
实验 1
然后当我尝试运行这个命令并尝试检查容器时,我发现实际上那个容器甚至没有运行。然后我使用 docker logs web
并发现这个错误:
can't open file 'app.py': [Errno 2] No such file or directory I assume that the /src/webapp mount overlays on the /opt/webapp, which there is no content.
问题 1 我怎样才能删除这个挂载并检查内容是否仍然如引用所说?
实验二
当我尝试 运行
$ docker 运行 -d -P --name web2 -v newvolume:/opt/webapp training/webapp python app.py
我发现容器 运行 正确。然后我使用 docker exec -it web2 /bin/bash
并发现所有现有内容仍在 /opt/webapp 内。我还可以在此处添加更多文件。所以在这种情况下,看起来体积不是叠加而是合并。如果我使用 docker inspect web
并检查 Mounts,那么我会看到该卷是在 /var/lib/docker/volumes/newvolume/_data
问题 2 如果我给出一个名称而不是主机目录绝对路径,那么该卷将不会覆盖容器目录 /opt/webapp 而是将两个目录连接在一起?
另一种解决方案是使用 docker cli 提交容器(或导出它)并在不进行映射的情况下重新创建它。
Question 1 How can I remove this mount and check if the content is still there as the quote said?
您将创建一个没有卷装载的新容器。例如
$ docker run -d -P --name web training/webapp python app.py
(理论上可以执行一些特权操作来删除 运行 容器上的挂载,但在容器内你通常不会有这个权限,养成这样的习惯是个好习惯将容器视为临时容器。)
Question 2 If I give a name instead of a host-dir absolute path, then the volume will not overlay the container-dir /opt/webapp but connect the two dir together?
差不多。命名卷发生的事情是 docker 在卷为空时提供初始化步骤并且使用该卷安装创建容器。初始化步骤将该目录中的图像内容复制到卷中,包括递归的所有文件和目录、所有权和权限。这对于 运行 容器非常有用,因为非根用户具有容器内的用户需要能够写入的卷目录。初始化发生后,具有相同命名卷的未来容器将跳过初始化,即使图像内容已更改,例如如果您在图像中添加新内容。