• docker找回构建时被删除的文件


    设想这样一个场景:当一个docker镜像被多次引用构建,在某次构建中某个文件被删除,如何找回被删除的文件?

    要想回答这么一个问题,首先得熟悉下docker镜像的分层存储结构,镜像每一层都是只读的:

    1620

    那当我们执行docker pull imagename 时,拉下来的镜像每一层是存放在哪的呢?

    [root@zjmaster ~]# docker info
    Storage Driver: overlay2
    Docker Root Dir: /var/lib/docker
    从docker info输出我们知道,此机器上docker是以overlay2作为驱动,docker相关文件的存储目录为/var/lib/docker

    1596877797_28_w673_h360.png

    此目录还包含了镜像,容器,网络,存储卷等信息。

    由于我们用的是overlay2,所以我们的镜像存储的目录是: /var/lib/docker/overlay2,在这个目录下,我们将可以找到每个镜像层的文件,在每个子目录的diff目录中可以找到当前层相对于上一层的文件变化情况。

    如下通过一个我们熟悉的nginx镜像来解析说明:

    [root@zjmaster ~]# docker pull nginx

    [root@zjmaster ~]# docker inspect nginx

    ...

    "GraphDriver": {
    "Data": {
    "LowerDir": "/var/lib/docker/overlay2/15891b392a181e5f93d8af360a5dc7cf3a0bd929e619336797d8a3ffd5b50ef0/diff:/var/lib/docker/overlay2/a5e75f89dea7bcea271c61316339a5ce8cab0df65a39f040aa36bb2ec272adad/diff:/var/lib/docker/overlay2/1759d17a2cf99e000b0500c51d3d5873df35dd8442fc111b3b642be9b43705c4/diff:/var/lib/docker/overlay2/71983445e648623b51c22994ff62c571a75c8179fc60467eb2e789cf6eba7d79/diff",
    "MergedDir": "/var/lib/docker/overlay2/3ff91f7302cb140448b917ede7d91a7afec00871145353d3c176d1b1e16389b2/merged",
    "UpperDir": "/var/lib/docker/overlay2/3ff91f7302cb140448b917ede7d91a7afec00871145353d3c176d1b1e16389b2/diff",
    "WorkDir": "/var/lib/docker/overlay2/3ff91f7302cb140448b917ede7d91a7afec00871145353d3c176d1b1e16389b2/work"
    },
    "Name": "overlay2"
    },

    在GraphDriver.Data中有几个信息:

    LowerDir: Read-only image layers separated by colons from top most layer -> bottom most layer

    MergedDir: Merged view of all the layers

    UpperDir: Read-write layer where changes are written

    WorkDir: Used specifically by the underlying Linux OverlayFS

    镜像每一层的信息,在docker inspect image主要就关注LowerDir 和 UpperDir

    可以看到,上述的nginx镜像是由五个镜像层组成的(LowerDir中4个+UpperDir中1个)。与docker pull时的层数是一致的:

    1596877674_80_w981_h258.png

    同时,我们用docker history 命令可以看到镜像的历史构建信息。

    1596874123_49_w1242_h427.png

    在Dockerfile中,只有RUN COPY ADD命令会产生新层,其它命令只会创建临时中间镜像,不会增加镜像的大小,可以看到,这里也是有五个层,与上面的相对应。

    由镜像的分层结构存储我们可以知道,如果有一个文件在后续的构建中被删除,那如果我们能找到删除时上一层的diff文件,我们是能知道被删除的文件是怎样的。我们来构建一个这样的场景并演示如何恢复。

    第一步,拉取一个ubuntu:18.04基础镜像。

    [root@zjmaster /]# docker pull ubuntu:18.04
    18.04: Pulling from library/ubuntu
    7595c8c21622: Pull complete
    d13af8ca898f: Pull complete
    70799171ddba: Pull complete
    b6c12202c5ef: Pull complete
    Digest: sha256:a61728f6128fb4a7a20efaa7597607ed6e69973ee9b9123e3b4fd28b7bba100b
    Status: Downloaded newer image for ubuntu:18.04
    [root@zjmaster /]# docker history ubuntu:18.04
    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    2eb2d388e1a2        2 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
    <missing>           2 weeks ago         /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
    <missing>           2 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B
    <missing>           2 weeks ago         /bin/sh -c [ -z "$(apt-get indextargets)" ]     987kB
    <missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:7d9bbf45a5b2510d4…   63.2M

    第二步:制作Dockerfile,删除copy进去的screct.txt文件,并运行容器

    [root@zjmaster /data/docker]# cat Dockerfile
    FROM ubuntu:18.04
    
    COPY secret.txt /tmp/secret.txt
    RUN rm /tmp/secret.txt
    
    EXPOSE 80
    CMD ["/bin/bash"]
    [root@zjmaster
    /data/docker]# cat secret.txt Hello World! [root@zjmaster /data/docker]# docker build -t ubuntu:rmfile . Sending build context to Docker daemon 3.072kB Step 1/5 : FROM ubuntu:18.04 ---> 2eb2d388e1a2 Step 2/5 : COPY secret.txt /tmp/secret.txt ---> 2856d2f8f07f Step 3/5 : RUN rm /tmp/secret.txt ---> Running in de4ed8d2790b Removing intermediate container de4ed8d2790b ---> 313f23ffc4fc Step 4/5 : EXPOSE 80 ---> Running in fcc0ba3961f5 Removing intermediate container fcc0ba3961f5 ---> ede9fff02d30 Step 5/5 : CMD ["/bin/bash"] ---> Running in 01986f45d0c2 Removing intermediate container 01986f45d0c2 ---> 26ffd7e8f2ef Successfully built 26ffd7e8f2ef Successfully tagged ubuntu:rmfile [root@zjmaster /data/docker]# docker run -idt ubuntu:rmfile /bin/bash 49c74ce8afee493107daf1415bb01406978c109c2927cdd92d1881fd5dbe2f66 [root@zjmaster /data/docker]# [root@zjmaster /data/docker]# docker exec 49c74ce8afee493107daf1415bb01406978c109c2927cdd92d1881fd5dbe2f66 /bin/bash -c 'ls /tmp/secret.txt' ls: cannot access '/tmp/secret.txt': No such file or directory
    可以发现容器中的/tmp目前并没有secret.txt文件。接下来我们尝试找回这个文件。


    第三步:

    获取镜像历史构建信息,并标出层级:

    [root@zjmaster /data/docker]# docker history ubuntu:rmfile
    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    26ffd7e8f2ef        2 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
    ede9fff02d30        2 minutes ago       /bin/sh -c #(nop)  EXPOSE 80                    0B
    313f23ffc4fc        2 minutes ago       /bin/sh -c rm /tmp/secret.txt                   0B       第六层
    2856d2f8f07f        2 minutes ago       /bin/sh -c #(nop) COPY file:bd6fdd1577f2abf2…   13B      第五层
    2eb2d388e1a2        2 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
    <missing>           2 weeks ago         /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B       第四层
    <missing>           2 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B     第三层
    <missing>           2 weeks ago         /bin/sh -c [ -z "$(apt-get indextargets)" ]     987kB    第二层
    <missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:7d9bbf45a5b2510d4…   63.2MB   第一层

    由此我们知道secret.txt是在第六层被删除的,所以我们只需要找到第五层的文件即可恢复。

    第四步:

    用docker inspect 获取第五层的diff路径:

    [root@zjmaster /data/docker]# docker inspect ubuntu:rmfile
    
    "GraphDriver": {
    
    "Data": {
    "LowerDir": "/var/lib/docker/overlay2/a51164d454343a309fec1fc9e34511ccb15c42107ecfddd75b5e3f3536c0ab9f/diff:/var/lib/docker/overlay2/0aa0f1c5a06d463c495c61e9d15fe6ad87b80c34b80450651f0e43f4ef0b1629/diff:/var/lib/docker/overlay2/86ed072ad089a17e0b14f0658d85c91eab9ff1e6cdca36f54e24d066ab8db019/diff:/var/lib/docker/overlay2/b03c3e40173d1fa67806c674d7ace749b1a1fba65939b9f841df44ada1c428eb/diff:/var/lib/docker/overlay2/3b1ae2f59bdc2fe8260f04d9e4b7ba61eff75bff190673c4c8e856a86e998b7e/diff",
    "MergedDir": "/var/lib/docker/overlay2/37dc44c3887436e3fd446a0b8b137d7093a357ee42f6c83f03622c6d446757f4/merged",
    "UpperDir": "/var/lib/docker/overlay2/37dc44c3887436e3fd446a0b8b137d7093a357ee42f6c83f03622c6d446757f4/diff",
    "WorkDir": "/var/lib/docker/overlay2/37dc44c3887436e3fd446a0b8b137d7093a357ee42f6c83f03622c6d446757f4/work"
    },
    "Name": "overlay2"
    },

    UpperDir 为最上层,在此为第六层,其它从LowerDir一层层往下数。

    /var/lib/docker/overlay2/37dc44c3887436e3fd446a0b8b137d7093a357ee42f6c83f03622c6d446757f4/diff 第六层
    /var/lib/docker/overlay2/a51164d454343a309fec1fc9e34511ccb15c42107ecfddd75b5e3f3536c0ab9f/diff 第五层
    /var/lib/docker/overlay2/0aa0f1c5a06d463c495c61e9d15fe6ad87b80c34b80450651f0e43f4ef0b1629/diff 第四层
    /var/lib/docker/overlay2/86ed072ad089a17e0b14f0658d85c91eab9ff1e6cdca36f54e24d066ab8db019/diff 第三层
    /var/lib/docker/overlay2/b03c3e40173d1fa67806c674d7ace749b1a1fba65939b9f841df44ada1c428eb/diff 第二层
    /var/lib/docker/overlay2/3b1ae2f59bdc2fe8260f04d9e4b7ba61eff75bff190673c4c8e856a86e998b7e/diff 第一层

    进入第五层目录果真看到了被删除前的文件。

    [root@zjmaster /]# tree /var/lib/docker/overlay2/a51164d454343a309fec1fc9e34511ccb15c42107ecfddd75b5e3f3536c0ab9f/diff
    /var/lib/docker/overlay2/a51164d454343a309fec1fc9e34511ccb15c42107ecfddd75b5e3f3536c0ab9f/diff
    `-- tmp
        `-- secret.txt
    
    1 directory, 1 file
    [root@zjmaster /]# cat /var/lib/docker/overlay2/a51164d454343a309fec1fc9e34511ccb15c42107ecfddd75b5e3f3536c0ab9f/diff/tmp/secret.txt
    Hello World!
  • 相关阅读:
    学习进度——第五周
    构建之法阅读笔记02
    学习进度——第四周
    整型数组——首尾相连
    构建之法阅读笔记01
    二维数组
    学习进度——第三周
    新最大子数组——数量级和数量无限大
    最大子数组求和
    P3388 【模板】割点(割顶)题解 tarjan求割点
  • 原文地址:https://www.cnblogs.com/zejin2008/p/13460498.html
Copyright © 2020-2023  润新知