镜像的优化

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

打开虚拟机然后打开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进行修改

 

 

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