zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    .Net WebApi接口之Swagger UI 隐藏指定接口类或方法
    .Net WebApi接口之Swagger集成详解
    SVN服务器的本地搭建和使用
    MemCache在.NET中使用Memcached.ClientLibrary详解
    Memcache分布式锁
    MemCache可视化客户端管理及监控工具TreeNMS
    Redis可视化客户端管理及监控工具TreeNMS
    MemCache服务安装配置及windows下修改端口号
    MemCache在win7上的可视化配置以及Nodejs/Net应用
    Redis分布式锁
  • 原文地址:https://www.cnblogs.com/lgj8/p/12289837.html
Copyright © 2011-2022 走看看