【Docker】基于华为 openEuler 应用 Docker 镜像体积压缩

书接 openEuler 系列文章(可以翻看测试系列),本次跟大家说说如何将 Java 包轻量化地构建到 openEuler 镜像中且保持镜像内操作系统是全补丁状态。

之前我们都是使用现成的 jdk 镜像进行构建的,如下图:

FROM ibm-semeru-runtimes:open-8u392-b08-jre-jammyVOLUME /tmp
ADD compress-example-0.0.1.jar /home
WORKDIR /home/
ENTRYPOINT ["java","-jar","compress-example-0.0.1.jar"]

这样构建的速度又快又轻量化,如下图:

yuanzhenhui@MacBook-Pro target % docker build -t compress-example1 .
[+] Building 2.3s (8/8) FINISHED                                                                                                     docker:desktop-linux=> [internal] load build definition from Dockerfile                                                                                                 0.0s=> => transferring dockerfile: 542B                                                                                                                 0.0s=> [internal] load .dockerignore                                                                                                                    0.0s=> => transferring context: 2B                                                                                                                      0.0s=> [internal] load metadata for docker.io/library/ibm-semeru-runtimes:open-8u392-b08-jre-jammy                                                      0.0s=> [internal] load build context                                                                                                                    0.5s=> => transferring context: 50B                                                                                                                     0.4s=> CACHED [1/3] FROM docker.io/library/ibm-semeru-runtimes:open-8u392-b08-jre-jammy                                                                 0.0s=> [2/3] ADD compress-example-0.0.1.jar /home                                                                                                       1.4s=> [3/3] WORKDIR /home/                                                                                                                             0.0s=> exporting to image                                                                                                                               0.3s=> => exporting layers                                                                                                                              0.2s=> => writing image sha256:2543f431ddd2bc33b1448711965bd376a5a1849034519da7d22eec34779d3851                                                         0.0s=> => naming to docker.io/library/compress-example1                                                                                                 0.0sWhat's Next?View summary of image vulnerabilities and recommendations → docker scout quickview

最终结果是原始镜像 256MB,测试应用镜像299MB。如下图:

yuanzhenhui@MacBook-Pro target % docker images
REPOSITORY                              TAG                        IMAGE ID       CREATED         SIZE
compress-example1                       latest                     2543f431ddd2   4 seconds ago   299MB
ibm-semeru-runtimes                     open-8u392-b08-jre-jammy   5dd0d62cb035   4 days ago      256MB

但奈何我们有业务方面有“信创”的要求,所有第三方软件都需要“国产化”。为此选择了华为的 openEuler 作为操作系统,镜像方面也是采用华为的 openEuler 为原始镜像。下载 openEuler 最新镜像(23.09)进行验证,发现镜像中并没有安装 JDK。于是我们在接下来的构建中其实还需要安装 JDK 并进行环境变量配置。如下图:

# 基础镜像
FROM openeuler/openeuler:23.09# 上传同级目录中的毕昇jdk到镜像根目录
ADD bisheng-jre-8u392-linux-x64.tar.gz .# 在镜像内执行系统更新,保证镜像内系统已安装最新补丁(这里采用连接符来进行串联处理能够有效减少构建体积)
RUN yum update -y && \
yum upgrade -y && \
yum install fontconfig -y && \
yum autoremove -y && \
mv bisheng-jre1.8.0_392 java# 设置jdk变量
ENV JAVA_HOME /java
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$PATH# 设置系统编码(这里可以参考我之前为 openEuler 写的测试系列文章,里面会有答案的)
ENV LC_ALL C.utf8
ENV LANG C.utf8# 挂载文件夹路径
VOLUME /tmp# 上传jar包到制定目录
ADD compress-example-0.0.1.jar /home# 指定工作目录
WORKDIR /home/# 执行语句
ENTRYPOINT ["java","-jar","compress-example-0.0.1.jar"]

如果你像我一样没有提前下载 openEuler 镜像,那么构建的时间将会再进一步延长,如下图:

