我正在使用分层 jar 文件方法 [1] 来优化我们的 Docker 映像构建时间。我注意到从以下命令中提取的 jar 文件不会保留提取的单个 jar 文件的时间戳。
java -Djarmode=layertools -jar my-uber-jar.jar extract
如果我运行上述命令,请检查提取文件的时间戳,然后重新运行该命令并重新检查它们始终更新为当前时间的时间戳。
例子:
$ java -Djarmode=layertools -jar my-uber-jar.jar extract
$ ls -l dependencies/BOOT-INF/lib/commons-*
-rw-r--r-- 1 legacy staff 327K Oct 1 09:23 dependencies/BOOT-INF/lib/commons-codec-1.11.jar
-rw-r--r-- 1 legacy staff 204K Oct 1 09:23 dependencies/BOOT-INF/lib/commons-io-2.5.jar
-rw-r--r-- 1 legacy staff 490K Oct 1 09:23 dependencies/BOOT-INF/lib/commons-lang3-3.8.1.jar
-rw-r--r-- 1 legacy staff 60K Oct 1 09:23 dependencies/BOOT-INF/lib/commons-logging-1.2.jar
-rw-r--r-- 1 legacy staff 2.1M Oct 1 09:23 dependencies/BOOT-INF/lib/commons-math3-3.6.1.jar
...等待〜5分钟...
$ java -Djarmode=layertools -jar my-uber-jar.jar extract
$ ls -l dependencies/BOOT-INF/lib/commons-*
-rw-r--r-- 1 legacy staff 327K Oct 1 09:29 dependencies/BOOT-INF/lib/commons-codec-1.11.jar
-rw-r--r-- 1 legacy staff 204K Oct 1 09:29 dependencies/BOOT-INF/lib/commons-io-2.5.jar
-rw-r--r-- 1 legacy staff 490K Oct 1 09:29 dependencies/BOOT-INF/lib/commons-lang3-3.8.1.jar
-rw-r--r-- 1 legacy staff 60K Oct 1 09:29 dependencies/BOOT-INF/lib/commons-logging-1.2.jar
-rw-r--r-- 1 legacy staff 2.1M Oct 1 09:29 dependencies/BOOT-INF/lib/commons-math3-3.6.1.jar
这对我来说是个问题的原因是我正在尝试使用 Docker buildkit [2] 优化来减少发送到远程 Docker 守护程序的构建上下文的数量。使用分层 jar 文件方法和 Docker buildkit 背后的想法是避免将任何依赖 jar 文件发送到远程 docker 守护进程,除非它们以某种方式发生变化。Docker buildkit 似乎注意到了更改的时间戳,然后将所有文件发送到远程服务器,即使这些文件的校验和与之前的构建相同。我已经确认,如果我只是在不重新提取文件的情况下进行构建,那么很少有数据会发送到远程 Docker 守护进程。
使用分层 jar 文件可以很好地减少在 a 上发送的数据量,docker push
但我们的工作流程需要在远程服务器上构建 docker(通过 IntelliJ 的远程 docker 构建功能)
这引出了我的问题:
a) 是否可以在保留时间戳的同时提取图层?
b) 是否可以让 docker buildkit 查看校验和而不是时间戳?
[1] https://spring.io/blog/2020/08/14/creating-efficient-docker-images-with-spring-boot-2-3 [2] https://docs.docker.com/develop /develop-images/build_enhancements/