👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料:
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

导读

在容器化实践中部署spring boot应用普遍采用基础java镜像再添加jar包层来构建应用镜像制品。随着公司业务大量上云,每个变更日上传到云上镜像日渐增多,导致本地机房到云上带宽压力倍增。为解决镜像上传问题,调研了相关技术栈决定采用spring boot 2.3新增的镜像分层构建功能。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

基础环境

  • spring boot version >= 2.3
  • java oracle jdk 8u201
  • docker version 20.10.13
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

基于传统单个jar包构建模式

基础Dockerfile

以下是我们基于基础镜像构建spring boot镜像制品的Dockerfile,采用了比较传统的COPY jar包。相信这也是大家普遍采用的模式。Dockefile如下,该Dockerfile存在一个坑,会在下边阐述。
FROM registry.xxx.com/base/oracle-jdk:8u201

ENV TZ=Asia/Shanghai

ENV LC_ALL en_US.utf8

WORKDIR /app

ADD ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

ADD ./entrypoint.sh /app/bin/entrypoint.sh

ENTRYPOINT  
exec
 bash /app/bin/entrypoint.sh

RUN ln -s /app/logs /app/
log
 && chown 1001.1001 -R /app

Base镜像信息

我们base镜像主要分三层添加了相关常用的工具如telnet netstat等以及安全修复
docker image inspect registry.xxx.com/base/oracle-jdk:8u201

分层信息:
"RootFS"
: {

"Type"
"layers"
,

"Layers"
: [

"sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02"
,

"sha256:2105884a1756425b2188084cc1738d6a6b13293773af56f6727af1be979858ed"
,

"sha256:c33745b350978d855171c996779055195b09e227844b7a03a1d795aee803dbb9"
    ]

}

Base镜像大小 622MB

镜像大小 622MB 不算太小,对比友商有些基础镜像竟然1-2G😂 简直有点离谱。
registry.xxx.com/base/oracle-jdk  8u201 1869b73a8999  2 years ago  622MB

Base镜像history信息

从构建历史可以看出占用空间主要分为三层分别是
  • centos 7 基础镜像层
  • yum install 层
  • jdk 层
docker image  
history
 registry.xxx.com/base/oracle-jdk:8u201

IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT

1869b73a8999   2 years ago   /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago   /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago   /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago   /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago   /bin/sh -c 
#(nop)  LABEL maintainer=…           0B
<missing>      2 years ago   /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago   /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago   /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB

传统构建方式

docker build -t registry.xxx.com/layer/build:old .

Sending build context to Docker daemon  67.45MB

Step 1/8 : FROM registry.xxx.com/base/oracle-jdk:8u201

 ---> 1869b73a8999

Step 2/8 : ENV TZ=Asia/Shanghai

 ---> Running 
in
 a67423d7246b

Removing intermediate container a67423d7246b

 ---> 9304102c278e

Step 3/8 : ENV LC_ALL en_US.utf8

 ---> Running 
in
 05bf14c10efd

Removing intermediate container 05bf14c10efd

 ---> 63fb6c823893

Step 4/8 : WORKDIR /app

 ---> Running 
in
 095764328d18

Removing intermediate container 095764328d18

 ---> c057ab4a7d18

Step 5/8 : ADD ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

 ---> 08928447fafa

Step 6/8 : ADD ./entrypoint.sh /app/bin/entrypoint.sh

 ---> 0902efa62157

Step 7/8 : ENTRYPOINT  
exec
 bash /app/bin/entrypoint.sh

 ---> Running 
in
 dc0eb814cfff

Removing intermediate container dc0eb814cfff

 ---> 20679a170252

Step 8/8 : RUN ln -s /app/logs /app/
log
 && chown 1001.1001 -R /app

 ---> Running 
in
 34159dca7464

Removing intermediate container 34159dca7464

 ---> b6043465c072

Successfully built b6043465c072

Successfully tagged registry.xxx.com/layer/build:old

