詳解SpringBoot(2.3)應用製作Docker映象(官方方案)

zq2599發表於2020-06-08

關於《SpringBoot-2.3容器化技術》系列

《SpringBoot-2.3容器化技術》系列,旨在和大家一起學習實踐2.3版本帶來的最新容器化技術,讓我們們的Java應用更加適應容器化環境,在雲端計算時代依舊緊跟主流,保持競爭力;

全系列文章分為主題和輔助兩部分,主題部分如下:

  1. 《體驗SpringBoot(2.3)應用製作Docker映象(官方方案)》
  2. 《詳解SpringBoot(2.3)應用製作Docker映象(官方方案)》
  3. 《掌握SpringBoot-2.3的容器探針:基礎篇》
  4. 《掌握SpringBoot-2.3的容器探針:深入篇》
  5. 《掌握SpringBoot-2.3的容器探針:實戰篇》

輔助部分是一些參考資料和備忘總結,如下:

  1. 《SpringBoot-2.3映象方案為什麼要做多個layer》
  2. 《設定非root賬號不用sudo直接執行docker命令》
  3. 《開發階段,將SpringBoot應用快速部署到K8S》

本篇簡介

前文,我們們快速體驗了官方推薦的docker映象製作方案,但也產生了幾個疑問:

  1. SpringBoot-2.3版本推薦的映象構建方案和舊版本比有什麼不同?
  2. pom.xml中spring-boot-maven-plugin外掛新增的引數,到底做了什麼?
  3. Dockerfile中,java -Djarmode=layertools -jar application.jar extract這個操作啥意思?

本篇的目標就是解答上述問題,在尋找答案的過程中不斷補全知識點,提升自己;

關鍵知識點:映象layer

前文多次提到的映象layer到底是什麼,為什麼會有多層layer?有必要先把這個知識點夯實了,請參考文章《SpringBoot-2.3映象方案為什麼要做多個layer》

老版本SpringBoot的官方方案

SpringBoot-2.2.0.RELEASE版本為例,官方文件(
https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/reference/pdf/spring-boot-reference.pdf)給出的做法如下:

  1. 將SpringBoot工程編譯構建,在target目錄得到jar;
  2. 在target目錄新建dependency資料夾;
  3. 將jar解壓到dependency資料夾;
  4. 編寫Dockerfile檔案,內容如下:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.MyApplication"]
  1. 可見,官方推薦的做法是將整個jar檔案解壓,在Dockerfile中多次用COPY命令分別複製,這樣做的好處顯而易見:多個layer,如果映象的新版本中只修改了應用程式碼,那麼下載映象時只會下載/app這個layer,其他部分直接使用本地快取,這是docker映象的常規優化手段;
  2. 上述方案有個小問題:麻煩!!!
  3. 於是2.3.0.RELEASE版本做了些優化,讓事情變得簡單些;

2.3.0.RELEASE版本方案和舊版的區別

2.3.0.RELEASE版本構建Docker的步驟如下:

  1. pom.xml中的spring-boot-maven-plugin外掛增加一個配置項;
    2.編譯構建生成jar;
  2. 編寫Dockerfile,裡面用到了多階段構建(multi-stage builds),用工具從jar中提取拆分後,再多次執行COPY命令將拆分後的內容放入映象,達到多個layer的目的;

因此,2.3.0.RELEASE版本和舊版本相比有如下變化:

  1. pom.xml中多了個引數;
  2. 構建好jar後,無需自己解壓jar;
  3. Dockefile內容不一樣,舊版是手動解壓jar,再在Dockerfile分別複製,2.3.0.RELEASE是通過java命令從jar中提取出各部分內容

搞清楚了新舊版本的區別,我們們繼續研究下一個問題吧;

pom.xml中spring-boot-maven-plugin外掛新增的引數

  1. pring-boot-maven-plugin外掛新增引數如下圖所示:

