Dockerfile鏡像優化,減小鏡像


前言
鏡像的優化注意幾條:

選擇最精簡的基礎鏡像
減少鏡像的層數
清理鏡像構建的中間產物
注意優化網絡請求
盡量去用構建緩存
使用多階段構建鏡像
接下來我們以rhel7鏡像構建容器,並在容器中安裝nginx的源碼包。以此容器構建新的鏡像並做做優化

1.軟件准備

[root@server1 docker]# pwd
/tmp/docker
[root@server1 docker]# ls
nginx-1.15.9.tar.gz rhel7.tar

2.導入rhel7鏡像

[root@server1 ~]# docker load -i rhel7.tar

3.編寫Dockerfile

[root@server1 docker]# pwd
/tmp/docker
[root@server1 docker]# vim Dockerfile
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make
ADD nginx-1.15.9.tar.gz /mnt ##ADD比COPY更強大,如果文件是可識別的壓縮文件,會幫忙解壓
WORKDIR /mnt/nginx-1.15.9
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc ##關閉debug日志
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;"]

4.構建鏡像

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


5.創建容器,並測試是否能正常訪問

[root@server1 docker]# docker run -d --name nginx nginx:v1
096c2d2020638963e877e07a850589ff30e5f5af45278e33f8a859fed35dc81d
[root@server1 docker]#
[root@server1 docker]# docker inspect nginx
"Source": "/var/lib/docker/volumes/7a9f496f3b9d16fa9725ca107c39fa8b9d782c18f0dd3f8d04ea17022b72905a/_data",
"IPAddress": "172.17.0.2",

[root@server1 docker]# cd /var/lib/docker/volumes/7a9f496f3b9d16fa9725ca107c39fa8b9d782c18f0dd3f8d04ea17022b72905a/_data
[root@server1 _data]# ls
50x.html index.html
[root@server1 _data]# echo "hello world" > index.html
[root@server1 _data]#
[root@server1 _data]# cat index.html
hello world
[root@server1 _data]#
[root@server1 _data]# curl 172.17.0.2
hello world

6.查看鏡像大小,優化前大小為276M

[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 c3370bb3788a 6 minutes ago 276MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
1
2
3
4
第一次優化:
優化思路:將不想看到的輸出都導入到垃圾箱,例如剛剛封裝時編譯過程,如下圖

1.重新編寫Dockerfile

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

2.重新封裝鏡像

[root@server1 docker]# pwd
/tmp/docker
[root@server1 docker]# docker build -t nginx:v2 .

3.再次查看鏡像大小,與之前做比較,僅僅少了4M,效果不佳

[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 e47941468af7 About a minute ago 252MB
nginx v1 c3370bb3788a 16 minutes ago 276MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB

第二次優化:
優化思路:將RUN都放在一行,減少鏡像層數

1.Dockerfile如下

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

2.構建鏡像並查看鏡像大小

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


[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 cbda333c4f7d 30 seconds ago 250MB
nginx v2 e47941468af7 14 minutes ago 252MB
nginx v1 c3370bb3788a 29 minutes ago 276MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB


優化后鏡像減少了2M,效果仍然不佳

 

 


第三次優化:
優化思路:使用多階段構建

1.Dokcerfile如下

FROM rhel7 as build
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.9.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.9
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make &> /dev/null && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.15.9

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

2.構建鏡像並查看鏡像大小

[root@server1 docker]# docker build -t nginx:v4 .
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v4 51d0075d7486 23 seconds ago 141MB
nginx v3 cbda333c4f7d 4 minutes ago 250MB
nginx v2 e47941468af7 18 minutes ago 252MB
nginx v1 c3370bb3788a 33 minutes ago 276MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB

優化后效果明顯鏡像減小到150M

第四次優化:究極優化
優化思路:從底層優化

1.首先我們需要導入一個distroless和nginx鏡像

distroless”鏡像只包含應用程序及其運行時依賴項,不包含程序包管理器、shell以及在標准Linux發行版中可以找到的任何其他程序。
用distroless去除容器中所有不必要的東西

[root@server1 docker]# docker load -i distroless.tar
668afdbd4462: Loading layer [==================================================>] 18.39MB/18.39MB
Loaded image: gcr.io/distroless/base:latest

[root@server1 docker]# docker load -i nginx.tar
014cf8bfcb2d: Loading layer [==================================================>] 58.46MB/58.46MB
832a3ae4ac84: Loading layer [==================================================>] 53.91MB/53.91MB
e89b70d28795: Loading layer [==================================================>] 3.584kB/3.584kB
Loaded image: nginx:latest


2.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;"]

2.構建鏡像並查看鏡像大小

顯而易見,鏡像大大減小為23.2M,效果明顯

[root@server1 docker]# docker build -t nginx:v5 .
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v5 ea590f5d522f About a minute ago 23.2MB
nginx v4 51d0075d7486 20 minutes ago 141MB
nginx v3 cbda333c4f7d 25 minutes ago 250MB
nginx v2 e47941468af7 39 minutes ago 252MB
nginx v1 c3370bb3788a About an hour ago 276MB

3.構建容器並測試

[root@server1 docker]# docker run -d --name vm1 nginx:v5
50a7f5cf1617d57df98659a99424e327ee529dab1e8b16f2ba222014b64e457a

查看IP

[root@server1 docker]# docker inspect vm1


[root@server1 docker]# curl 172.17.0.3
1
能正常訪問到Nginx默認發布頁,證明容器鏡像可以正常使用

————————————————
版權聲明:本文為CSDN博主「@Limerence」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/meltsnow/article/details/94473852


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM