是否可以挂载docker映像,然后将其作为普通目录或已挂载的设备进行访问(RO)?

fbr*_*sch 8 docker

我想拍摄一个Docker映像(比如说ubuntu:latest),然后做类似的事情:

> docker-image-mount ubuntu:latest my_little_ubuntu  
> cd my_little_ubuntu
> ls
/usr /var /bin etc.
Run Code Online (Sandbox Code Playgroud)

有可能吗?

ave*_*rin 7

您可以使用 Podman 和 Buildah 挂载容器映像(RW)。

prompt:~ # podman pull ubuntu

prompt:~ # container=`buildah from ubuntu`

prompt:~ # echo $container
ubuntu-working-container

prompt:~ # mnt=`buildah mount $container`

prompt:~ # echo $mnt
/var/lib/containers/storage/overlay/2b1...09b/merged

prompt:~ # ls $mnt
bin  boot  dev  etc  home  lib  ...  usr  var

prompt:~ # buildah umount $container
Run Code Online (Sandbox Code Playgroud)

如果您确实想挂载正在运行或已停止的容器,可以使用该podman mount命令挂载它。


Via*_*lev 5

我刚刚研究了docker存储映像的内部结构。如果是aufs存储驱动程序,则存在以下目录布局(我假设docker生活在中/var/lib/docker)。

  • /var/lib/docker/aufs/diff泊坞窗在该目录中存储每个图像“层”的数据。它只是一个包含文件的目录,docker安装在容器根目录中。
  • /var/lib/docker/aufs/layers在此目录中,泊坞窗仅存储文本文件。每个文件都包含特定图像的层ID列表。

因此,docker本身会执行以下操作:

DOCKER_AUFS_PATH="/var/lib/docker/aufs/"
DOCKER_AUFS_LAYERS="${DOCKER_AUFS_PATH}/layers/"
DOCKER_AUFS_DIFF="${DOCKER_AUFS_PATH}/diff/"

error() { echo "$@" 1>&2; }

if [ -z "${IMAGE}" ];
then
  error "Image is not specified"
  exit 1
fi;

if [ -z "${TARGET}" ];
then
  error "Target is not specified"
  exit 1
fi;

BRANCH="br"
while read LAYER; do
  BRANCH+=":${DOCKER_AUFS_DIFF}/${LAYER}=ro+wh"
done < "${DOCKER_AUFS_LAYERS}/${IMAGE}"

mount -t aufs -o "${BRANCH}" "${IMAGE}" "${TARGET}"
Run Code Online (Sandbox Code Playgroud)

其中$ {IMAGE}是docker容器的ID,而$ {TARGET}是主机文件系统中用于装载映像的目录。

要卸载它,只需调用:

umount cf39b476aeec4d2bd097945a14a147dc52e16bd88511ed931357a5cd6f6590de

正如我在上面的评论中提到的那样,这在很大程度上取决于存储驱动程序(显然取决于docker版本),因此我无法保证您可以使此代码正常工作。