以无关容器的方式访问Docker的overlayfs技术
简要概括
在 Docker 容器内操作文件,通常使用 docker exec 运行 bash。但是,只有当容器正在运行时才能使用该方法操作。因此,我们考虑根据 docker inspect 的输出内容,在容器之外挂载 overlayfs 目录,并且不使用 Docker 来执行文件操作的方法。
环境
-
- Ubuntu 18.04 on Hyper-V
- XFS + overlay2 (c.f. https://qiita.com/haniokasai/items/87bbc2a7f48d777f95c8#_reference-fb9595a078fe57047287)
・・・
Server Version: 19.03.4
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
・・・
Kernel Version: 4.15.0-70-generic
Operating System: Ubuntu 18.04.3 LTS
OSType: linux
Architecture: x86_64
・・・
座降机构
「LowerDir」保存着比容器中新建立的文件更底层的文件。1 只读。
「WorkDir」是一个缓存区域,用于保持Upperdir中的文件具有原子性(文件完整性)。3
「Upperdir」记录了容器创建后的更改,并存储容器的独有数据。1
「挂载点或”MergedDir”」将上述三个文件夹合并在一起,成为文件操作的基础。在这里,可以纯粹地进行读写操作而无需考虑文件系统。1
挂载命令可以按照以下方式执行,没有问题。4
sudo mount -t overlay -o lowerdir=「"LowerDir"」,upperdir=「"UpperDir"」
,workdir=「"WorkDir"」 overlay 「マウントポイントまたは"MergedDir"」
以上的四个目录位置通过docker inspect命令可确定。
docker inspect コンテナ
・・・
"CpusetCpus": "",
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8-init/diff:/var/lib/docker/overlay2/35d8c38f712194bd9d57b9a433955c1141c1974c2b07bfb86b44bee0feb1f0d4/diff:/var/lib/docker/overlay2/018ec8b5d317fddd6fdb9634bf01d869bfd03f9122477a853317efb8d8ff2d86/diff:/var/lib/docker/overlay2/f7671e8be670d1ab91d5a63166374862d2c972448d7b1c4037cee15e1a7628da/diff:/var/lib/docker/overlay2/4fea42daa23e6120c2956ca1d2397d3829fdb8e9f03336ed2b4bd36c895fa53e/diff:/var/lib/docker/overlay2/a15984dba40e4afa1df1c5088b6d3a366e91c74c04ef9a19f7a9e061e6e59bea/diff:/var/lib/docker/overlay2/6f61ebd10ebd7fd6e07b0226b0ac71602d3152a8f9a09744c774998e3c0fdc47/diff:/var/lib/docker/overlay2/ae7ad5c9ce4f3051ad28d3fdc8270c8f7b2d11f63a1446156485e5aa1e9adb64/diff:/var/lib/docker/overlay2/8242e55feaed0c250e9919273671ff051b136853ce2b0e7cf4a499f68388e588/diff:/var/lib/docker/overlay2/fcfb7edf288d40aa1673e09955b1affc748561f5c4d55f01ea9dc3d4fdd418ab/diff",
"MergedDir": "/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8/merged",
"UpperDir": "/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8/diff",
"WorkDir": "/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "bind",
"Source": "/smx/docker_minecraft_res",
"Destination": "/minecraft/resources",
"Mode": "",
"RW": false,
"Propagation": "rprivate"
}
・・・
安装方法
長城
我们想要利用像《挂载机制》这一章中提到的挂载点。
以下是命令执行示例。
将挂载到 /mnt/test。
mount -t overlay overlay -o lowerdir="/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8-init/diff:/var/lib/docker/overlay2/35d8c38f712194bd9d57b9a433955c1141c1974c2b07bfb86b44bee0feb1f0d4/diff:/var/lib/docker/overlay2/018ec8b5d317fddd6fdb9634bf01d869bfd03f9122477a853317efb8d8ff2d86/diff:/var/lib/docker/overlay2/f7671e8be670d1ab91d5a63166374862d2c972448d7b1c4037cee15e1a7628da/diff:/var/lib/docker/overlay2/4fea42daa23e6120c2956ca1d2397d3829fdb8e9f03336ed2b4bd36c895fa53e/diff:/var/lib/docker/overlay2/a15984dba40e4afa1df1c5088b6d3a366e91c74c04ef9a19f7a9e061e6e59bea/diff:/var/lib/docker/overlay2/6f61ebd10ebd7fd6e07b0226b0ac71602d3152a8f9a09744c774998e3c0fdc47/diff:/var/lib/docker/overlay2/ae7ad5c9ce4f3051ad28d3fdc8270c8f7b2d11f63a1446156485e5aa1e9adb64/diff:/var/lib/docker/overlay2/8242e55feaed0c250e9919273671ff051b136853ce2b0e7cf4a499f68388e588/diff:/var/lib/docker/overlay2/fcfb7edf288d40aa1673e09955b1affc748561f5c4d55f01ea9dc3d4fdd418ab/diff",upperdir="/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8/diff",workdir= "/var/lib/docker/overlay2/1109be508e00968c34c73a5cd2c787ad6d3c4951f7b387700ace2b12daae8ec8/work" /mnt/test
我不想一遍又一遍地复制粘贴目录,所以让我们写一个脚本。或者,把它们整理成像下面这样的shell脚本,这样就可以更清晰地挂载了。
#!/bin/sh
CONTAINERNAME=コンテナ名
DOCKERHOST=unix:///var/run/docker.sock(各自で確認すること)
LOWERDIR=`docker -H ${DOCKERHOST} inspect --format='{{ .GraphDriver.Data.LowerDir }}' ${CONTAINERNAME}`
UPPERDIR=`docker -H ${DOCKERHOST} inspect --format='{{ .GraphDriver.Data.UpperDir}}' ${CONTAINERNAME}`
WORKDIR=`docker -H ${DOCKERHOST} inspect --format='{{ .GraphDriver.Data.WorkDir}}' ${CONTAINERNAME}`
MOUNTPOINT=/mnt/test
sudo mount -t overlay -o lowerdir=${LOWERDIR},upperdir=${UPPERDIR},workdir=${WORKDIR} overlay ${MOUNTPOINT}
执行结果
# umount /mnt/test
# ls /mnt/test
# ./test.sh
# ls /mnt/test
bin boot dev etc home lib lib32 lib64 libx32 media minecraft mnt opt proc root run sbin srv sys tmp usr var
取消挂载
很简单,只需指定挂载点。
umount /mnt/test
总结
迄今为止,Docker容器在启动失败时,恢复该容器非常困难。然而,使用这种方法,您可以执行操作而不受容器启动状态的影响。
回到MiRm的开发…
记事本
-
- Docker起動中にDocker側でのファイル編集はマウントポイントに反映されます
-
- storage-optのコンテナ毎の容量制限はマウントポイント内でも機能しています
- Dockerのオンオフは無視して問題なく、Docker内のmergedと同一の内容になります。
引述一个句子
以下是对所提供链接的本地化中文解释:
1. https://github.com/thomasweaver/docker-scanner/blob/e822bd8873b7225ce5c46f38226d232ea94f8124/scanner/Scanner/Mount.py
GitHub链接是关于docker-scanner项目中的Mount.py文件。
2. https://github.com/b00kwrm/tddd/blob/29edb508cf47c19872aa43a6b1558ad609205c69/tools/get-docker-fs.py
GitHub链接是关于tddd项目中的get-docker-fs.py文件。
3. https://github.com/att/docker-forensics/blob/944db5600bc9e7126f1d20e10499b4724bce4740/docker-mount.py
GitHub链接是关于docker-forensics项目中的docker-mount.py文件。
4. https://github.com/docker-forensics-toolkit/toolkit/blob/3fa4e46dbce7aef871ac2eec90caeed6cd921263/src/dof/model/container.py
GitHub链接是关于docker-forensics-toolkit项目中的container.py文件。
5. https://qiita.com/awakia/items/af9b46c322905cdce1d7
这个链接是一个Qiita上的文章,标题是”af9b46c322905cdce1d7″。
6. https://qiita.com/ryuichi1208/items/0bd0284dcf8a09299504
这个链接是一个Qiita上的文章,标题是”0bd0284dcf8a09299504″。
这篇文章看起来很有趣。
注释
以下是原始网址的中文释义:
http://docs.docker.jp/v1.9/engine/userguide/storagedriver/overlayfs-driver.html
https://www.clear-code.com/blog/2015/6/15.html
https://unix.stackexchange.com/questions/324515/linux-filesystem-overlay-what-is-workdir-used-for-overlayfs
https://wiki.archlinux.jp/index.php/Overlayfs