必看的dockerfile禁忌与建议!
脚本后续更新及迭代将由kkitDeploy项目代替 https://github.com/luckman666/kkitdeploy_server 请大家持续关注kkitDeploy
直接上对照组(看第三个run)
test1
1 FROM centos 2 MAINTAINER ** 3 4 RUN yum -y update 5 RUN yum -y install wget 6 7 RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.tar.gz" -O /tmp/jdk8_x64.tar.gz && gunzip /tmp/jdk8_x64.tar.gz && tar -C /opt -xf /tmp/jdk8_x64.tar && ln -s /opt/jdk1.8.0_121 /opt/jdk && yum clean all && rm -fr /tmp/*
test2
1 FROM centos 2 MAINTAINER ** 3 4 RUN yum -y update 5 RUN yum -y install wget 6 7 RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.tar.gz" -O /tmp/jdk8_x64.tar.gz && gunzip /tmp/jdk8_x64.tar.gz && tar -C /opt -xf /tmp/jdk8_x64.tar && ln -s /opt/jdk1.8.0_121 /opt/jdk 8 RUN yum clean all 9 RUN rm -fr /tmp/*
一样的命令我们分开不同来写会有什么区别呢?
1 alex@ubuntu:~/workspace/docker_project$ docker images 2 REPOSITORY TAG IMAGE ID CREATED SIZE 3 test2 latest a65c6cced43b 13 minutes ago 1.1 GB 4 test1 latest 67897397b053 14 minutes ago 729 MB
看到区别了么?
禁忌一(不分层或者瞎分层):
同一业务或功能操作分在一个层(一个run就是一个层哦!)!
禁忌二(切记画蛇添足):
绝对也千万别运行yum update,docker的目的就是用最小的资源运行程序。所以一律做减法,没用的不做,可用不可不用的不做,切记画蛇添足!
禁忌三(镜像好不好,就看小不小!):
别用docker commit制作镜像,这样的镜像都是没根的镜像,今天你知道咋回事。明天你可能就忘了,不好追溯其结构和顺序!而且这样的镜像通常都非常大!
禁忌四(容器的记忆比金鱼还短):
不要在docker中写入数据,如果有数据产生,必须存储在volume中
禁忌五(一个容器一个进程):
不多说了奥,容器不是虚拟机,一个容器干一个活就OK拉!
禁忌六(只安装,不删除):
用完的包要立即删除。
推荐及建议:
一、使用Alpine
Alpine是一个高度精简又包含了基本工具的轻量级Linux发行版,基础镜像只有4.41M,各开发语言和框架都有基于Alpine制作的基础镜像,所以推荐使用Alpine做基础镜像
看到他们差多少了吗?
二、使用scratch镜像构建其他镜像:
scratch是一个空镜像,只能用于构建其他镜像,比如你要运行一个包含所有依赖的二进制文件,如Golang程序,可以直接使用scratch作为基础镜像。还记得我们k8s里面的 pause镜像嘛?来看看它的Dockerfile:
FROM scratch ARG ARCH ADD bin/pause-${ARCH} /pause ENTRYPOINT ["/pause"]
pause镜像使用了scratch作为基础镜像,这个镜像本身是不占空间的,使用它构建的镜像大小几乎和二进制文件本身一样大,所以镜像非常小。当然在我们的Golang程序中也会使用。对于一些Golang/C程序,可能会依赖一些动态库,你可以使用自动提取动态库工具,比如ldd、linuxdeployqt等提取所有动态库,然后将二进制文件和依赖动态库一起打包到镜像中。
三、 busybox镜像(安卓核心哦!)
scratch是个空镜像,如果希望镜像里可以包含一些常用的Linux工具,busybox镜像是个不错选择,镜像本身只有1.16M,非常便于构建小镜像。
四、其他优化:
(1)在执行apt-get install -y 时增加选项— no-install-recommends ,可以不用安装建议性(非必须)的依赖,也可以在执行apk add 时添加选项--no-cache 达到同样效果;
(2)执行yum install -y 时候, 可以同时安装多个工具,比如yum install -y gcc gcc-c++ make …。将所有yum install 任务放在一条RUN命令上执行,从而减少镜像层的数量;
(3)组件的安装和清理要串联在一条指令里面,如 apk --update add php7 && rm -rf /var/cache/apk/* ,因为Dockerfile的每条指令都会产生一个文件层,如果将apk add … 和 rm -rf … 命令分开,清理无法减小apk命令产生的文件层的大小。 Ubuntu或Debian可以使用 rm -rf /var/lib/apt/lists/* 清理镜像中缓存文件;CentOS等系统使用yum clean all 命令清理。
欢迎关注我的个人公众号,有更多的学习资料等您来拿。