在這裡插入圖片描述
2. 上述引數有啥用?我這邊編譯構建了兩次jar,第一次有上述引數,第二次沒有,將兩次生成的jar解壓後對比,發現用了上述引數後,生成的jar會多出下圖紅框中的兩個檔案:

在這裡插入圖片描述

  1. 看看layers.idx檔案的內容,如下圖:

在這裡插入圖片描述

  1. 上圖中的內容分別是什麼意思呢?官方已給出了詳細解釋,如下圖紅框:

在這裡插入圖片描述

  1. 綜上所述,layers.idx檔案是個清單,裡面記錄了所有要被複制到映象中的資訊,接下來看看如何使用layers.idx檔案,這就涉及到jar包中新增的另一個檔案:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar

spring-boot-jarmode-layertools工具

  1. 前面已經介紹過jar中除了layers.idx,還多了個檔案:spring-boot-jarmode-layertools-2.3.0.RELEASE.jar ,來看看這個檔案的用處;
  2. 進入工程的target目錄,這裡面是編譯後的jar檔案(我這裡檔名為dockerlayerdemo-0.0.1-SNAPSHOT.jar),注意此時的spring-boot-maven-plugin外掛是帶上了下圖紅框中的引數的:

在這裡插入圖片描述

  1. 執行以下命令:
java -Djarmode=layertools -jar dockerlayerdemo-0.0.1-SNAPSHOT.jar list
  1. 得到結果如下圖所示,是layers.idx檔案的內容:

在這裡插入圖片描述

  1. 來看看官方對這個layertools的解釋,list引數的作用上面我們已經體驗過了,重點是紅框中的extract引數,它的作用是從jar中提取構建映象所需的內容:

在這裡插入圖片描述

  1. 看到這裡,您是否想到了《體驗SpringBoot(2.3)應用製作Docker映象(官方方案)》中Dockerfile的內容,請看下圖的紅框和紅字,是否有種恍然大悟的感覺:jar構建生成清單layers.idx,Dockerfile中根據清單從jar提取檔案放入映象:

在這裡插入圖片描述

至此,三個問題都已經找到了答案,小結一下:

SpringBoot-2.3.0.RELEASE推薦的映象構建方案和舊版本相比有什麼不同

  1. pom.xml中的spring-boot-maven-plugin外掛增加一個配置項;
  2. 構建好jar後,舊版本要自己解壓jar,新版不需要;
  3. 新版本的jar中,多了個檔案清單layers.idx和映象檔案處理工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar
  4. 舊版的Dockefile內容:因為前面解壓好了,所有在Dockerfile裡直接複製前面解壓的內容,這裡就有個風險:前一步解壓和當前複製的檔案位置要保證一致;
  5. 新版的Dockerfile內容:使用工具spring-boot-jarmode-layertools-2.3.0.RELEASE.jar,根據的layers.idx內容從jar中提取檔案,複製到映象中;
  6. 新版的Dockerfile中,由於使用了分階段構建,因此從jar提取檔案的操作不會儲存到映象的layer中;

pom.xml中spring-boot-maven-plugin外掛新增的引數,到底做了什麼

spring-boot-maven-plugin外掛新增的引數,使得編譯構建得到jar中多了兩個檔案,如下圖所示:

在這裡插入圖片描述

Dockerfile中,java -Djarmode=layertools -jar application.jar extract這個操作啥意思

  1. java -Djarmode=layertools -jar application.jar extract的作用是從jar中提取檔案,這些檔案是docker映象的一部分;
  2. 上述操作的引數是extract,另外還有兩個引數,官方解釋它們的作用如下:

在這裡插入圖片描述

至此,問題已全部澄清,相信您對SpringBoot-2.3.0.RELEASE官方的映象構建方案也足夠了解了,最後是我根據自己的認識畫的流程圖,幫助您快速理解整個構建流程:

在這裡插入圖片描述

歡迎訪問我的GitHub

歡迎關注我的公眾號:程式設計師欣宸

在這裡插入圖片描述

https://github.com/zq2599/blog_demos

相關文章