构建后镜像大小 为基础镜像大小 622MB + 2*65M <= 757MB

构建后比我们预期的 jar包加基础镜像所占用的空间大😢 why?
#jar包大小
ls -lh xxx-1.0.0.jar

-rw------- 1 root root 65M Aug 16 10:33 xxx-1.0.0.jar


#镜像大小
docker image ls |grep registry.xxx.com/layer/build

registry.xxx.com/layer/build                 old          b6043465c072   59 seconds ago   757MB

成品构建history信息

查看构建成品的镜像层发现竟然有两层一样大小,也会被推送了两遍。🥲离大谱。通过分析Dockerfile是因为RUN ln -s /app/logs /app/log && chown 1001.1001 -R /app 导致的。为保证镜像安全,生产环境运行统一采用了1001账号运行。为了保证1001对workdir有绝对的读写权限。对目录递归授权导致文件属性发生改变。
在构建时认为文件发生变化产生一样大小的两层导致的。(这还是我自己当时优化引入的屎山😊)具体原因我也不太清楚docker构建时如何判定文件发生变化,我原本以为是基于MD5码。实际上在对文件属主属组改变时MD5码是不对变的。有知道的大神可以在评论区留言交流。
docker image  
history
  registry.xxx.com/layer/build:old

IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT

b6043465c072   6 minutes ago   /bin/sh -c ln -s /app/logs /app/
log
 && chown…   67.4MB