yuanzhenhui@MacBook-Pro target % docker build -t compress-example2 .  
[+] Building 61.1s (10/10) FINISHED                                             docker:desktop-linux=> [internal] load .dockerignore                                                               0.0s=> => transferring context: 2B                                                                 0.0s=> [internal] load build definition from Dockerfile                                            0.0s=> => transferring dockerfile: 1.08kB                                                          0.0s=> [internal] load metadata for docker.io/openeuler/openeuler:23.09                            0.0s=> CACHED [1/5] FROM docker.io/openeuler/openeuler:23.09                                       0.0s=> [internal] load build context                                                               0.7s=> => transferring context: 46.93MB                                                            0.7s=> [2/5] ADD bisheng-jre-8u392-linux-x64.tar.gz .                                              1.4s=> [3/5] RUN yum update -y && yum upgrade -y && yum install fontconfig -y && yum autoremove   57.3s=> [4/5] ADD compress-example-0.0.1.jar /home                                                  0.3s => [5/5] WORKDIR /home/                                                                        0.0s => exporting to image                                                                          1.2s => => exporting layers                                                                         1.2s => => writing image sha256:1276428318f6f92f25ef16b064af257cc6add2c82a471e351d0fd501b607f508    0.0s => => naming to docker.io/library/compress-example2                                            0.0s What's Next?View summary of image vulnerabilities and recommendations → docker scout quickview

这个构建速度的确是有点慢要差不多一分钟,大部分时间都耗费在 yum 更新的那些事情上面了。我们再看看这个体积大小,如下图:

yuanzhenhui@MacBook-Pro target % docker images
REPOSITORY                              TAG                        IMAGE ID       CREATED          SIZE
compress-example2                       latest                     1276428318f6   3 minutes ago    614MB
compress-example1                       latest                     2543f431ddd2   27 minutes ago   299MB
ibm-semeru-runtimes                     open-8u392-b08-jre-jammy   5dd0d62cb035   4 days ago       256MB
openeuler/openeuler                     23.09                      09c854b5d453   2 months ago     210MB

这个测试应用镜像 2 竟然有 614MB,几乎是原镜像的 3 倍。究竟为什么会出现 3 倍的情况呢?由什么原因造成的呢?这个我们只需要使用 Docker Desktop 来看看就好了,如下图:

image.png
不得不说这个 Docker Desktop 真的非常好用。通过镜像分析就可以知道,多出来的体积一个是来自毕昇 jdk 的上传导致的,另外一个就是应用 jar 包的体积(出现风险先忽略不计哈),还有执行 RUN 指令后进行了系统更新这个也会产生新的体积。前两个是没有办法的啦。要用国产 jdk,又要上传应用 jar ,难道不用么?那么能够压缩的就只能是 yum 更新的这部分内容了。还有右侧告诉了我们究竟更新了什么内容,我们可以将不要的 package 摘录出来,在构建的时候用 yum remove 删除掉就好。为此,我们先运行一下 openeuler/openeuler:23.09 原始镜像,如下图:

yuanzhenhui@MacBook-Pro target % docker run -it openeuler/openeuler:23.09 /bin/bash

接着使用 yum list installed 命令看看有哪些已安装但没有用的包,这个过程比较漫长就不再文章里面说明了,因为这涉及到验证(毕竟怕删错了一些依赖组件)。最终的Dockerfile 如下所示:

# 基础镜像
FROM openeuler/openeuler:23.09# 上传同级目录中的毕昇jdk到镜像根目录
ADD bisheng-jre-8u392-linux-x64.tar.gz .# 在镜像内执行系统更新,保证镜像内系统已安装最新补丁(由于镜像只做 java web 的部署和使用,这里可以将一下不需要的调试包和工具删除)
RUN yum update -y && \
yum upgrade -y && \
yum install fontconfig -y && \
yum remove vim-minimal -y && \
yum remove tar -y && \
yum remove bc -y && \
yum remove gdb-gdbserver -y && \
yum autoremove -y && \
yum clean all && \
mv bisheng-jre1.8.0_392 java# 设置jdk变量
ENV JAVA_HOME /java
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$PATH# 设置系统编码
ENV LC_ALL C.utf8
ENV LANG C.utf8# 挂载文件夹路径
VOLUME /tmp# 上传jar包到制定目录
ADD compress-example-0.0.1.jar /home# 指定工作目录
WORKDIR /home/# 执行语句
ENTRYPOINT ["java","-jar","compress-example-0.0.1.jar"]

