URL
date
AI summary
slug
status
tags
summary
type

问题描述

在MacOS上使用Docker的同学,不知道你有没有碰到过下面这个问题:
👉
当你想要修改或查看docker容器内的文件时,提示你No sush file or directory
我们知道,docker通过volume机制来完成容器内文件到宿主机磁盘的映射,而volume的默认挂载路径在 /var/lib/docker/volumes 目录下。我们可以通过 docker inspect container_name来查看指定容器挂载的volume
docker inspect mysql_local_test
如下显示的Source就是我们对应的volume在宿主机文件系统的路径
notion image
但是在MacOS中,你直接访问对应路径,会提示No sush file or directory
notion image

Solutions

借助Google,我总结了下面4种解决方案,可以让你更好的查看或者修改容器内的文件

1. 使用nsenter

docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
这也是网上流传最多的方案了,试了下确实是可以访问到对应目录 启动了一个容器,并执行nsenter命令后,就能访问到之前的目录了
notion image
但是这种方式只能用命令行的方式查看文件,但是比如我想用可视化的软件打开文件查看,就不行了。

2. 使用容器 + volume的方式

docker run -it -v /var/lib/docker:/var/lib/docker debian sh
这种方式就直接使用了volume的方式,把容器里的/var/lib/docker挂载到了宿主机上对应的目录,这样我们就能直接读写了。
notion image
不过这样还是没法用可视化的软件打开,这个时候我们可以再挂载一个目标目录,这个目录在我们的MacOS下是可以读写的即可。然后在容器内通过cp命令(目录的话需要加-r),把我们要读取的文件copy到目标目录下,就可以实现了。
docker run -it -v /var/lib/docker:/var/lib/docker -v /Users/zhuzhuchao/volume-test:/volume-test debian sh
notion image
我们从MacOS上访问对应目录看看是不是有东西了
notion image
如果通过可视化软件修改完之后需要再同步到容器里,这个时候可以用同样的方式,cp覆盖过去
如果仅仅是需要访问某个volume里面的内容,推荐下面这种方式,更加简单
docker run --mount source=d4c6c40d88ffa448b4b360ae13b14726c207ba61218ef5a978d7628a4df19a3f,target=/app -it debian /bin/sh

3. 使用容器 + volume + 修改volume的方式

这个是方案2的升级版,首先需要按照方案2完成原volume的copy,然后再修改原容器的volume,直接指向copy之后的目录,一劳永逸,两边修改都是同一份文件,也免去了cp来cp去的烦恼。
我们看看如何修改容器的volume,问了下chatgpt
notion image
试了下,被告知命令不支持,并且去官网看了,也没有--mount参数,所以此方法估计不太可行。
notion image
还有一种是可以通过修改容器的conf文件,但是我看了下conf文件里面不止一个文件有挂载路径相关的配置,所以为了防止改出更多的问题,还是不建议尝试了。
最后,换一种思路,因为容器本身就是轻量级的东西,本身不保存任何状态,所以我们再起一个新容器,然后复用原先的volume是不是就可以了。嗯,非常有效。

4. 通过Kitematic工具修改Volume

这个工具也是在解决这个问题过程中发现的一个可视化的Docker工具,不过就是这个工具害我差点以为数据丢了。
启动之后,左边是所有container,选中一个之后,会展示container相关的信息,其实volumes列出了相关的volumes信息。单机之后,会弹出一个提示。在enable volumes之前,你需要知道,一旦你点了,其实它会帮你创建一个新的目录,并且这个目录你的MacOS可以直接读写,然后替换容器原来的Volume,但是原来的Volume还在,只是这个Container不再使用了。如果你了解了这一点,那就enable吧,然后用前面的方法,把之前volume的数据迁移过来,就可以直接通过可视化管理啦
notion image

总结

如果你使用了默认挂载路径,那么上面这4种方案,肯定是方案3最好了,一劳永逸而且操作起来也不复杂。
当然你可以从一开始就规避这个问题,直接不要使用默认的挂载路径,自己指定挂载路径,那么就不会碰到这个问题

参考

  1. https://sealhuang.github.io/migrate-docker-volume-from-one-host-to-another
  1. https://blog.csdn.net/qq_43758789/article/details/121272433
  1. https://docs.docker.com/engine/reference/commandline/container_update/
RocketMQ使用docker启动导致2台消费者实例instanceId相同带你透过源码理解SpringBoot配置文件加载流程