Slim-Docker-Image
导读
在容器化实践中部署spring boot应用普遍采用基础java镜像再添加jar包层来构建应用镜像制品。随着公司业务大量上云,每个变更日上传到云上镜像日渐增多,导致本地机房到云上带宽压力倍增。为解决镜像上传问题,调研了相关技术栈决定采用spring boot 2.3新增的镜像分层构建功能。
基础环境
- spring boot version >= 2.3
- java oracle jdk 8u201
- docker version 20.10.13
基于传统单个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