假设你有一个这样的工作目录:
$ tree .
.
??? Dockerfile
??? file.txt
Run Code Online (Sandbox Code Playgroud)
并且Dockerfile
包含:
FROM debian:9
WORKDIR /usr/src/foo
COPY file.txt .
RUN echo Some random command involving file.txt \
&& rm -f file.txt
Run Code Online (Sandbox Code Playgroud)
然后构建相应的镜像并将其推送到给定的 Docker 注册表:
$ docker build -t foo/bar .
$ docker login #…
$ docker push foo/bar
Run Code Online (Sandbox Code Playgroud)
有没有一种方法(或几种方法)从图像中检索file.txt
,添加内容然后在中间层中删除?答案是否取决于 的选择WORKDIR
?
有没有一种方法(或几种方法)可以从图像中检索在中间层中添加然后删除的 file.txt 的内容?
是的!
答案是否取决于 WORKDIR 的选择?
号WORKDIR
不会做的比改变当前的工作目录以外的任何其他。
当您从 Dockerfile 构建映像时,Dockerfile 中的每个指令都会创建一个新层。“映像”只是在运行容器时组合起来形成容器文件系统的层的集合。这些层中的每一个都可以在磁盘上的/var/lib/docker
. 例如,假设我使用这个 Dockerfile 构建了一个镜像:
FROM debian:9
COPY file.txt /root/file.txt
RUN rm -f /root/file.txt
Run Code Online (Sandbox Code Playgroud)
在该目录中,我有一个名为的文件file.txt
,其中包含以下文本:
hello world
Run Code Online (Sandbox Code Playgroud)
如果我运行docker build -t erikmd .
,我会看到:
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM debian:9
---> d508d16c64cd
Step 2/3 : COPY file.txt /root/file.txt
---> Using cache
---> 6f06029c1cca
Step 3/3 : RUN rm -f /root/file.txt
---> Using cache
---> a2dc62c823c9
Successfully built a2dc62c823c9
Successfully tagged erikmd:latest
Run Code Online (Sandbox Code Playgroud)
在构建过程中的每一步都生成新的层,并且它是提供使用表示中间图像是所有的结果Dockerfile命令到该点的图像ID。鉴于关于输出,我可以运行:
$ docker run --rm 6f06029c1cca cat /root/file.txt
Run Code Online (Sandbox Code Playgroud)
并查看文件的内容:
hello world
Run Code Online (Sandbox Code Playgroud)
但是,如果我不只是构建图像呢?在这种情况下,我将首先使用docker image inspect
命令查看包含图像的图层列表:
$ docker image inspect erikmd | jq '.[0].RootFS.Layers'
[
"sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303",
"sha256:41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e",
"sha256:1948a4bd00b6f1712667bb2c68d1fe6eb60fbbcdf8bad62653208c23bf2602a5"
]
Run Code Online (Sandbox Code Playgroud)
上面,jq
只是一个查询JSON数据的工具。如果您不方便,您可以目视检查docker image inspect
相同信息的输出jq
。
假设使用overlay2
存储驱动程序的默认 Docker 配置,您将在/var/lib/docker/image/overlay2/layerdb/sha256/*/diff
. 因此,例如:
# grep -l 13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303 \
/var/lib/docker/image/overlay2/layerdb/sha256/*/diff
/var/lib/docker/image/overlay2/layerdb/sha256/13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303/diff
Run Code Online (Sandbox Code Playgroud)
第一层是debian:9
图像。我们可以通过运行来确认:
$ docker image inspect debian:9 | jq '.[0].RootFS.Layers'
[
"sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303"
]
Run Code Online (Sandbox Code Playgroud)
......所以我们会忽略它。让我们找到第二层:
# grep -l 41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e \
/var/lib/docker/image/overlay2/layerdb/sha256/*/diff
/var/lib/docker/image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/diff
Run Code Online (Sandbox Code Playgroud)
在与该diff
文件相同的目录中,我们会找到一个名为的文件cache-id
:
# cat image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/cache-id
118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75
Run Code Online (Sandbox Code Playgroud)
即cache-id
识别到其中的层已经被提取的目录; 我们可以在下面找到它/var/lib/docker/overlay2/<id>
:
# ls /var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75
diff/ link lower work/
Run Code Online (Sandbox Code Playgroud)
我们对diff/
目录的内容感兴趣:
# find /var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef6
21ccb70cf14fe672dc74ef75/diff/
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/root
/var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75/diff/root/file.txt
Run Code Online (Sandbox Code Playgroud)
就在那里!
注意以上所有假设您使用的是overlay2
存储驱动程序(这是当今大多数平台(如果不是所有平台)的默认设置)。如果您使用不同的驱动程序,磁盘上的布局将有所不同。
归档时间: |
|
查看次数: |
296 次 |
最近记录: |