V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhaojun1998
V2EX  ›  分享发现

谈一种另类的压缩 Docker 镜像大小的方式

  •  
  •   zhaojun1998 · 2 天前 · 676 次点击

    最近将一个 Spring Boot 项目编译成了 Spring Native 可执行文件,项目启动速度是上来了,但是可执行文件的大小可骤增至 350M 左右,导致 Docker 镜像的大小也一起增加了很多,考虑到 Docker 拉取本身的网络就很坎坷了,我就想有没有办法能再压缩下大小。

    最开始的方案是使用 upx, 压缩率不错,压缩后可直接执行,但是发现这个工具是有代价的,因为他是执行时从内存中解压你原本的程序,所以你节省了多少可执行文件大小,就会额外占用多少内存,这对我是不可接受的,我觉得内存更可贵一些,这个方案可能更适合 go 程序使用,本身可执行文件大小不会太大,所以也不会导致增加很多内存占用。

    第二个方案是无意中想到的,我能不能自己压缩文件放到镜像中,然后在运行时解压出来再执行,这相较于 upx 的方案来说是在硬盘解压,不会额外占用内存,但是这个要考虑解压的速度(压缩速度不是很重要,可以用 CI/CD 来跑),然后就找到了一个压缩算法 zstd,不论压缩率设置多高,解压缩的时间都是一样的 (如 350M 使用 zstd -19 最高级别,压缩时间 5 分钟,大小可达到 80M 左右,但解压时间仅 0.5 秒)。

    然后在 Dockerfile 中给镜像安装 zstd ,并在最后运行时进行判断是否解压:

    FROM debian:10-slim
    
    ARG TARGETARCH
    
    RUN apt update -y && apt install --no-install-recommends zstd -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    
    # 省略其他
    
    CMD if [ -f /data/app.zst ]; then zstd --no-progress -d /data/app.zst && rm -rf /data/app.zst && chmod +x /data/app && /data/app --spring.config.location=file:/root/application.properties; else chmod +x /data/app && /data/app --spring.config.location=file:/root/application.properties; fi
    

    不知道这种方式算优雅,还是算丑陋,但至少解决了我的问题,希望也能帮助到有类似需求的人。

    5 条回复    2024-12-24 18:05:37 +08:00
    mayli
        1
    mayli  
       2 天前
    有点闲,docker image 本身就是压缩的

    https://docs.docker.com/build/exporters/#compression

    docker buildx build \
    --output type=image,name=<registry>/<image>,push=true,compression=zstd .
    zhaojun1998
        2
    zhaojun1998  
    OP
       2 天前
    @mayli #1

    感谢,我试试这个,之前真不知道。
    netnr
        3
    netnr  
       2 天前
    专业的加个参数就搞定了 😂
    pigeon2049
        4
    pigeon2049  
       2 天前
    另一个方法
    使用 maven 作为运行时 base image
    或者 dockerfile 里安装 maven
    springboot 使用 thin-launcher

    https://github.com/spring-projects-experimental/spring-boot-thin-launcher

    这样打包时所有依赖都不会带上 配置好 maven 运行时会自动拉取 缺点是首次运行会慢很多
    优点是极度节省 docker 镜像的空间 完整 jar 包 500M
    thin-layout 打出来 5M
    lower
        5
    lower  
       2 天前
    @pigeon2049 op 都打成 native image 了,这种应该不支持吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1054 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 19:49 · PVG 03:49 · LAX 11:49 · JFK 14:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.