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

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

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

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

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

由于我们用的是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时的层数是一致的:

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

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

由镜像的分层结构存储我们可以知道,如果有一个文件在后续的构建中被删除,那如果我们能找到删除时上一层的diff文件,我们是能知道被删除的文件是怎样的。有这么一个题目:有一个docker 镜像 nginx-php 正在运行,容器中的 env.php 文件在构建镜像时被误删了,导致在容器中访问 localhost:80 报错。请想办法找回这个文件,将它放回到容器正确的位置。

找回方法

第一步:

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

由此我们知道env.php是在第四层被删除的,所以我们只需要找到第三层的文件即可恢复。

第二步:

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

[root@TENCENT64 /]# docker inspect nginx-php

"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/81d273995d89ed7da9f9a6b7b68683ebf7776ac7247e0f46c815f0f736dce011/diff:/var/lib/docker/overlay2/7dd42d9227abd33d8d926b04c572aba8ee4e3cd39479935637657c47caf1bdbf/diff:/var/lib/docker/overlay2/c7febf6a82208290a35760ce1c966bd3481a88e40d64005444ece29e47656809/diff:/var/lib/docker/overlay2/85876f4cb3f2fdbb9ac1ee0c3a4ff7d50789bc705db6522ece3221d88863642c/diff:/var/lib/docker/overlay2/e37b4d0d32bdcd47832c309ce9a05ad6924468bba00e227a2aef3400cd16b825/diff",
"MergedDir": "/var/lib/docker/overlay2/0d0ad887405cce471cc371bfd31711c110ea7ae48318f63ff638a68dd6659e0a/merged",
"UpperDir": "/var/lib/docker/overlay2/0d0ad887405cce471cc371bfd31711c110ea7ae48318f63ff638a68dd6659e0a/diff",
"WorkDir": "/var/lib/docker/overlay2/0d0ad887405cce471cc371bfd31711c110ea7ae48318f63ff638a68dd6659e0a/work"
}
},

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

/var/lib/docker/overlay2/0d0ad887405cce471cc371bfd31711c110ea7ae48318f63ff638a68dd6659e0a/diff 第六层

/var/lib/docker/overlay2/81d273995d89ed7da9f9a6b7b68683ebf7776ac7247e0f46c815f0f736dce011/diff  第五层

/var/lib/docker/overlay2/7dd42d9227abd33d8d926b04c572aba8ee4e3cd39479935637657c47caf1bdbf/diff 第四层

/var/lib/docker/overlay2/c7febf6a82208290a35760ce1c966bd3481a88e40d64005444ece29e47656809/diff 第三层 

/var/lib/docker/overlay2/85876f4cb3f2fdbb9ac1ee0c3a4ff7d50789bc705db6522ece3221d88863642c/diff 第二层

/var/lib/docker/overlay2/e37b4d0d32bdcd47832c309ce9a05ad6924468bba00e227a2aef3400cd16b825/diff 第一层

进入目录果真看到了被删除前的文件,将文件复制出来,并放在运行中的容器即可。

