1.Docker镜像的优化原理
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络需求
尽量去用构建缓存
使用多阶段构建镜像
2.Docker镜像优化示例
以安装nginx为例,以rhel7为基础镜像
(1)未优化
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.15.8
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v1 . ##创建V1镜像
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v1 db655dcc5514 26 seconds ago 325MB ##未优化时大小为325M
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
(2)1次优化(清理中间缓存)
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v2 . ##创建v2镜像
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v2 f144b7e699da 39 seconds ago 269MB ##镜像大小减少56M
rhel7 v1 db655dcc5514 7 minutes ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
(3)2次优化,关闭nginx的debug模式
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.8.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v3 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 87c818b4ebed 42 seconds ago 256MB ##再次减少13M
rhel7 v2 f144b7e699da 8 minutes ago 269MB
rhel7 v1 db655dcc5514 15 minutes ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
(4)3次优化(采用多阶段构建镜像并删除解压后的包)
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
ADD nginx-1.15.8.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.15.8
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v4 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 7034b42bd75b 25 seconds ago 141MB ##再次减少115M
rhel7 v3 87c818b4ebed 9 minutes ago 256MB
rhel7 v2 f144b7e699da 16 minutes ago 269MB
rhel7 v1 db655dcc5514 23 minutes ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
(5)4次优化(减少底层base的大小)
底层镜像采用distroless
[root@server1 ~]# docker load -i distroless.tar
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 7034b42bd75b 5 minutes ago 141MB
<none> <none> 017783721314 5 minutes ago 254MB
rhel7 v3 87c818b4ebed 14 minutes ago 256MB
rhel7 v2 f144b7e699da 21 minutes ago 269MB
rhel7 v1 db655dcc5514 28 minutes ago 325MB
<none> <none> 7b24b4e0abc4 2 hours ago 308MB
busybox v1 2ed2629f2683 2 hours ago 1.15MB
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
gcr.io/distroless/base latest 9a255d5fe262 49 years ago 16.8MB
由此可知:distroless大小为16.8M而rhel7为140M比较大
利用distroless对nginx进行编译
实验前提:必须保证实验主机可以联到外网
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM nginx:1.16 as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG Asia/Shanghai
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base
COPY --from=base /opt /
EXPOSE 80
VOLUME ["/usr/share/nginx/html"]
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v5 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v5 28449b3da44c 51 seconds ago 23.7MB ##优化为最小只有23.7M
rhel7 v4 7034b42bd75b 25 minutes ago 141MB
rhel7 v3 87c818b4ebed 34 minutes ago 256MB
rhel7 v2 f144b7e699da 41 minutes ago 269MB
rhel7 v1 db655dcc5514 About an hour ago 325MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB