前言 镜像的优化注意几条:
- 选择最精简的基础镜像
- 减少镜像的层数
- 清理镜像构建的中间产物
- 注意优化网络请求
- 尽量去用构建缓存
- 使用多阶段构建镜像
接下来,我们以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 .
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.htmlindex.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
REPOSITORYTAGIMAGE IDCREATEDSIZE
nginxv1c3370bb3788a6 minutes ago276MB
rhel7latest0a3eb3fde7fd5 years ago140MB
第一次优化 优化思路:将不想看到的输出都导入到垃圾箱,例如刚刚封装时编译过程,如下图
文章图片
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
REPOSITORYTAGIMAGE IDCREATEDSIZE
nginxv2e47941468af7About a minute ago252MB
nginxv1c3370bb3788a16 minutes ago276MB
rhel7latest0a3eb3fde7fd5 years ago140MB
第二次优化: 优化思路:将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
REPOSITORYTAGIMAGE IDCREATEDSIZE
nginxv3cbda333c4f7d30 seconds ago250MB
nginxv2e47941468af714 minutes ago252MB
nginxv1c3370bb3788a29 minutes ago276MB
rhel7latest0a3eb3fde7fd5 years ago140MB
优化后镜像减少了2M,效果仍然不佳
文章图片
第三次优化: 优化思路:使用多阶段构建
1.Dockerfile如下:
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.9FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;
"]
【k8s|Dockerfile镜像优化方案指引】
文章图片
2.构建镜像并查看镜像大小
[root@server1 docker]# docker build -t nginx:v4 .
[root@server1 docker]# docker images
REPOSITORYTAGIMAGE IDCREATEDSIZE
nginxv451d0075d748623 seconds ago141MB
nginxv3cbda333c4f7d4 minutes ago250MB
nginxv2e47941468af718 minutes ago252MB
nginxv1c3370bb3788a33 minutes ago276MB
rhel7latest0a3eb3fde7fd5 years ago140MB
优化后效果明显镜像减小到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
ARGS Asia/ShanghaiRUN 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/localtimeFROM gcr.io/distroless/baseCOPY --from=base /opt /EXPOSE 80ENTRYPOINT ["nginx", "-g", "daemon off;
"]
2.构建镜像并查看镜像大小
显而易见,镜像大大减小为23.2M,效果明显
[root@server1 docker]# docker build -t nginx:v5 .
[root@server1 docker]# docker images
REPOSITORYTAGIMAGE IDCREATEDSIZE
nginxv5ea590f5d522fAbout a minute ago23.2MB
nginxv451d0075d748620 minutes ago141MB
nginxv3cbda333c4f7d25 minutes ago250MB
nginxv2e47941468af739 minutes ago252MB
nginxv1c3370bb3788aAbout an hour ago276MB
3.构建容器并测试
[root@server1 docker]# docker run -d --name vm1 nginx:v5
50a7f5cf1617d57df98659a99424e327ee529dab1e8b16f2ba222014b64e457a
查看IP
[root@server1 docker]# docker inspect vm1
文章图片
[root@server1 docker]# curl172.17.0.3
能正常访问到Nginx默认发布页,证明容器镜像可以正常使用
文章图片
推荐阅读
- linux|2022年云原生趋势
- 个人日记|K8s中Pod生命周期和重启策略
- k8s|Scheduling Framework 与 Extender对比及详细介绍
- k8s|k8s(六)(配置管理与集群安全机制)
- Go|Docker后端部署详解(Go+Nginx)
- docker|Docker
- 【快速学习】docker构建java项目实践
- Alpine Docker 安装 bash
- K8s自动化运维平台
- docker|docker导入dmp文件到oracle容器