前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何反编译一个Docker镜像还原Dockerfile?

如何反编译一个Docker镜像还原Dockerfile?

作者头像
chengcheng222e
发布2021-11-12 17:31:46
4.5K0
发布2021-11-12 17:31:46
举报
文章被收录于专栏:简栈文化简栈文化
前言

现在对于一个开发来说,Docker应该是再熟悉不过了。还记得在2013~2014左右的时候,听说多最多的就是Cloud Foundry,那个时候就一直在说云的事情。后面Docker就绝杀了它~

那它帮我们解决了一个什么问题了?面试的时候也许会问到。

在很久以前,我们开发代码,估计最蛋疼的事情就是发布版本了。我还记得在房多多的时候(2014~2016)左右,每次发布几个开发围绕在运维的身边,有时候运维忙不过来,开发就直接在运维的电脑上开始VIM干活了,修改若干配置。由于多环境的原因,我们无法保证每个环境都是一样的。

  • 可能你的操作系统不同,导致打包、发布的脚本不同
  • 环境不同,没有很好的配置管理,你的代码有不同的写法
  • 特别是跟操作系统相关的那些参数,可能瞬间就会带来性能问题

那么Docker就可以把我们的操作系统、代码、脚本等都一起打包成一个Image,就可以保证只要是运行同一个Image,我们的所有内容都是一样的。就不会出现,我在测试环境跑的好好的,一到生产连启动都成问题。

问题

现在一般一个POD就只跑一个进程,DevOps会根据我们的发布流水线自动的将一个项目进行打包、发布,整套的CI、CD做的是行云流水。但是,每个项目ROOT下都会需要一个叫Dockerfile的文件。但偏偏有一些历史项目,没有Dockerfile文件,只有一个Run的容器再跑,真的是非常惊悚。docker rm [OPTIONS] CONTAINER [CONTAINER...],就GAME OVER了。

怎么办?
方法1:以当前容器作为基础镜像

真的,什么也不想。先保个底,把你当前的容器打包成一个镜像推送到仓库里去,哪天有意外或者说需要基于它做一些事情的时候才有可能。比如:你要本地也部署一份代码来debug

一般都是私有的仓库,会需要输入用户名与密码

代码语言:javascript
复制
➜  ~ docker login {仓库地址}
Username: chenyuan
Password:
Login Succeeded

然后,将镜像打包推送到私有仓库去

代码语言:javascript
复制
docker commit -a "name" -m "小陈来拯救你" 706e502e8693 {镜像地址}:{tag}

docker push {镜像地址}:{tag}

docker pull {镜像地址}:{tag}

但是这样子的问题在于,我们无法知道环境依赖了哪些模块,如果需要重新再部署一套,我为了保证环境的干净又需要删除哪些东西。就是无法知道增加与减少哪些东西,也就会导致环境存在不一致性,失去了我们的初衷。

方法2:从运行的容器中复制

先把镜像跑起来,然后从运行起来的容器中复制文件出来,复制命令如下:

代码语言:javascript
复制
# 从容器复制文件或目录到宿主机器
docker cp 6619ff360cce:/opt/h2-data/pkslow ./
docker cp 6619ff360cce:/opt/h2-data/pkslow/pkslow.txt ./

第一种方法并不是万能的,因为有些镜像过于简单,少了许多基础命令,以至于无法复制文件,也无法进入shell环境。其次,要运行起来再操作,也有点占用资源,比较麻烦。

方法3:解压镜像tar文件(推荐)

此方法就是相当于反编译,拿到当时打镜像时候你做的详细操作。比较麻烦,但是是最靠谱的,最具有操作性的。

先将镜像保存为tar文件,命令如下:

代码语言:javascript
复制
docker save -o {name}.tar {镜像地址}:{tag}

下载后就会有一个tar包在本地,然后就解压出来。可以看一下manifest.json文件的内容

代码语言:javascript
复制
[
    {
        "Config": "dca33100e3683d6fb4d56a4c142ccccc1c113f061454a64bc07c852fe068ea1d.json",
        "RepoTags":
        [
            "{镜像地址}:{tag}"
        ],
        "Layers":
        [
            "216168069a5195a9424b3a73a62bda39e4d5f8dcae2f7149a336c2e29beeb06b/layer.tar",
            "4b0e1f4bede4cef5dee11aff78ff89f543dc62eb02306db1b96d896b101e069d/layer.tar",
            "3fe7f20416fdd4958cc18b6fb0d28881147246c32677d102a431c31bf12288f7/layer.tar",
            "84c1758c9c15f83d8aa4e1ad13c2918aea80f802f01d19eeb2f7c6e1897d7160/layer.tar",
            "31bf0d828ecc19f178d8337e1c22a030984e9185e805b48ea911bd866730af2f/layer.tar",
            "7b30e9a6f195343744ca82c66d31b61771e8d6502a271ad60deb1fa1103e83ca/layer.tar",
            "522ee848bbd06c6e4dad8d5200b83c9197ccce717fb09687b435190d287f6829/layer.tar",
            "a64965663d7c30ed09d35f05439dcfb6247f030df0d72a0e78f54fb6ae5a8c74/layer.tar",
            "a93f0f89669c097497a3e3de7aeffebeba2838f180e4f13844be55fe124885ae/layer.tar",
            "fd69896888f7361654ed0e27ed2634311b6707dd20706487e33e24f32bb23ebe/layer.tar",
            "69c55c418aba5b8fb5239b4e8b092e02100f4ec49dae8ded9cc0a161b21884d7/layer.tar",
            "5ef51ffa437403d5d33a40208c3781ea84a93f53947e5d7fad086092667bd3b1/layer.tar"
        ]
    }
]

图片是解压后的效果,里面都会存在一个layer.tar,这里再解压就是当时打镜像时候的一些资源文件。

http://static.cyblogs.com/image-20210928200049751.png

http://static.cyblogs.com/image-20210928200334841.png

红色的部分就是我们想要的内容。再辛苦一点,把自己想要的东西整理出来。描述的比较轻描淡写,任何事情只要手动去做一遍,就会理解与记住。

参考地址
  • https://segmentfault.com/a/1190000040213872?sort=newest

如果大家喜欢我的文章,可以关注个人订阅号。欢迎随时留言、交流。如果想加入微信群的话一起讨论的话,请加管

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 简栈文化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 问题
  • 怎么办?
    • 方法1:以当前容器作为基础镜像
      • 方法2:从运行的容器中复制
        • 方法3:解压镜像tar文件(推荐)
        • 参考地址
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档