得到的最终结果是这样的,如下图:

yuanzhenhui@MacBook-Pro target % docker build -t compress-example3 .
[+] Building 52.6s (10/10) FINISHED                                                                                                                                   docker:desktop-linux=> [internal] load .dockerignore                                                                                                                                                     0.0s=> => transferring context: 2B                                                                                                                                                       0.0s=> [internal] load build definition from Dockerfile                                                                                                                                  0.0s=> => transferring dockerfile: 1.21kB                                                                                                                                                0.0s=> [internal] load metadata for docker.io/openeuler/openeuler:23.09                                                                                                                  0.0s=> [1/5] FROM docker.io/openeuler/openeuler:23.09                                                                                                                                    0.0s=> [internal] load build context                                                                                                                                                     0.0s=> => transferring context: 246B                                                                                                                                                     0.0s=> CACHED [2/5] ADD bisheng-jre-8u392-linux-x64.tar.gz .                                                                                                                             0.0s=> [3/5] RUN yum update -y && yum upgrade -y && yum install fontconfig -y && yum remove vim-minimal -y && yum remove tar -y && yum remove bc -y && yum remove gdb-gdbserver -y &&   51.4s=> [4/5] ADD compress-example-0.0.1.jar /home                                                                                                                                        0.1s=> [5/5] WORKDIR /home/                                                                                                                                                              0.0s => exporting to image                                                                                                                                                                0.9s => => exporting layers                                                                                                                                                               0.9s => => writing image sha256:27c6709bae124f79cdabb6302369216c0bf04e4d1410f4034c587f72b9fd3f5a                                                                                          0.0s => => naming to docker.io/library/compress-example3                                                                                                                                  0.0s What's Next?View summary of image vulnerabilities and recommendations → docker scout quickview

构建的时间比之前的还少了几秒,最后看看这几次构建的结果,如下图:

yuanzhenhui@MacBook-Pro target % docker images
REPOSITORY                              TAG                        IMAGE ID       CREATED              SIZE
compress-example3                       latest                     27c6709bae12   About a minute ago   539MB
compress-example2                       latest                     1276428318f6   2 hours ago          614MB
compress-example1                       latest                     2543f431ddd2   2 hours ago          299MB

测试应用 3 镜像比测试应用 2 镜像体积要更小了。
至此,原生的 Docker 镜像压缩方案完成。

那么为什么要做镜像压缩呢?其实之前一直没有留意到镜像太大的问题(可能之前大部分时间都是直接拿 Docker hub 里 OpenJDK 厂家做好的镜像来构建,出来体积不会太大因此在转“信创”业务线之后也一直没有留意),直到运维那边反馈说应用包太大导致每次发布拉取的时间极长。后来到 UAT 服务器上看了一下。如下图:

REPOSITORY                  TAG               IMAGE ID       CREATED             SIZE
xxx/uat/chain-evaluate     12151627          e1808f7ff397   5 days ago          1.72GB
xxx/uat/chain-service      12151626          9078e026a429   5 days ago          1.72GB

好家伙,每个镜像都几乎有 1.5 GB 以上。除了网络小水管有问题外,日后镜像私库也会告急。这…就只能想办法来压缩一下。
其实最好的做法就是看看有没有第三方的工具直接对成品镜像进行压缩。

您可别说还真有,网上比较火的就是 docker-slim(slimtoolkit)和 docker-squash 两款工具。经实测,两款工具是真的强大。唯一的缺点就是配置参数也有点多了(其实 docker-squash 还可以但 docker-slim 就…),像我这种想“开(偷)箱(懒)即(省)用(事)”的人来说还是有点麻烦。

为此就选择在构建的时候去场景进行精简处理,毕竟 Dockerfile 还是挺灵活的,指令用起来就像直接操作系统一样。最最最重要的一点是,用第三方工具一不留神有可能连关键功能都给你“嘎”掉,而你当时是不知道的,到上生产之后出现故障了才发现,又要排查一段时间…这些都是次生风险。与其这样,还不如老老实实从自己清晰的方向出发吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/291575.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS笔记之rosbag的快速切片(C++实现)

