鏡像的優化

  • 選擇最精簡的基礎鏡像
  • 減少鏡像的層數
  • 清理鏡像構建的中間產物
  • 注意優化網絡請求
  • 儘量去用構建緩存
  • 使用多階段構建鏡像

打開虛擬機然後打開docker

systemctl start docker

然後我們編輯我們的dockerfile(vim dockfile)

FROM rhel7
ADD nginx-1.16.1.tar.gz /mnt 
WORKDIR /mnt/nginx-1.16.1
RUN yum install -y gcc 
VOLUME ["/usr/Local/nginx/html"]
CMD ["world"]

然後我們進入容器查看

[root@server1 docker]# docker run -it --rm rhel7 bash 
bash-4.2#1s 
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

然後我們編輯我們的yum源,bash-4.2# vi dvd.repo

[dvd]
name=rhe17
baseurl=http://172.25.0.74/rhel7.6
gpgcheck=0

然後我們我們安裝軟件

bash-4.2# vum install -y gcc make pcre-devel

如果安裝過程中出現rpdmdb報錯之類的我們重新rebuilddb就可以了

 

如果我們使用7.0的鏡像的話我們的dockerfile需要做重新對nginx進行編譯等操作

FROM rhel7
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt 
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb
RUN yum install -y gcc make pcre-devel zlib-devel 
RUN sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc 
RUN./configure--prefix=/usr/Local/nginx 
RUN make 
RUN make install 
VOLUME ["/usr/local/nginx/html"] 
CMD ["nginx","-g","daemon off;"]

然後我們build容器

docker build -t nginx:v1 .

我們通過docker history nginx:v1查看

 

然後我們運行查看

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

通過curl查看nginx運行是否成功

 

因爲我們設置了volume所以他會自動給我們掛載到默認的目錄中

然後我們可以自己穿件一個文件

vim test。html

www.westos.org

然後我們去訪問

[rooteserver1 data]# curl 172.17.0.2/test.html 
www.westos.org

如何減少鏡像層數

我麼可以通過&&連接符將run中的內容都連到一起

FROM rhel7
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt 
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel  && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx  && make && make install 
VOLUME ["/usr/local/nginx/html"] 
CMD ["nginx","-g","daemon off;"]

然後我們再去build

docker build -t nginx:v2 .最後 會發現大小確實變小了,證明了減少層數能夠減少大小

  

清理鏡像構建中間的產物

比如我們可以使用yum clean all,清楚yum緩存,然後通過rm -fr /mnt/nginx-1.16.1

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

然後我們build v3

docker build -t nginx:v3 .然後再去查看會發現清理了緩存之後會少將近30M

使用多階段構建鏡像,我們最重要的就是VOLUME等後面幾步,我們可以把前面幾步都歸爲一步然後再拷貝過來

FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt 
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel  && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx  && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM rhel7
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"] 
CMD ["nginx","-g","daemon off;"]

docker build -t nginx:v4 .然後再去查看會發現這樣少了100M多

 

選擇最精簡的鏡像

鏡像有很多我們選用的是140M的算是很精簡的鏡像了

我們也可以使用更精簡的鏡像比如使用ubuntu,然後再運行

FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt 
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel  && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx  && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM ubuntu
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"] 
CMD ["nginx","-g","daemon off;"]

然後我們發現這次只有65.1M

 

然後我們進行運行查看發現並不能使用,ubuntu缺少一定的庫

但是我們這麼做並沒有錯誤

[root@server1 docker]# docker run -it--rm nginx:v5 bash
root@13627f02fa14:/#
root@13627f02fa14:/#
root@13627f02fa14:/#1s
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

但是我們剛纔創建的v4是可以我們可以通過v4將v5缺少的庫都拷貝過去ubuntu缺少的是libpcre.so.l庫我們從v4的rhel中拷貝過去。

FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt 
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel  && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx  && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM ubuntu
COPY libpcre.so.1 /lib/x86 64-linux-gnu
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"] 
CMD ["nginx","-g","daemon off;"]

然後我們刪除v5重新創建一個v5

[rooteserver1 docker]# docker run -it --rm nginx:v5 bash

然後去查看我們剛纔的那個拷貝的文件是否正確了

 

然後去運行v5

發現還是存在問題,缺少nobody用戶,也可能是內置文件存在差異等問題,此處就不做排錯了。

我們可以拉取更小的一個base-debian10

我們也可以從GitHub下載更多的base鏡像

 

通過docker images

發現其只有19.2M

FROM nginx as base

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 /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 /

USER 1000:1000

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

然後我們build和run發現還是存在問題,我們刪除剛纔創建的nginx和v5

如果我們按照要求使用1.17版本的nginx然後在我們刪除後面的用戶信息發現測試成功

FROM nginx1.17 as base

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 /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 /

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

通過測試發現無論是nginx1.17還是使用最新的nginx版本都可以實現容器的正常運行,只要刪除用戶信息即可。

如果覺得鏡像名字太長可以通過tag進行修改

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章