docker之nginx镜像优化4

本文介绍了如何通过减少镜像层数、清理中间产物以及使用多阶段构建来优化Docker中的Nginx镜像。通过合并RUN指令、删除不必要的文件以及利用distroless基础镜像,成功将镜像大小从346MB减至31.7MB。此外,还展示了如何处理依赖库文件,确保镜像精简的同时保持功能完整。
摘要由CSDN通过智能技术生成

系列文章目录

docker之nginx镜像优化4


一、镜像优化的意义及方法

镜像的优化可以减少客户端下载时候的带宽
在这里插入图片描述
已经选择了精简的镜像,所以减少镜像的层数,可以把之前的RUN合并在一起。将WORKDIR切换成在RUN底下的cd
之前的Dockerfile:

FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel 
ADD nginx-1.18.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.18.0
RUN ./configure --prefix=/usr/local/nginx
RUN yum install make -y
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

减少镜像层数后:

[root@docker1 docker]# cat Dockerfile 
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/dvd.repo
ADD nginx-1.18.0.tar.gz /mnt
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel && cd /mnt/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx && yum install make -y && make && make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

清理中间产物:/var/cache/yum yum的缓存路径,nginx安装包删掉,编译完了make gcc都可以删掉(安装make这些包时候会安装依赖性,但是删掉时候不删掉依赖性)

[root@docker1 docker]# cat Dockerfile 
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/dvd.repo
ADD nginx-1.18.0.tar.gz /mnt
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && cd /mnt/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx && make && make install  && rm -fr /mnt/nginx-1.18.0 /var/cache/yum 
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@docker1 docker]# docker build -t webserver:v2 .

优化后镜像大小差距:

[root@docker1 docker]# docker images webserver
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
webserver           v2                  503439033877        24 seconds ago      258MB
webserver           v1                  bdd2829a42e3        36 minutes ago      346MB
[root@docker1 docker]# docker images rhel7
rhel7               latest              0a3eb3fde7fd        7 years ago         140MB

优化了:346-258,除去基础base镜像140,还是多了

可以看出多的主要在Yum里面111MB,该层主要安装包编译等

[root@docker1 docker]# docker history webserver:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
503439033877        6 minutes ago       /bin/sh -c #(nop)  CMD ["/usr/local/nginx/sb…   0B                  
c140026256fd        6 minutes ago       /bin/sh -c rpmdb --rebuilddb && yum install …   111MB               
8b163bc5912e        7 minutes ago       /bin/sh -c #(nop) ADD file:a90dc1ecadbd423a5…   6.25MB              
b17ef4913f9c        48 minutes ago      /bin/sh -c #(nop) COPY file:fe5cdcb63a06bd4c…   67B                 
82ca7e5c38e6        49 minutes ago      /bin/sh -c #(nop)  VOLUME [/usr/local/nginx/…   0B                  
8aa3b0c110c7        49 minutes ago      /bin/sh -c #(nop)  EXPOSE 80                    0B                  
0a3eb3fde7fd        7 years ago                                                         140MB               Imported from -

可以看出v1没有优化的时候,光yum代码。

[root@docker1 docker]# docker history webserver:v1
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
bdd2829a42e3        44 minutes ago      /bin/sh -c #(nop)  CMD ["/usr/local/nginx/sb…   0B                           
9e03306cbffd        44 minutes ago      /bin/sh -c yum install make -y                  43.6MB                         
bf1e3007a03b        49 minutes ago      /bin/sh -c yum install -y gcc pcre-devel zli…   133MB               

源码编译后,真正只需要编译后的二进制代码
所以,我真正只需要/usr/local/nginx的二进制代码只有5M,其余的(中间产物)不需要,再把debug一关不到1M
可以只把操作系统编译好的源码(二进制代码)给其它操作系统直接使用


二、使用多阶段构建

分两个部分,先在一个容器编译好二进制代码再拷贝给第二个容器使用
将debug注释掉

[root@docker1 nginx-1.18.0]# vim auto/cc/gcc 

在这里插入图片描述

[root@docker1 nginx-1.18.0]# sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc 

