idea docker 镜像生成太慢太大问题

文章目录

  • 前言
  • 一、更小的jdk基础镜像
  • 二、服务瘦包(thin jar)
    • 2.1 maven
    • 2.2 修改dockerfile
    • 2.3 container run options
  • 三、 基础jdk镜像入手?
  • 总结


前言

idea docker 内网应用实践遗留问题

  1. idea docker插件 build 服务镜像太慢
  2. 服务镜像太大

一、更小的jdk基础镜像

精简的jdk镜像 123MB,jdk17-alpine

二、服务瘦包(thin jar)

打包成瘦包(thin jar)在许多情况下都有明显的优势,尤其是在企业级和分布式部署环境中。以下是瘦包的一些主要好处:

  • 减小文件尺寸: 瘦包仅包含应用本身的代码和必需的资源,不包含外部依赖。这通常会导致文件尺寸比包含所有依赖的胖包(fat jar)小得多,这使得上传到服务器或存储在仓库中更快速、更高效。

  • 快速构建: 在构建过程中,由于不需要打包所有的依赖,构建瘦包通常比构建胖包要快。

  • 部署灵活性: 瘦包允许在部署时选择性地添加依赖。你可以根据不同的环境(开发、测试、生产)来管理依赖,这意味着可以有针对性地解决依赖性问题。

  • 共享依赖: 如果多个应用部署在同一服务器上,它们可以共享相同的依赖库,减少重复的依赖文件,节省空间。

  • 依赖管理: 瘦包使得依赖管理更加明确。所有的外部依赖都在构建或部署过程中被解决,这样可以更容易地处理依赖之间的冲突。

  • 更新和维护: 如果需要更新或替换某个依赖,你可以单独更新那个依赖,而不需要重新构建整个应用的胖包。

  • 资源占用: 对于基于微服务的架构,使用瘦包可以在微服务之间共享公共的运行时环境,减少了每个服务实例的资源占用。

  • 安全性: 在有严格安全要求的环境中,使用瘦包可以更容易地进行安全审计,因为你可以精确地知道哪些库是运行时必需的。

  • 与容器技术协同: 在使用容器技术(如 Docker)时,瘦包可以轻松结合基础镜像中的依赖,便于创建轻量级的容器镜像。

然而,瘦包也有它的缺点,例如可能需要额外的依赖管理工具或处理依赖传递的复杂性,因此在决定使用瘦包时,需要根据项目的具体需求和部署环境来权衡利弊。

2.1 maven

plugins 添加maven打包策略

            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <version>2.3.12.RELEASEversion>
                <configuration>
                    <mainClass>com.cuzue.file.FileServerApplicationmainClass>
                    <layout>ZIPlayout>
                    
                    <includes>
                        <include>
                            <groupId>nothinggroupId>
                            <artifactId>nothingartifactId>
                        include>
                    includes>
                configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-dependency-pluginartifactId>
                <executions>
                    <execution>
                        <id>copy-dependenciesid>
                        <phase>prepare-packagephase>
                        <goals>
                            <goal>copy-dependenciesgoal>
                        goals>
                        <configuration>
                            <outputDirectory>../liboutputDirectory>
                            <excludeTransitive>falseexcludeTransitive>
                            <stripVersion>falsestripVersion>
                            
                            <includeScope>runtimeincludeScope>
                        configuration>
                    execution>
                executions>
            plugin>

2.2 修改dockerfile

主要修改:

  • 外部lib 容器卷挂载
  • JVM使用/dev/urandom作为熵源来加快随机数的生成速度-Djava.security.egd=file:/dev/./urandom
