本文主要是介绍掰开别人的Docker镜像-提取别人的历史build命令,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近研究了一下如何掰开别人构建好的docker镜像,扒拉出原来的构建命令。
很多前辈都说是没法查到的,但是经过梳理发现还是有一点方法可以扒拉出来的。下面以coolq的镜像为例记录一下蒸锅过程备忘。
为了方便,我是在群晖里安装docker测试的。下载的coolq版本是:v3.0.1的后一个版本,也就是这篇文章写的时候的最新版本latest
先拉取coolq镜像:
docker pull coolq/wine-coolq:latest
然后通过以下命令查看该镜像的构建history(该命令输出相关参数的解释参照文章:https://www.cnblogs.com/cooper-73/p/9830371.html):
docker history coolq/wine-coolq:latest --format "table {{.ID}}\t{{.CreatedBy}}\t{{.Size}}" --no-trunc
将输出复制到你喜欢的文本编辑器里,比如UE。很整齐的样子对吧,我们主要要的就是CREATED BY这列内容。
从下往上看。
第一行就是:/bin/sh -c #(nop) ADD file:91a750fb184711fde03c9172f41e8a907ccbb1bfb904c2c3f4ef595fcddbc3a9 in /
看起来他往镜像里添加了一个文件,可是是什么不知道,文件名已经被docker build的时候加密了。
好吧,我们就搜索一下这个:91a750fb184711fde03c9172f41e8a907ccbb1bfb904c2c3f4ef595fcddbc3a9
竟然有收获:https://microbadger.com/images/x11vnc/desktop
这里有个x11vnc/desktop的镜像里也包含了这个构建,看第一部分,竟然是ubuntu的镜像,版本号:bionic-20200219。
红框里的内容是不是跟咱们history的最后五行几乎一毛一样滴?!
这说明最后五行就是ubuntu镜像构建时候的命令,我们就不管了。
从倒数第六行开始,我们写一个Dockerfile,试试能否构建出一个coolq镜像就行了。好戏开始了。咱们继续,骚年~
用putty连接群晖。
登录后 sudo -i,输入密码,切换到超级root。
mkdir coolq
cd coolq
touch Dockerfile
vi Dockerfile
先写下初始的几行:
#coolWeChat
FROM ubuntu:bionic-20200219
MAINTAINER robin lee bingor.lee@outlook.com
接下来,看看倒数第六行的CREATED BY是什么内容:
/bin/sh -c #(nop) ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 S6_BEHAVIOUR_IF_STAGE2_FAILS=2 S6_CMD_ARG0=/sbin/entrypoint.sh VNC_GEOMETRY=800x600 VNC_PASSWD=MAX8char USER_PASSWD= DEBIAN_FRONTEND=noninteractive
经过仔细观察 除了 RUN 命令外都会包含:/bin/sh -c #(nop)
这行其实就是:ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 S6_BEHAVIOUR_IF_STAGE2_FAILS=2 S6_CMD_ARG0=/sbin/entrypoint.sh VNC_GEOMETRY=800x600 VNC_PASSWD=MAX8char USER_PASSWD= DEBIAN_FRONTEND=noninteractive
我们把他写入我们的Dockerfile
然后再继续上面一行整理一下:
RUN groupadd user && useradd -m -g user user && apt-get update && apt-get upgrade -y && apt-get install -y git ca-certificates wget locales nginx sudo xorg openbox python-numpy rxvt-unicode && wget -O - https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz | tar -xzv && ln -s /init /init.entrypoint && wget -O /tmp/tigervnc.tar.gz https://bintray.com/tigervnc/stable/download_file?file_path=tigervnc-1.10.1.x86_64.tar.gz && tar xzf /tmp/tigervnc.tar.gz -C /tmp && chown root:root -R /tmp/tigervnc-1.10.1.x86_64 && tar c -C /tmp/tigervnc-1.10.1.x86_64 usr | tar x -C / && locale-gen en_US.UTF-8 && mkdir -p /app/src && git clone --depth=1 https://github.com/novnc/noVNC.git /app/src/novnc && git clone --depth=1 https://github.com/novnc/websockify.git /app/src/websockify && apt-get purge -y git wget && apt-get autoremove -y && apt-get clean && rm -fr /tmp/* /app/src/novnc/.git /app/src/websockify/.git /var/lib/apt/lists
再上一行又懵逼了:
/bin/sh -c #(nop) COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /
好啦,表芳!
看起来是 COPY了一个目录到镜像里,像那么回事。
我们把拉取的coolq RUN起来,再拉取一个ubuntu:bonic:20200219跑起来。进去看看。
docker pull ubuntu:bionic-20200219
对比一下两个镜像里有什么不一样。
是不是,看不出来~哈哈,我也是,有点复杂拉~~~难道没办法了?古人告诉过我们“抛转引玉”,我们现在就抛一块砖,看能否引出玉来吧。方法如下:
我们在Dockerfile里写入:
#COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /
意思是这个命令是啥不知道,先注释在这里。然后我们继续把上几行的命令写完。
EXPOSE 5901/tcp 9000/tcp 9001/tcp
ENTRYPOINT ["/init.entrypoint"]
CMD ["start"]
然后build一下镜像。
docker build -t coolqtest1:v1 .
是不是开始 跑码,跑码,跑马溜溜的山上,一朵溜溜的BUG 。。。。。
啰嗦半天跑完了,说成功生成一个镜像,好了,我们run下这个镜像,用群晖就比较容易,点启动。一切默认。跑起来!
丢(第二声)~~~,容器启动又停止了~~去容器日志看看,是不是报错了,哈哈~这就是我们抛出来的砖,仔细看说有个文件没找到。/sbin/entrypoint.sh
好办,我们从coolq镜像里把他拉出来。
mkdir copyfiles2
mkdir copyfiles2/sbin
docker cp 46a5fb88f6c4:/sbin/entrypoint.sh ./copyfiles2/sbin/
注:46a5fb88f6c4是coolq起的容器的ID,可以通过docker ps查看到。
我们vi ./copyfiles2/sbin/entrypoint.sh,内容整理了一下,他要用到的脚本如下:
/bin/s6-svc -wu -T 5000 -u /var/run/s6/services/tigervnc
/bin/s6-svc -wu -T 5000 -u /var/run/s6/services/websocketify
/bin/s6-svc -wu -T 5000 -u /var/run/s6/services/nginx
sudo --preserve-env -Hu user /app/vncmain.sh "$@"
这里说明一下:/bin/s6-svc这个在之前的构建里安装了s6,然后用s6来管理服务,回收僵尸进程,s6启动时,会把 /etc/services.d/下的服务都复制到 /var/run/s6/services下启动并监控,避免过多垃圾进程导致你的容器奔溃掉(如果想了解下s6可以看这里:https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/78929491),之前不太懂,想要改下/var/run/s6/services/tigervnc/run脚本,怎么改都不行,后来才知道要去/etc/services.d/下去改,哎,我踩坑,你受益啊~
好,既然知道这个脚本启动的服务都是从/etc/services.d/下复制的,那我们去我们构建的镜像起的容器里去看看,是不是没有这些服务?愣着干嘛,拉出来啊~
mkdir copyfiles2/etc
mkdir copyfiles2/etc/services.d
docker cp 0d1502a2afa0:/etc/services.d ./copyfiles2/etc/
mkdir copyfiles2/app
docker cp 0d1502a2afa0:/app/vncmain.sh ./copyfiles2/app
注:这里有个知识点(坑),46a5fb88f6c4:/etc/services.d 如果最后没有/就是把这个services.d目录名复制到后面的etc下,如果有/就是复制下面的所有文件还有文件夹(参考:https://www.it1352.com/647399.html)
坑2:如果报"docker cp" requires exactly 2 arguments.那就看看 后面的路径参数之间是不是不是半角的空格,删除空格再加一个!
好了,文件有了,我们继续完善我们的Dockerfile
在#COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /下添加
WORKDIR ./
COPY copyfiles2 /
注:知识点这个COPY copyfiles2 /如果直接写,build到时候,你会收到报错COPY failed: stat /volume1/@docker/tmp/docker-builder239052814/copyfile2: no such file or directory
WORKDIR ./是告诉docker build运行下一条命令的工作目录是当前目录,不然他就会懵逼说找不到,找不到你妹啊~不愧是Do坑儿啊~丢~~~你懂的二声。
好了,是不是迫不及待的想要了~~~~打住~想要build一下了。
docker build -t coolqtest1:v4 .
我们build一个tag为v4的新版本吧,上面我们每次build都会用不通的tag。好看到有啥不同,搞完了,到时候记得docker rmi删除掉多余的镜像哈。
等我啰嗦完,他也Biu~完了,我们RUN一下。
是不是还是容器退出了?!表芳~~~看看日志~是不是说启动80端口时端口被占用了?说明原作者还修改nginx.conf的配置文件。
把他也撸出来~
mkdir copyfiles2/etc/nginx
docker cp 0d1502a2afa0:/etc/nginx/nginx.conf ./copyfiles2/etc/nginx/
继续Biu~~~Run,哈哈,是不是容器不会退出了,浏览器访问:http://ip:9000是不是可以看到noVNC的界面了?!
别鸡动~~进不去的~~~
好吧,继续长征~
继续往上看build的history是不是又有一个:
COPY dir:4f1dc1b5cc5c6e51966462d288d9524e613a6a4f26b780d54fc81d2b0fd731ed in /
是不是心里芳的一批~~~
老办法给她备注到 Dockerfile里去:
#COPY dir:4f1dc1b5cc5c6e51966462d288d9524e613a6a4f26b780d54fc81d2b0fd731ed in /
然后继续:
RUN chown root:root /tmp && chmod 1777 /tmp && apt-get update && apt-get install -y wget software-properties-common apt-transport-https && wget -O- -nc https://dl.winehq.org/wine-builds/winehq.key | apt-key add - && apt-add-repository -y https://dl.winehq.org/wine-builds/ubuntu && add-apt-repository -y ppa:cybermax-dexter/sdl2-backport && dpkg --add-architecture i386 && apt-get update && apt-get install -y cabextract unzip python-numpy language-pack-zh-hans tzdata fontconfig && apt-get install -y --no-install-recommends fcitx fcitx-ui-classic fcitx-pinyin && apt-get install -y --allow-unauthenticated --install-recommends winehq-devel && wget -O /usr/local/bin/winetricks https://github.com/Winetricks/winetricks/raw/master/src/winetricks && chmod 755 /usr/local/bin/winetricks && wget -O /tmp/gecko.tar.gz http://dl.winehq.org/wine/wine-gecko/2.47.1/wine-gecko-2.47.1-x86.tar.bz2 && mkdir -p /usr/share/wine/gecko && tar xf /tmp/gecko.tar.gz -C /usr/share/wine/gecko && apt-get purge -y software-properties-common apt-transport-https && apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists
RUN chsh -s /bin/bash user && su user -c 'WINEARCH=win32 /usr/bin/wine wineboot' && su user -c '/usr/bin/wine regedit.exe /s /tmp/coolq.reg' && su user -c 'wineboot' && echo 'quiet=on' > /etc/wgetrc && su user -c '/usr/local/bin/winetricks -q win7' && su user -c '/usr/local/bin/winetricks -q /tmp/winhttp_2ksp4.verb' && su user -c '/usr/local/bin/winetricks -q msscript' && su user -c '/usr/local/bin/winetricks -q fontsmooth=rgb' && wget https://dlsec.cqp.me/docker-simsun -O /tmp/simsun.zip && mkdir -p /home/user/.wine/drive_c/windows/Fonts && unzip /tmp/simsun.zip -d /home/user/.wine/drive_c/windows/Fonts && mkdir -p /home/user/.fonts/ && ln -s /home/user/.wine/drive_c/windows/Fonts/simsun.ttc /home/user/.fonts/ && chown -R user:user /home/user && su user -c 'fc-cache -v' && mkdir /home/user/coolq && rm -rf /home/user/.cache/winetricks /tmp/* /etc/wgetrc
ENV LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 TZ=Asia/Shanghai COOLQ_URL=http://dlsec.cqp.me/cqa-tuling
VOLUME [/home/user/coolq]
保存(vi的话按esc 输入:wq回车)后,Biu~~~RUN.....
版本号v5: docker build -t coolqtest1:v5 .
v5???到这里是不是觉得曙光就在眼前,自己也有点威武了,别飘~~嘿嘿。
这里镜像增加了1.2GB,好大啊,雅蠛蝶~~
下载也要好久~~
等呗~
构建有两个文件找不到,这个就牵扯的coolq的了,通过搜索,发现这里有:
https://github.com/kotonemoe/docker-wine-coolq-dotnet45
wget https://github.com/kotonemoe/docker-wine-coolq-dotnet45/raw/master/winhttp_2ksp4.verb
wget https://raw.githubusercontent.com/kotonemoe/docker-wine-coolq-dotnet45/master/coolq.reg
mkdir copyfiles2/tmp
mv winhttp_2ksp4.verb copyfiles2/tmp/
mv coolq.reg copyfiles2/tmp/
如果下不了,你就需要梯子。
继续构建,试试看。
现在报访问/tmp没有权限
这篇关于掰开别人的Docker镜像-提取别人的历史build命令的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!