老超市技术论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 最新
    • 标签
    • 热门
    • 用户
    • 群组

    反编译Docker镜像还原Dockerfile?源代码

    教程/The tutorial
    1
    1
    6
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • A
      admin 最后由 编辑

      现在对于一个开发来说,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。

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

      ➜ ~ docker login {仓库地址}
      Username: chenyuan
      Password:
      Login Succeeded
      然后,将镜像打包推送到私有仓库去

      docker commit -a "name" -m "小陈来拯救你" 706e502e8693 {镜像地址}:{tag}
      
      docker push {镜像地址}:{tag}
      
      docker pull {镜像地址}:{tag}
      

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

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

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

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

      方法3:解压镜像tar文件(推荐)
      此方法就是相当于反编译,拿到当时打镜像时候你做的详细操作。比较麻烦,但是是最靠谱的,最具有操作性的。

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

      docker save -o {name}.tar {镜像地址}:{tag}
      

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

      [
          {
              "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,这里再解压就是当时打镜像时候的一些资源文件。

      e12ac2aa-b495-4d23-aac6-64f338213b83-image.png

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

      1 条回复 最后回复 回复 引用 0
      • First post
        Last post
      ICP证: 辽ICP备16008076号-2 辽公网安备 21140302000151号