已经启动的 Docker 容器如何挂载目录?

在系统是 CentOS6.7 的阿里云 ECS 里,有一个已在运行的 Docker 容器,想在容器里挂载一个宿主的本地目录,这样某些容器里输出的文件,就可以在本地目录中打开访问了。请问如何挂载呢?

但是搜了一圈发现这个问题很少人问,难道是我问的方式不对吗,还是大家都是有别的办法实现?大胆想象一下可能别人是停掉容器然后重新 docker run -v *** 再恢复数据?

看来 Docker 容器已经在跑了,要挂载一个新目录是一件很麻烦的事情?我找了很久,只搜到一条答案:http://dockerone.com/article/149 ,而且跟着步骤做到【找到文件系统的设备(和sub-root)】这一步,我 $DEV 和 $SUBROOT 的输出是 rootfs 和 / ,跟文中完全不一样。

请问我可以怎么做呢?

阅读 58.8k
6 个回答

这里讨论是说,没有人会做这件事。

你可以用docker cp把运行中的容器中的文件拷贝出来,停掉,再用docker run -v挂上你想要的卷。

不用过度纠结,docker官方并没有提供给你运行容器修改/添加挂载配置的操作。参照
Yujiaao 的方法,是相对最简单的实用的。PS:旧的容器容器停止后,可以不急着删除,如果文件遗漏还可以重新拷贝,或在在异常时,重新启动,恢复运行

你可以通过修改 docker 的源码来实现。

可以通过在容器内创建磁盘设备文件,然后把整个分区挂载进容器。

先看宿主的块设备:

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    1   7.2G  0 disk
└─sda1        8:1    1   7.2G  0 part
nvme0n1     259:0    0 119.2G  0 disk
├─nvme0n1p1 259:1    0   260M  0 part /boot
├─nvme0n1p2 259:2    0   128M  0 part
├─nvme0n1p3 259:3    0   118G  0 part /
└─nvme0n1p4 259:4    0   850M  0 part

记下要挂载的分区的设备号(例如/的259:3)。

# 启动一个容器,没什么特殊参数
docker run -itd --name demo alpine:latest sh 

#在容器内创建一个设备节点
$ docker exec demo mknod -m 0500 /dev/nvme0n1p3 b 259 3 

# 找到容器PID=1的进程PID
$ docker top demo
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                4189                4174                0                   23:07               pts/0               00:00:00            sh

# 通过命名空间挂载磁盘
$ docker exec demo mkdir /data
$ sudo mount -N 4189 /dev/nvme0n1p3 /data

# 访问试试
$ docker exec demo ls -lh /data
total 16
-rw-r--r--    1 root     root         108 Jan 20  2019 archlinux
lrwxrwxrwx    1 root     root           7 May 23 14:18 bin -> usr/bin
drwxr-xr-x    2 root     root           6 Jan 20  2019 boot
...

分区都挂载进去了,干啥都行了~

弄完才发现和题主发的文章大同小异:-|

说个与 docker 无关的方法:

sshfs 可以透过 ssh 连接挂载文件系统。在容器里装一个可以通过 ssh 把宿主的目录挂进来。docker exec 新开一个 shell 搞这事就可以。这样目录里的内容存在容器外。

如果容器暴露了 ssh 端口,也可以在外面用 sshfs 把里面的目录挂出来。这样文件夹里的内容实际在容器里。容器没了就没了。

通过 ssh 不只可以挂宿主机的目录,有 ssh 连接哪里的目录都可以挂。

docker默认没提供这个功能.

但是可以先把容器停掉, 用docker commit 创建一个新的image, 然后在运行新的image时挂载.

docker stop 容器名
docker commit 容器名 新的镜像名
docker run -v "挂载" 新的镜像名
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