FROM jdk-alpine:17
LABEL maintainer="cuzue [email protected]"
VOLUME ["/tmp","/mnt/upload","/server/lib"]
ADD target/*.jar file.jar
ENV SERVER_PORT="8000" XMS="1024m" XMX="1024m" NACOS_CONFIG_ADDR="nacos.server:8848" NACOS_CONFIG_SPA="intelligence-gsdss" NACOS_DISCOVERY_ADDR="nacos.server:8848" NACOS_DISCOVERY_SPA="intelligence-gsdss" MAIN_CLASS="com.cuzue.file.FileServerApplication"
ENTRYPOINT java -server -Xms$XMS -Xmx$XMX -Dserver.port=$SERVER_PORT -Dloader.path=/server/lib/ -Djava.security.egd=file:/dev/./urandom -Duser.timezone=Asia/Shanghai -Dspring.profiles.active=dev -Dspring.cloud.nacos.config.server-addr=$NACOS_CONFIG_ADDR -Dspring.cloud.nacos.config.namespace=$NACOS_CONFIG_SPA -Dspring.cloud.nacos.discovery.server-addr=$NACOS_DISCOVERY_ADDR -Dspring.cloud.nacos.discovery.namespace=$NACOS_DISCOVERY_SPA -jar file.jar $MAIN_CLASS

2.3 container run options

  • 上传服务package生成的lib包到宿主机/data/server/app/lib
  • docker容器启动指定容器卷-v /data/server/app/lib:/server/lib
    容器卷指定路径,宿主机/data/server/app/lib容器路径/server/lib

idea docker 镜像生成太慢太大问题_第1张图片

三、 基础jdk镜像入手?

下一步思路多阶段构建或更好的方案,没有具体实践,不知道怎么弄,有经验的小伙伴希望可以分享一下可行性高的方案

打包镜像时不将jdk基础镜像打包到每一个服务中,类似挂载jdk容器卷可以实现,但是这种方式并不是Docker的最佳实践,且可能会导致预期之外的问题,特别是在使用不同版本的JDK或涉及到JDK内部路径变动时。

GPT的建议:
在Docker中,如果你想要避免将JDK基础镜像打包到每一个服务的镜像中,可以采用以下几种常见的方法:

  1. 使用多阶段构建(Multi-stage build):
    多阶段构建允许你在一个Dockerfile中使用多个FROM语句。你可以在一个阶段使用包含JDK的基础镜像来编译和构建应用,然后在第二个阶段只将编译后的应用复制到一个不含JDK的轻量级基础镜像中。例如:

    # 第一阶段:构建
    FROM maven:3.6.3-jdk-11 AS builder
    WORKDIR /app
    COPY src /app/src
    COPY pom.xml /app
    RUN mvn clean package
    
    # 第二阶段:创建最终镜像
    FROM openjdk:11-jre-slim
    COPY --from=builder /app/target/my-app.jar /app/
    CMD ["java", "-jar", "/app/my-app.jar"]
    

    这样做的好处是你的最终镜像大小减小,因为它不包含整个JDK,只有JRE。

  2. 使用JRE基础镜像:
    如果你的应用不需要JDK中的编译工具,而只需要运行Java字节码,你可以直接使用JRE基础镜像而不是JDK。这可以减少镜像大小并缩短下载时间。

  3. 创建自定义基础镜像:
    你可以创建一个自定义的基础镜像,其中包含了JDK和你的应用通用的其他依赖。然后,你可以在构建每个服务的Docker镜像时使用这个自定义镜像作为基础。

  4. JDK资源共享:
    如果你的多个服务部署在同一台机器上,可以考虑在Docker主机上安装JDK,并通过卷(volume)共享的方式让不同的容器使用同一个JDK。

  5. 使用精简版JDK发行版:
    对于需要JDK环境的服务,可以考虑使用精简版的JDK发行版,如AdoptOpenJDK的OpenJ9、Alibaba的Dragonwell或者Amazon的Corretto等。这些发行版往往提供了更小的容器镜像。

请注意,选择哪种方法取决于你的具体需求和约束。多阶段构建是最常见的做法,因为它提供了灵活性和优化的最终镜像大小。不过,如果你的服务确实需要JDK来运行,例如它们使用JDK特定的工具或API,那么这种情况下你可能无法避免在每个服务镜像中包含JDK。

总结

GPT的建议:
如果你在使用 IntelliJ IDEA 配合 Docker 进行镜像构建时遇到速度慢的问题,可以尝试以下几种方法来改善这个情况:

  1. 优化 Dockerfile:
  • 减少镜像层数:每条 RUNCOPYADD 指令都会创建一个新的镜像层。通过组合指令来减少层数可以减少构建时间。
  • 使用 .dockerignore 文件:排除不必要的文件和目录被复制到 Docker 上下文中,减少构建时间和镜像大小。
  • 利用构建缓存:确保更改频繁的指令放在 Dockerfile 的底部,这样可以最大化地利用 Docker 缓存。
  1. 提升硬件性能:
  • Docker 镜像构建过程中可能会占用大量的 CPU 和内存资源,确保你的开发机器有足够的资源分配给 Docker。
  • 如果使用的是虚拟机或远程 Docker 守护进程,提高网络速度和分配给虚拟机的资源可能有帮助。
  1. 使用更快的网络连接:
  • 镜像构建过程中可能需要下载基础镜像和依赖,网络速度的快慢直接影响到下载速度。
  1. 设置 Docker 镜像加速器:
  • 很多地区通过 Docker 官方镜像源下载镜像可能会比较慢,使用国内的镜像加速服务可以显著提高下载速度。
  1. 减少构建上下文大小:
  • Docker 在构建镜像时,会将当前目录(即构建上下文)发送到 Docker daemon,如果当前目录很大,会导致构建过程缓慢。减少构建上下文的大小可以提高速度。
  1. 分阶段构建(Multi-stage builds):
  • 如果你的应用构建过程包括编译等多个步骤,可以使用分阶段构建来减少最终镜像的大小,从而减少上传到仓库的时间。
  1. 预先拉取基础镜像:
  • 如果构建过程需要使用到某些特定的基础镜像,提前手动拉取这些镜像可以省去构建过程中的下载时间。
  1. 关闭 IDE 的不必要插件或服务:
  • IntelliJ IDEA 中运行的其他后台任务可能会影响到 Docker 镜像构建的性能,尝试关闭不需要的插件或服务。
  1. 定期清理 Docker:
  • 定期使用 docker system prune 清理无用的 Docker 对象(例如悬空的镜像和停止的容器),可以释放磁盘空间,有时也能提高构建速度。

检查这些方面,并根据你的具体情况进行调整,应该能够帮助你提高在 IntelliJ IDEA 中使用 Docker 打包镜像的速度。如果这些方法都不奏效,可能需要更详细地分析构建过程中的瓶颈。


idea docker 镜像生成太慢太大问题_第2张图片

你可能感兴趣的:(【docker容器】,intellij-idea,docker,java)