ROS笔记之rosbag的快速切片(C实现) —— 杭州 2023-12-21 夜 code review 文章目录 ROS笔记之rosbag的快速切片(C实现)1.运行效果2.文件结构3.fast_rosbag_slice.cpp4.CMakeLists.txt5.package.xml6.对fast_rosbag_slice.cpp进行函数封装 正常该功能是ROS官方命令行&#xff1a…

安全、效率、成本:混合云数据库管理的三重挑战!

随着业务需求的不断演变,数据在多云平台之间流动,给数据库管控带来了新的层次和复杂性。这给数据库管控带来了前所未有的挑战。企业可能面临着一系列问题,包括安全性挑战、管理复杂性、性能与效率问题、成本控制难题、缺乏统一的管理视图以及…

Hardhat环境搭建(六)---无需翻墙

Hardhat环境搭建 官方地址 node环境 npm环境 git环境 安装hardhat npm init npminit是什么 在node开发中使用npm init会生成一个pakeage.json文件,这个文件主要是用来记录这个项目的详细信息的,它会将我们在项目开发中所要用到的包,以…

7.串口通信uart编写思路及自定义协议

前言: 串口是很重要的,有许多模块通信接口就是串口,例如gps模块,蓝牙模块,wifi模块还有一些精度比较高的陀螺仪模块等等,所以学会了串口之后,这些听起来很牛批的模块都能够用起来了。此外&#…

【Midjourney】Midjourney根据prompt提示词生成黑白色图片

目录 🍇🍇Midjourney是什么? 🍉🍉Midjourney怎么用? 🔔🔔提示词格式 🍋🍋应用示例——“秘密花园”式涂色书配图生成 🍌🍌例子1…

pycharm下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令,报命令无法识别,错误信息如下: PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径&a…

AI Native工程化:百度App AI互动技术实践

作者 | GodStart 导读 随着AI浪潮的兴起,越来越多的应用都在利用大模型重构业务形态,在设计和优化Prompt的过程中,我们发现整个Prompt测评和优化周期非常长,因此,我们提出了一种Prompt生成、评估与迭代的一体化解决方案…

华为OD机试 - 多段线数据压缩(Java JS Python C)

题目描述 下图中,每个方块代表一个像素,每个像素用其行号和列号表示。 为简化处理,多线段的走向只能是水平、竖直、斜向45度。 上图中的多线段可以用下面的坐标串表示:(2,8),(3,7),(3,6),(3,5),(4,4),(5,3),(6,2),(7,3),(8,4),(7,5)。 但可以发现,这种表示不是最简的,…

声音克隆:让你的声音变得无所不能

什么是声音克隆? 声音克隆是一种利用人工智能技术,根据一段声音样本,生成与之相似或完全相同的声音的过程。声音克隆可以用于多种场景。 声音克隆的原理是利用深度学习模型,从声音样本中提取声音特征,然后根据目标文…

在ClickHouse数据库中启用预测功能

在这篇博文中,我们将介绍如何将机器学习支持的预测功能与 ClickHouse 数据库集成。ClickHouse 是一个快速、开源、面向列的 SQL 数据库,对于数据分析和实时分析非常有用。该项目由 ClickHouse, Inc. 维护和支持。我们将探索它在需要数据准备以…

Nvm切换nodejs版本

下载地址 Releases coreybutler/nvm-windows GitHub 安装运行 双击安装运行即可 下载速度慢的,可以通过修改配置文件切换国内下载镜像 node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: CNPM Binaries Mirror 打开安装目录,修改se…

云呼叫中心支持的通信渠道

1.电话通信 电话是云呼叫中心最常用的通信渠道之一。云呼叫中心可以通过电话与客户进行沟通,包括呼入和呼出电话。客户可以拨打企业提供的电话号码与企业联系,企业也可以通过云呼叫中心系统自动或手动拨打客户电话进行沟通。 2.短信通信 短信也是一种…