Docker镜像的优化

我们在使用docker镜像的时候会发现一些镜像运行的话会非常的大,占用系统资源,那么我们其实是可以通过优化来解决这样的问题的

镜像的优化准则:

  1. 选择最精简的基础镜像
  2. 减少镜像的层数
  3. 清理镜像构建的中间产物
  4. 注意优化网络请求
  5. 尽量去用构建缓存
  6. 使用多阶段构建镜像

那么接下来我们以为rhel7镜像nginx的源码安装为例来做优化
1.首先获得一个nginx的源码包

[root@server1 docker]# ls
Dockerfile  nginx-1.15.8.tar.gz  web  yum.repo	
[root@server1 docker]# 

2.编写Dockerfile文件

[root@server1 docker]# cat Dockerfile 
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install 
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

3.构建镜像
在这里插入图片描述
在这里插入图片描述
[root@server1 docker]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 af236e3138f9 About a minute ago 276MB
nginx latest 53f3fd8007f7 3 weeks ago 109MB
我们可以很容易的看到我构建的镜像的大小有276MB,比官方的nginx大了很多,那么我们就要开始对其进行优化
在优化前我们先尝试一下我们的nginx是否成功了

[root@server1 docker]# docker run -d --name nginx nginx:v1
b098b2a4bf0f3478e7156663a6e97d19424331e094ce06922b26a902de53bc34

在这里插入图片描述
在这里插入图片描述
上面的目录为nginx容器默认发布界面的在物理机目录
4.开始优化;
第一次优化:将不想看到的输出都导入到垃圾箱

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel && yum clean all
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/local/nginx
RUN make &> /dev/null
RUN make install &> /dev/null
RUN rm -fr /mnt/nginx-1.15.8
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] 

在这里插入图片描述
在这里插入图片描述
然后我们再比较,发现大小有变化。
第二次优化:把run全部放在一行,这样减少层数,但是效果不是很好,减少的比较少,这里就不做具体说明了
第三次优化:使用多阶段构建

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM rhel7 as build
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel && 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 -rf /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;"]

其实这样就类似与我们在一台主机上安装了nginx,但是我们只需要将这台主机上的nginx拷贝到另一台主机上,这样,第二台主机就只有nginx,而没有了之前的那么多东西

重构镜像

[root@server1 docker]# docker build -t nginx:v3 .

在这里插入图片描述
在这里插入图片描述
我们可以发现以下减少了快一半
我们来测试一下是否可用

[root@server1 docker]# docker run -d --name nginx -p 80:80 nginx:v3
595ab7b2d3db839ba43f595030df0e7f5373ef5c7c478dbe3e3333b5becfa57c

在这里插入图片描述
我们看到是完全可用的
第四次优化:使用最精简的镜像
因为nginx服务,不是用到了所有的数据。所以我们选择使用最精简的镜像来重构镜像

[root@server1 ~]# docker load -i distroless.tar 
668afdbd4462: Loading layer  18.39MB/18.39MB
Loaded image: gcr.io/distroless/base:latest
[root@server1 ~]# docker images gcr.io/distroless/base
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE	
gcr.io/distroless/base   latest              9a255d5fe262        49 years ago        16.8MB

我们可以看到这个镜像同rhel7的大小小了太多,但是镜像小,也就代表了需要我们的操作就会更多,因为很多东西还没有构建,关于distroless镜像的使用大家可以自己百度,这里就不做过多说明了

我们来重新编写Dockerfile

[root@server1 ~]# cd /tmp/docker/
[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# cat Dockerfile 
FROM nginx 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

ENTRYPOINT ["nginx", "-g", "daemon off;"]

其实这就像我们在一张白纸上书写了我们所需要的东西。
重构镜像

[root@server1 docker]# docker rm -f nginx 
nginx
[root@server1 docker]# docker build -t nginx:v4 .

在这里插入图片描述
在这里插入图片描述
我们可以发现其仅仅只有20多MB
测试nginx是否正常

[root@server1 docker]# docker run -d --name nginx -p 80:80 nginx:v4
ce0702ce569c8c5bfe4199dfae880a865f1bb8f146f8bbc70962c5a8b2443748

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42446031/article/details/90812209