20679a170252   6 minutes ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["/bin/sh" "-c…   0B
0902efa62157   6 minutes ago   /bin/sh -c 
#(nop) ADD file:9ac19caf793524884…   128B
08928447fafa   6 minutes ago   /bin/sh -c 
#(nop) ADD file:c7624c195e7c047ee…   67.4MB
c057ab4a7d18   6 minutes ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
63fb6c823893   6 minutes ago   /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
9304102c278e   6 minutes ago   /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
1869b73a8999   2 years ago     /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago     /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago     /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago     /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago     /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
<missing>      2 years ago     /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago     /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago     /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB

#镜像也推送了两层一样大小
[root@localhost old-nochown]
# docker push registry.xxx.com/layer/build:old
The push refers to repository [registry.xxx.com/layer/build]

bb35157fcb0b: Pushing [=============>                                     ]  18.35MB/67.45MB

3c0641004863: Pushed

6ed0abaff975: Pushing [=====================>                             ]  28.38MB/67.45MB

aa0794231b2c: Pushed

c33745b35097: Layer already exists

2105884a1756: Layer already exists

174f56854903: Layer already exists

优化Dockerfile

原因知道了。优化思路是先创建目录并递归授权。同时构建出来的jar的权限可以通过COPY 指定1001属主属组。
FROM registry.xxx.com/base/oracle-jdk:8u201

ENV TZ=Asia/Shanghai

ENV LC_ALL en_US.utf8

RUN mkdir -pv /app/{bin,lib,logs} && ln -s /app/logs /app/
log
 && chown 1001:1001 -R /app

WORKDIR /app

COPY  --chown=1001:1001 ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

COPY  --chown=1001:1001 ./entrypoint.sh /app/bin/entrypoint.sh

ENTRYPOINT  
exec
 bash /app/bin/entrypoint.sh

优化后的镜像只有COPY这一层的jar包了。
docker image 
history
 registry.xxx.com/layer/build:old-mkdir

IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT

b9fc3a8a97f2   29 hours ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["/bin/sh" "-c…   0B
c823448f9582   29 hours ago   /bin/sh -c 
#(nop) COPY --chown=1001:1001file…   128B
9a997f3962bf   29 hours ago   /bin/sh -c 
#(nop) COPY --chown=1001:1001file…   67.4MB
f272c4e64f87   29 hours ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
1a526d3df7c2   29 hours ago   /bin/sh -c mkdir -pv /app/{bin,lib,logs} && …   9B

63fb6c823893   30 hours ago   /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
9304102c278e   30 hours ago   /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
1869b73a8999   2 years ago    /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago    /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago    /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago    /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB

基于spring boot 分层构建方式

探索基于分层构建原理

直接上手官方文档的demo 把官方文档demo的多阶段构建拆分一下。
cat Dockerfile

FROM registry.xxx.com/base/oracle-jdk:8u201 as builder

WORKDIR /app

COPY --chown=1001:1001 ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

RUN java -Djarmode=layertools -jar /app/lib/xxx-1.0.0.jar extract

一阶段实际就是将jar解压按照spring boot layers.idx文件中的分层方式将依赖和业务代码分层。
"dependencies"
:

  - BOOT-INF/lib/library1.jar

  - BOOT-INF/lib/library2.jar

"spring-boot-loader"
:

  - org/springframework/boot/loader/JarLauncher.class

  - org/springframework/boot/loader/jar/JarEntry.class

"snapshot-dependencies"
:

  - BOOT-INF/lib/library3-SNAPSHOT.jar

"application"
:

  - META-INF/MANIFEST.MF

  - BOOT-INF/classes/a/b/C.class

进入到容器中可以看到被解压为4个目录:
[root@b762a63589c1 app]
# ls
application  dependencies  lib  logs  snapshot-dependencies  spring-boot-loader

存储占用如下:其中不出意外dependencies也就是依赖库占用是最大的 业务代码只有可怜的304K🤔。
[root@29d87aaf64b9 app]
# du -lh  --max-depth=1
304K    ./application

65M     ./dependencies

0       ./logs

20K     ./snapshot-dependencies

420K    ./spring-boot-loader

65M     ./lib

130M    .

基于分层构建构建制品镜像

在官方的demo上修改得到完整的Dockerfile。其中优化了entrypoint脚本,采用分层构建后启动应用不能采用传统的java $JAVA_OPTS -jar xxx.jar这方式启动应用。要使用java org.springframework.boot.loader.JarLauncher启动应用因此jvm参数需要通过脚本接受容器的环境变量来传入。
FROM registry.xxx.com/base/oracle-jdk:8u201 as builder

WORKDIR /app

COPY --chown=1001:1001 ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

RUN java -Djarmode=layertools -jar /app/lib/xxx-1.0.0.jar extract


FROM registry.xxx.com/base/oracle-jdk:8u201

ENV TZ=Asia/Shanghai

ENV LC_ALL en_US.utf8

RUN mkdir -pv /app/logs && ln -s /app/logs /app/
log
 && chown 1001:1001 -R /app

WORKDIR /app

COPY --chown=1001:1001 --from=builder /app/dependencies/ ./

COPY --chown=1001:1001 --from=builder /app/spring-boot-loader/ ./

COPY --chown=1001:1001 --from=builder /app/snapshot-dependencies/ ./

COPY --chown=1001:1001 --from=builder /app/application/ ./

CMD [
"exec"
]

ENTRYPOINT [
"bash"
,
"/app/entrypoint.sh"
]

entrypoint.sh脚本使用exec将java作为容器1号进程,避免无法接受linux 信号导致java进程无法正常退出。
#!/bin/bash
if
 [ -f /opt/cm/before.sh ]; 
then
source
 /opt/cm/before.sh;

fi
exec
 java 
$JAVA_OPTS
 org.springframework.boot.loader.JarLauncher

构建镜像
[root@localhost new]
# docker build -t registry.xxx.com/layer/build:new .
Sending build context to Docker daemon  67.45MB

Step 1/14 : FROM registry.xxx.com/base/oracle-jdk:8u201 as builder

 ---> 1869b73a8999

Step 2/14 : WORKDIR /app

 ---> Using cache

 ---> 6973e49f31fa

Step 3/14 : COPY --chown=1001:1001 ./xxx-1.0.0.jar /app/lib/xxx-1.0.0.jar

 ---> Using cache

 ---> c5a17d5969ea

Step 4/14 : RUN java -Djarmode=layertools -jar /app/lib/xxx-1.0.0.jar extract

 ---> Using cache

 ---> 911074c3ef21

Step 5/14 : FROM registry.xxx.com/base/oracle-jdk:8u201

 ---> 1869b73a8999

Step 6/14 : ENV TZ=Asia/Shanghai

 ---> Using cache

 ---> 9304102c278e

Step 7/14 : ENV LC_ALL en_US.utf8

 ---> Using cache

 ---> 63fb6c823893

Step 8/14 : RUN mkdir -pv /app/logs && ln -s /app/logs /app/
log
 && chown 1001:1001 -R /app

 ---> Running 
in
 9cac9cb86507

mkdir: created directory ‘/app’

mkdir: created directory ‘/app/logs’

Removing intermediate container 9cac9cb86507

 ---> 858e77315e6b

Step 9/14 : WORKDIR /app

 ---> Running 
in
 81c7173692fc

Removing intermediate container 81c7173692fc

 ---> 5c19ddda3114

Step 10/14 : COPY --chown=1001:1001 --from=builder /app/dependencies/ ./

 ---> 078e3f4a199c

Step 11/14 : COPY --chown=1001:1001 --from=builder /app/spring-boot-loader/ ./

 ---> 1542209ccc8b

Step 12/14 : COPY --chown=1001:1001 --from=builder /app/snapshot-dependencies/ ./

 ---> 75a9584e0952

Step 13/14 : COPY --chown=1001:1001 --from=builder /app/application/ ./

 ---> 555270edceea

Step 14/14 : ENTRYPOINT [
"java"
"org.springframework.boot.loader.JarLauncher"
]

 ---> Running 
in
 fe99278683a2

Removing intermediate container fe99278683a2

 ---> 2cce0deab7e2

Successfully built 2cce0deab7e2

Successfully tagged registry.xxx.com/layer/build:new

查看分层详情,可以看到jar被拆分成4层分别由copy指令创建。
[root@localhost ~]
# docker image history registry.xxx.com/layer/build:new
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT

2cce0deab7e2   28 hours ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["java" "org.s…   0B
555270edceea   28 hours ago   /bin/sh -c 
#(nop) COPY dir:2f5975d11563ae449…   248kB
75a9584e0952   28 hours ago   /bin/sh -c 
#(nop) COPY dir:a3bb0870001a0ef25…   18.5kB
1542209ccc8b   28 hours ago   /bin/sh -c 
#(nop) COPY dir:16d00ea1f180914e2…   252kB
078e3f4a199c   28 hours ago   /bin/sh -c 
#(nop) COPY dir:1d3190ed598b634a5…   67.1MB
5c19ddda3114   28 hours ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
858e77315e6b   28 hours ago   /bin/sh -c mkdir -pv /app/logs && ln -s /app…   9B

63fb6c823893   30 hours ago   /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
9304102c278e   30 hours ago   /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
1869b73a8999   2 years ago    /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago    /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago    /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago    /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago    /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago    /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB
对比发现jar包被拆分了。
[root@localhost new]
# diff old.info  new.info
1,16c1,18

< IMAGE          CREATED             CREATED BY                                      SIZE      COMMENT

< b9fc3a8a97f2   About an hour ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["/bin/sh" "-c…   0B
< c823448f9582   About an hour ago   /bin/sh -c 
#(nop) COPY --chown=1001:1001file…   128B
< 9a997f3962bf   About an hour ago   /bin/sh -c 
#(nop) COPY --chown=1001:1001file…   67.4MB
< f272c4e64f87   About an hour ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
< 1a526d3df7c2   About an hour ago   /bin/sh -c mkdir -pv /app/{bin,lib,logs} && …   9B

< 63fb6c823893   2 hours ago         /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
< 9304102c278e   2 hours ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
< 1869b73a8999   2 years ago         /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

< <missing>      2 years ago         /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
< <missing>      2 years ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
< <missing>      2 years ago         /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

< <missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
< <missing>      2 years ago         /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
< <missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
< <missing>      2 years ago         /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB
---

> IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT

> 2cce0deab7e2   8 minutes ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["java" "org.s…   0B
> 555270edceea   8 minutes ago   /bin/sh -c 
#(nop) COPY dir:2f5975d11563ae449…   248kB
> 75a9584e0952   8 minutes ago   /bin/sh -c 
#(nop) COPY dir:a3bb0870001a0ef25…   18.5kB
> 1542209ccc8b   8 minutes ago   /bin/sh -c 
#(nop) COPY dir:16d00ea1f180914e2…   252kB
> 078e3f4a199c   8 minutes ago   /bin/sh -c 
#(nop) COPY dir:1d3190ed598b634a5…   67.1MB
> 5c19ddda3114   8 minutes ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
> 858e77315e6b   8 minutes ago   /bin/sh -c mkdir -pv /app/logs && ln -s /app…   9B

> 63fb6c823893   2 hours ago     /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
> 9304102c278e   2 hours ago     /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
> 1869b73a8999   2 years ago     /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

> <missing>      2 years ago     /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
> <missing>      2 years ago     /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
> <missing>      2 years ago     /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

> <missing>      2 years ago     /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
> <missing>      2 years ago     /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
> <missing>      2 years ago     /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
> <missing>      2 years ago     /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB
推送到仓库
[root@localhost new]
# docker push registry.xxx.com/layer/build:new
The push refers to repository [registry.xxx.com/layer/build]

e5409ea62302: Pushed

7167dfa406ea: Pushed

cf7e94a2dc11: Pushed

8e261e1bae2c: Pushed

770c31a84800: Pushed

c33745b35097: Layer already exists

2105884a1756: Layer already exists

174f56854903: Layer already exists

new: digest: sha256:faef10681394c01d1c2973ed10c7c33e7289eec25f22c90d085f6eef96ce3bff size: 2001

验证模拟开发推送代码更新镜像

开发摸了一天🐟终于开发出新版本
[root@localhost new]
# md5sum  bc-1.0.1.jar  bc-1.0.0.jar
3792d3178a4e07708052b7effa9b12f8  xxx-1.0.1.jar

8ee570b94977668631355cb49c5d7cf1  xxx-1.0.0.jar

构建新版本,构建过程阶段二中使用了cache 仅更新了 application层
[root@localhost new]
# docker image build -t  registry.xxx.com/layer/build:new-1.0.1 .
Sending build context to Docker daemon  134.9MB

Step 1/16 : FROM registry.xxx.com/base/oracle-jdk:8u201 as builder

 ---> 1869b73a8999

Step 2/16 : WORKDIR /app

 ---> Using cache

 ---> 6973e49f31fa

Step 3/16 : COPY --chown=1001:1001 ./xxx-1.0.1.jar /app/lib/xxx-1.0.1.jar

 ---> b219210fd8ab

Step 4/16 : RUN java -Djarmode=layertools -jar /app/lib/xxx-1.0.1.jar extract

 ---> Running 
in
 d099c10b653c

Removing intermediate container d099c10b653c

 ---> 66a8593b0291

Step 5/16 : FROM registry.xxx.com/base/oracle-jdk:8u201

 ---> 1869b73a8999

Step 6/16 : ENV TZ=Asia/Shanghai

 ---> Using cache

 ---> 9304102c278e

Step 7/16 : ENV LC_ALL en_US.utf8

 ---> Using cache

 ---> 63fb6c823893

Step 8/16 : RUN mkdir -pv /app/logs && ln -s /app/logs /app/
log
 && chown 1001:1001 -R /app

 ---> Using cache

 ---> 858e77315e6b

Step 9/16 : WORKDIR /app

 ---> Using cache

 ---> 5c19ddda3114

 Step 10/16 : COPY --chown=1001:1001 ./entrypoint.sh /app/entrypoint.sh

 ---> Using cache

 ---> c47b74bb8cf9

Step 11/16 : COPY --chown=1001:1001 --from=builder /app/dependencies/ ./

 ---> Using cache

 ---> 078e3f4a199c

Step 12/16 : COPY --chown=1001:1001 --from=builder /app/spring-boot-loader/ ./

 ---> Using cache

 ---> 1542209ccc8b

Step 13/16 : COPY --chown=1001:1001 --from=builder /app/snapshot-dependencies/ ./

 ---> Using cache

 ---> 75a9584e0952

Step 14/16 : COPY --chown=1001:1001 --from=builder /app/application/ ./

 ---> 0f138b106caf

Step 15/16 : CMD [
"exec"
]

 ---> Using cache

 ---> a1170ae7a20e

Step 16/16 : ENTRYPOINT [
"bash"
,
"/app/entrypoint.sh"
]

 ---> Using cache

 ---> 5a6bb7613fc8

Successfully built 5a6bb7613fc8

Successfully tagged registry.xxx.com/layer/build:new-1.0.1

推送到仓库可以看到仅推送了application层 只有300K
docker push registry.xxx.com/layer/build:new-1.0.1

The push refers to repository [registry.xxx.com/layer/build]

c33a5c6456bd: Pushed

7167dfa406ea: Layer already exists

cf7e94a2dc11: Layer already exists

8e261e1bae2c: Layer already exists

770c31a84800: Layer already exists

c33745b35097: Layer already exists

2105884a1756: Layer already exists

174f56854903: Layer already exists

new-1.0.1: digest: sha256:53647bb45f0f0bb5bb8d56f14cd40deb22f0d5e4fce1200fed1c225a516dddb5 size: 2001

验证镜像

[root@localhost new]
# docker run -it --rm -u 1001:1001  -e JAVA_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintCommandLineFlags"  registry.xxx.com/layer/build:new-1.0.1
可以看到打印出了堆栈信息(容器默认是不开启的)应用成功启动😋
[root@localhost ~]
# docker run -it --rm -u 1001:1001  -e JAVA_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintCommandLineFlags"  registry.xxx.com/layer/build:new-1.0.1
-XX:InitialHeapSize=130478208 -XX:MaxHeapSize=2087651328 -XX:+PrintCommandLineFlags -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC

{Heap before GC invocations=1 (full 0):

 PSYoungGen      total 37888K, used 32768K [0x00000000d6800000, 0x00000000d9200000, 0x0000000100000000)

  eden space 32768K, 100% used [0x00000000d6800000,0x00000000d8800000,0x00000000d8800000)

  from space 5120K, 0% used [0x00000000d8d00000,0x00000000d8d00000,0x00000000d9200000)

  to   space 5120K, 0% used [0x00000000d8800000,0x00000000d8800000,0x00000000d8d00000)

 ParOldGen       total 86016K, used 0K [0x0000000083800000, 0x0000000088c00000, 0x00000000d6800000)


  eden space 32768K, 0% used [0x00000000d6800000,0x00000000d6800000,0x00000000d8800000)

  from space 5120K, 72% used [0x00000000d8800000,0x00000000d8ba1748,0x00000000d8d00000)

  to   space 5120K, 0% used [0x00000000dad00000,0x00000000dad00000,0x00000000db200000)

 ParOldGen       total 86016K, used 8K [0x0000000083800000, 0x0000000088c00000, 0x00000000d6800000)

  object space 86016K, 0% used [0x0000000083800000,0x0000000083802000,0x0000000088c00000)

 Metaspace       used 6799K, capacity 7074K, committed 7168K, reserved 1056768K

  class space    used 820K, capacity 935K, committed 1024K, reserved 1048576K

}

...

2023-08-17 20:50:42.253  INFO 1 --- [           main] org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver.<init>(EndpointLinksResolver.java:58) - [] : Exposing 1 endpoint(s) beneath base path 
'/actuator'
2023-08-17 20:50:42.315  INFO 1 --- [           main] org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - [] : Starting ProtocolHandler [
"http-nio-8082"
]

2023-08-17 20:50:42.349  INFO 1 --- [           main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:220) - [] : Tomcat started on port(s): 8082 (http) with context path 
'/xxx'
2023-08-17 20:50:42.376  INFO 1 --- [           main] org.springframework.boot.StartupInfoLogger.logStarted(StartupInfoLogger.java:61) - [] : Started Application 
in
 11.242 seconds (JVM running 
for
 12.553)

对比两个版本可以发现只有application成hash值不一样 代码量增加了253kB-248kB=5KB
[root@localhost new]
# docker image history  registry.xxx.com/layer/build:new
IMAGE          CREATED             CREATED BY                                      SIZE      COMMENT

2cce0deab7e2   About an hour ago   /bin/sh -c 
#(nop)  ENTRYPOINT ["java" "org.s…   0B
555270edceea   About an hour ago   /bin/sh -c 
#(nop) COPY dir:2f5975d11563ae449…   248kB
75a9584e0952   About an hour ago   /bin/sh -c 
#(nop) COPY dir:a3bb0870001a0ef25…   18.5kB
1542209ccc8b   About an hour ago   /bin/sh -c 
#(nop) COPY dir:16d00ea1f180914e2…   252kB
078e3f4a199c   About an hour ago   /bin/sh -c 
#(nop) COPY dir:1d3190ed598b634a5…   67.1MB
5c19ddda3114   About an hour ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
858e77315e6b   About an hour ago   /bin/sh -c mkdir -pv /app/logs && ln -s /app…   9B

63fb6c823893   3 hours ago         /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
9304102c278e   3 hours ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
1869b73a8999   2 years ago         /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago         /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago         /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB
[root@localhost new]
# docker image history  registry.xxx.com/layer/build:new-1.0.1
IMAGE          CREATED             CREATED BY                                      SIZE      COMMENT

76aa6233354a   40 minutes ago      /bin/sh -c 
#(nop)  ENTRYPOINT ["java" "org.s…   0B
0f138b106caf   40 minutes ago      /bin/sh -c 
#(nop) COPY dir:4d21cc5ce0d92794b…   253kB
75a9584e0952   About an hour ago   /bin/sh -c 
#(nop) COPY dir:a3bb0870001a0ef25…   18.5kB
1542209ccc8b   About an hour ago   /bin/sh -c 
#(nop) COPY dir:16d00ea1f180914e2…   252kB
078e3f4a199c   About an hour ago   /bin/sh -c 
#(nop) COPY dir:1d3190ed598b634a5…   67.1MB
5c19ddda3114   About an hour ago   /bin/sh -c 
#(nop) WORKDIR /app                  0B
858e77315e6b   About an hour ago   /bin/sh -c mkdir -pv /app/logs && ln -s /app…   9B

63fb6c823893   3 hours ago         /bin/sh -c 
#(nop)  ENV LC_ALL=en_US.utf8        0B
9304102c278e   3 hours ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai         0B
1869b73a8999   2 years ago         /bin/sh -c 
set
 -ex;   
cd
 /tmp;   curl -fsSLO…   302MB

<missing>      2 years ago         /bin/sh -c 
#(nop)  ENV JAVA_VERSION=8 JAVA_U…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  ENV TZ=Asia/Shanghai LANG…   0B
<missing>      2 years ago         /bin/sh -c 
set
 -ex;   yum update -y;   yum i…   116MB

<missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL maintainer=currycan…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  CMD ["/bin/bash"]            0B
<missing>      2 years ago         /bin/sh -c 
#(nop)  LABEL org.label-schema.sc…   0B
<missing>      2 years ago         /bin/sh -c 
#(nop) ADD file:b3ebbe8bd304723d4…   204MB
上述对开发没有恶意,大家都是辛苦勤劳上进的打工人。 哈哈哈又是摸🐟的一天 ---Author Logn
引用:[spring boot官方文档](Container Images (spring.io))

欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,长按”或“扫描”下方二维码噢
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
继续阅读
阅读原文