docker找回构建时被删除的文件的更多相关文章

  1. MSDeploy 同步时不删除原有文件

    在 jenkins里  Execute Windows batch command "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\m ...

  2. 找回从pycharm中删除的文件及文件夹

  3. Docker镜像构建文件Dockerfile及相关命令介绍

    使用docker build命令或使用Docker Hub的自动构建功能构建Docker镜像时,都需要一个Dockerfile文件.Dockerfile文件是一个由一系列构建指令组成的文本文件,doc ...

  4. rsync同步时,删除目标目录比源目录多余文件的方法(--delete)

    在日常运维工作中,我们经常用到rsync这个同步神器.有时在同步两个目录时,会要求删除目标目录中比源目录多出的文件,这种情况下,就可用到rsync的--delete参数来实现这个需求了. 实例说明:在 ...

  5. java实现创建临时文件然后在程序退出时自动删除文件(转)

    这篇文章主要介绍了java实现创建临时文件然后在程序退出时自动删除文件,从个人项目中提取出来的,小伙伴们可以直接拿走使用. 通过java的File类创建临时文件,然后在程序退出时自动删除临时文件.下面 ...

  6. docker 构建自己的image 镜像文件

    docker build 构建自己的镜像文件. 1.在本地工程中运行生成一个springboot的可运行的jar. 因为我习惯用eclipse,所以在eclipse下新建一个springboot的工程 ...

  7. Inno setup 卸载时删除程序文件夹(文件)

    Inno setup 卸载时删除程序文件夹(文件) //删除所有配置文件以达到干净卸载的目的 procedure CurUninstallStepChanged(CurUninstallStep: T ...

  8. Docker镜像构建的两种方式

    关于Docker里面的几个主要概念 这里用个不太恰当的比方来说明. 大家肯定安装过ghost系统,镜像就像是ghost文件,容器就像是ghost系统.你可以拿别人的ghost文件安装系统(使用镜像运行 ...

  9. Docker镜像构建

    一.简介 在构建容器化应用时,相当重要的步骤莫过于镜像制作,本文将介绍镜像制作方法以及镜像制作的建议.通常镜像的制作有两种方式: 使用现有的容器使用docker commit 生成镜像 使用Docke ...

随机推荐

  1. 足球动图gif(一)

  2. P1536 村村通(洛谷)并查集

    隔壁的dgdger带我看了看老师的LCA教程,我因为学习数学太累了(就是懒),去水了一下,感觉很简单的样子,于是我也来写(水)个博客吧. 题目描述 某市调查城镇交通状况,得到现有城镇道路统计表.表中列 ...

  3. 【API进阶之路】老板给我涨薪30%!如何通过SDK接口搞定千万级流量直播

    摘要:看我如何通过API Explorer 的SDK接口搞定千万级流量直播. 最近几个月,我的变化其实还蛮大的,从一个被实习生“无视”的“前浪”,转变成了不仅能够解决技术问题还能解决业务问题(顺手还能 ...

  4. vue : rem自适应的应用

    我们知道,rem是一个css单位,指的是HTML根节点的字体大小. MDN:css单位 而我们在用rem布局的时候必然会遇到一个问题:我们需要根据用户的屏幕大小去计算rem. 以下是代码. (在VUE ...

  5. PyQt5多线程和定时器

    多线程 一般情况单线程就可以很好的完成任务,但是对于GUI程序来说,单线程就不能完全满足需求.如果有耗时流程,在单线程的情况下,界面操作就会卡死,直到耗时操作完成,才会响应界面操作.为了解决这个问题, ...

  6. 【揭秘】阿里测试框架,各大CTO良心力荐

    自动化测试因其节约成本.提高效率.减少手动干预等优势已经日渐成为测试人员的“潮流”,从业人员日益清楚地明白实现自动化框架是软件自动化项目成功的关键因素之一.本篇文章将从 什么是真正的自动化测试框架.自 ...

  7. Flutter.. 两个点语法含义

    在Flutter编程中,会经常用到".."的语法糖,如下 state.clone() ..splashImg = action.img ..famousSentence = act ...

  8. APP自动化 -- contexts(上下文切换)

    一.上下文是什么? 1.解释 1)在混合型APP中包含了  原生页面 和 H5页面,如果需要进入APP内嵌的H5页面里面去操作就需要先切换进去,如果要继续回到原生页面操作就需要切回来. 2)这个就像是 ...

  9. spring学习(一)spring简介

    Spring简介: Spring 框架是 Java 应用最广的框架,它的成功来源于理念,而不是技术本身,它的理念包括 IoC (Inversion of Control,控制反转) 和 AOP(Asp ...

  10. 全卷积神经网络FCN详解(附带Tensorflow详解代码实现)

    一.导论 在图像语义分割领域,困扰了计算机科学家很多年的一个问题则是我们如何才能将我们感兴趣的对象和不感兴趣的对象分别分割开来呢?比如我们有一只小猫的图片,怎样才能够通过计算机自己对图像进行识别达到将 ...