如何檢索已在 Docker 映像中添加然後刪除的文件?
假設您有一個這樣的工作目錄:
$ tree . . ├── Dockerfile └── file.txt
並且
Dockerfile
包含:FROM debian:9 WORKDIR /usr/src/foo COPY file.txt . RUN echo Some random command involving file.txt \ && rm -f file.txt
然後建構相應的鏡像並將其推送到給定的 Docker 系統資料庫:
$ docker build -t foo/bar . $ docker login #… $ docker push foo/bar
有沒有一種方法(或幾種方法)從圖像中檢索,其內容
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
在該目錄中,我有一個名為的文件
file.txt
,其中包含以下文本:hello world
如果我執行
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
建構過程中的每一步都會生成一個新層,它會為您提供一個表示中間鏡像的鏡像 ID,該中間鏡像是到目前為止所有 Dockerfile 命令的結果。鑑於關於輸出,我可以執行:
$ docker run --rm 6f06029c1cca cat /root/file.txt
並查看文件內容:
hello world
但是,如果我不只是建構圖像怎麼辦?在這種情況下,我將首先使用
docker image inspect
命令查看構成圖像的層列表:$ docker image inspect erikmd | jq '.[0].RootFS.Layers' [ "sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303", "sha256:41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e", "sha256:1948a4bd00b6f1712667bb2c68d1fe6eb60fbbcdf8bad62653208c23bf2602a5" ]
在上面,
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
第一層是
debian:9
圖像。我們可以通過執行來確認:$ docker image inspect debian:9 | jq '.[0].RootFS.Layers' [ "sha256:13d5529fd232cacdd8cd561148560e0bf5d65dbc1149faf0c68240985607c303" ]
…所以我們將忽略它。讓我們找到第二層:
# grep -l 41494b03ef195ce6db527bd68b89cbebdace66210b4c142e95f8553fcb0bf51e \ /var/lib/docker/image/overlay2/layerdb/sha256/*/diff /var/lib/docker/image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/diff
在與該
diff
文件相同的目錄中,我們將找到一個名為cache-id
:# cat image/overlay2/layerdb/sha256/14347a192896a59fdf5c1a9ffcac2f93025433c66136d3531d7bbb3aec53efc7/cache-id 118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75
標識
cache-id
層已被提取到的目錄;我們可以在下面找到它/var/lib/docker/overlay2/<id>
:# ls /var/lib/docker/overlay2/118b1e4a401873e1db8849c0821d0280b4cf9ef621ccb70cf14fe672dc74ef75 diff/ link lower work/
我們對
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
它就在那裡!
注意以上所有內容都假設您正在使用
overlay2
儲存驅動程序(這是當今大多數平台(如果不是所有平台)的預設設置)。如果您使用不同的驅動程序,磁碟上的佈局將有所不同。