在这里插入图片描述
全部替换完成
将该指令添加到Dockerfile中,并且多阶段构建(将上一个容器编译后的nginx的二进制编码拿来使用)
as build是给上面起名build
COPY --from=build /usr/local/nginx /usr/local/nginx 将上一个容器的二进制编码目录(/usr/local/nginx)放在下一个容器的/usr/local/nginx
暴露端口和卷都不是必须的所以删掉了,编一个最精简的Dockerfile

[root@docker1 docker]# cat Dockerfile 
FROM rhel7 as build
COPY dvd.repo /etc/yum.repos.d/dvd.repo
ADD nginx-1.18.0.tar.gz /mnt
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && cd /mnt/nginx-1.18.0 && 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.18.0 /var/cache/yum 

FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

[root@docker1 docker]# docker build -t webserver:v3 .

除去140MB的基础镜像base,一个nginx 1MB

[root@docker1 docker]# docker images webserver
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
webserver           v3                  5cd6dd1fdc7f        31 seconds ago      141MB
webserver           v2                  503439033877        35 minutes ago      258MB
webserver           v1                  bdd2829a42e3        About an hour ago   346MB

docker 能运行肯定nginx没问题,有问题CMD都报错了

[root@docker1 docker]# docker run -d --name nginx webserver:v3
[root@docker1 docker]# docker container inspect nginx | grep "IPAddress"
            "IPAddress": "172.17.0.2",
[root@docker1 docker]# curl 172.17.0.2
<h1>Welcome to nginx!</h1>

再优化都不可能比base镜像小
所以,在优化需要寻找更加精简的base,通过https://hub.docker.com/寻找或www.github.com或www.gitee.com上面寻找

nginx在运行时候,会调用系统的动态库文件
库文件必不缺的,缺了二进制文件就起不来了。
所以在拷贝二进制文件目录的时候把库文件也要考入,同时编译的nginx不同调用的库文件也不同,加了opensll还有lib-opensll库,所以如果换取更小的镜像的话,需要把库文件和二进制文件同时迁移。同时还要考虑这些库文件有无依赖性还要调用其他的库文件。

[root@docker1 docker]# docker run -it --rm webserver:v3 bash
bash-4.2# ldd /usr/local/nginx/sbin/nginx 
	linux-vdso.so.1 =>  (0x00007ffc06f6d000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f3560c8a000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3560a6e000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f3560837000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f35605d6000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f35603c0000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f355ffff000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f3560e8e000)
	libfreebl3.so => /lib64/libfreebl3.so (0x00007f355fd80000)

在github上面搜索distroless,这个是谷歌的容器工具。
在这里插入图片描述
下载
在这里插入图片描述我用的是debian10,导入镜像。

[root@docker1 docker]# docker load -i base-debian10.tar 

这个base镜像小

[root@docker1 docker]# docker images 
gcr.io/distroless/base-debian10   latest              d48fcdd54946        52 years ago        19.2MB

首先在github搜索distroless nginx,进去
在这里插入图片描述
然后查看别人写好的Dockerfile,可以看出用的是官方提供的最小镜像并且是多阶段构建,以及将系统的库文件考入。
在这里插入图片描述编写Dockerfile2

[root@docker1 docker]# cat Dockerfile2
FROM nginx:1.18.0 as base

# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE

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 /usr/sbin/nginx-debug /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /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* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /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-debian10

COPY --from=base /opt /

EXPOSE 80 443

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

构建镜像,-f指定dockerfile2,要不然读取的是默认的Dockerfile

[root@docker1 docker]# docker build -t webserver:v4 -f Dockerfile2 .

效果

[root@docker1 docker]# docker images webserver
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
webserver           v4                  0fce27d5ac56        15 seconds ago      31.7MB

运行容器,运行成功。

[root@docker1 docker]# docker run -d --name nginx webserver:v4
[root@docker1 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
79bc3e329d8f        webserver:v4        "nginx -g 'daemon of…"   23 seconds ago      Up 22 seconds       80/tcp, 443/tcp     nginx
[root@docker1 docker]# docker inspect nginx | grep IP
                    "IPAddress": "172.17.0.2",

访问成功

[root@docker1 docker]# curl 172.17.0.2
<h1>Welcome to nginx!</h1>

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值