SpringBoot + Dockerレイヤードパッケージ
バックグラウンド
SpringBootは、デフォルトでorg.springframework.boot:spring-boot-maven-plugin
Mavenプラグインを使用してプロジェクトをjarパッケージにコンパイルします。デフォルトでコンパイルされたjarパッケージは全体であり、java -jar
コマンドで直接開始できます。dockerと組み合わせた後、DockerFile
またはでDocker Compose
Dockerイメージにパッケージ化できます。ただし、MavenがSpringBootプロジェクトファイルをターゲットフォルダー内の完全なjarパッケージにコンパイルするたびに、jarパッケージには独自のコードと依存するサードパーティのjarパッケージが含まれます。多くの場合、jarパッケージは100Mを超えるため、dockerパッケージと組み合わせると、docker push
完全なjarパッケージが毎回アップロードされます。最近、SpringBoot 2.3.0がリリースされました。このアップデートには、レイヤードパッケージのサポートが含まれています。SpringBootをDockerと組み合わせてレイヤードパッケージを実現する方法を見てみましょう。
デモプロジェクトウェアハウス:https://gitee.com/wxdfun/springboot-layers.git
分析
SpringBootプロジェクトをjarパッケージにコンパイルする方法とDockerの使用方法は紹介されていません。Baiduにアクセスして、今日のトピックを直接入力できます。この記事では、Dockerイメージ分析ツールを使用しますdive
。インストールと使用については、ドキュメントhttps://github.com/wagoodman/diveを参照してください。
元のSpringBootパッケージとDockerFileコンパイルイメージを見てみましょう。テスト用の簡単なデモプロジェクトを作成しましょう。
Pom構成SpringBootパッケージプラグイン
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
ルートディレクトリのDockerFileファイル
FROM openjdk:8-jre
MAINTAINER [email protected]
WORKDIR application
EXPOSE 36665
ADD ./target/*.jar ./app.jar
CMD java -jar app.jar
次に、関連するコマンドパッケージを実行します
mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:1.0.0
最初にこのDockerイメージのレイヤーを見てみましょう。それぞれ、を使用docker inspect
しdive
て確認してください。
docker inspect hc.registry.docker.com:5000/springboot-layers:1.0.0
[外部リンク画像の転送に失敗しました。ソースサイトにヒル防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-WUNntqU3-1592193616881)(https://imgb.hnhcyy.com/ctr_cloud/ doc / md / 20200615104414.jpg)]
dive hc.registry.docker.com:5000/springboot-layers:1.0.0
次に、少しJavaコードを変更し、上記の手順を繰り返して問題を確認します。
[外部リンク画像の転送に失敗しました。ソースサイトにヒル防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-1iaRTW16-1592193616883)(https://imgb.hnhcyy.com/ctr_cloud/ doc / md / 20200615105447.jpg)]
mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:1.0.1
docker inspect hc.registry.docker.com:5000/springboot-layers:1.0.1
Dockerイメージのレイヤー化ファイルの最後の部分のみが、最後のコンパイルと異なります。
dive hc.registry.docker.com:5000/springboot-layers:1.0.1
[外部リンク画像の転送に失敗しました。ソースサイトにヒル防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-aCNRsyij-1592193616885)(https://imgb.hnhcyy.com/ctr_cloud/ doc / md / 20200615105947.jpg)]
いくつかの文字を変更しただけで、dockerはまだパッケージ化時にspringbootの完全なjarパッケージをアップロードしていることがわかります。
改造
最近、springboot 2.3.0がリリースされ、springboot階層パッケージがサポートされました。新機能をdockerと組み合わせる方法を見てみましょう。2.3.0.RELEASEに依存するようにspringbootをアップグレードします。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/>
</parent>
SpringBoot-mavenプラグインでレイヤードパッケージングをサポートするための構成を追加します
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>
パッケージ分析操作を再度実行mvn clean package
すると、次のコマンドを使用して、springboot2.3.0階層パッケージとコンパイルのjarパッケージ構造を確認できます。
java -Djarmode=layertools -jar target/springboot-layers-1.0.0.jar list
layertoolsがjarパッケージの依存関係が別のフォルダーにパッケージ化されていることを認識し、元のdockerfileを変更していることがわかります。
FROM openjdk:8-jre as builder
WORKDIR application
ADD ./target/*.jar ./app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM openjdk:8-jre
MAINTAINER [email protected]
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
EXPOSE 36665
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
このdockerfileは、一時的なイメージビルドがビルダーとしてマークされ、完全なjarパッケージが一度ロードされた後、java -Djarmode=layertools -jar app.jar extract
コマンドが実行されてjarパッケージが階層パッケージディレクトリに分解され、新しいイメージが再度ビルドされ、階層ディレクトリが作成されることを意味します。リストのディレクトリ順序に従ってバッチに分割されます。Dockerイメージにロードします。
Dockerイメージを再度ビルドしますdocker build . -t hc.registry.docker.com:5000/springboot-layers:2.0.0
docker inspect hc.registry.docker.com:5000/springboot-layers:2.0.0
Dockerイメージのファイルレイヤーには、さらに多くのレベルがあることがわかります。少しJavaコードを変更して、もう一度ビルドしてみましょう。
mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:2.0.1
Dockerのイメージレベルを再度分析します
docker inspect hc.registry.docker.com:5000/springboot-layers:2.0.1
それでも最後のファイルレイヤーのみが変更されています。diveを使用して分析してください
dive hc.registry.docker.com:5000/springboot-layers:2.0.1
不思議なことが起こりました。今回のdockerの変更には、4.6kのファイル変更しかありません。2.0.0および2.0.1Dockerイメージを個別にプッシュして、これら2つの変更されたレイヤードファイルのみが再アップロードされるかどうかを確認します
思ったように、2.0.1 docker image push changeファイルは上記でマークされた唯一の4.6kファイルであり、アップロードされた階層ファイルも大幅に削減されていることがわかります。最後に、ミラーを開始して成功を確認できます。
docker run -p 36665:36665 hc.registry.docker.com:5000/springboot-layers:2.0.1
結果
階層パッケージをサポートするようにspringboot2.3.0バージョンを構成し、dockerfileファイルも対応する形式に変更した後、実際に目的の効果を得ることができます。毎回再アップロードするのは、作成したコード、サードパーティの依存関係、SpringBootの内部構成、スナップショットの依存関係のみです。これらのSpringBootは、さまざまなフォルダーにパッケージ化され、Dockerの階層特性に依存して段階的にファイルを追加します。層状包装の効果が得られます。知りたい友達はそれをしてjava -Djarmode=layertools -jar target/springboot-layers-2.0.1.jar extract
、下の図のファイルの内容を見て真実を明らかにすることができます。
SpringBootの内部構成、スナップショットの依存関係、これらのSpringBootは、さまざまなフォルダーにパッケージ化されており、Dockerの階層特性に依存しています。ファイルを段階的に追加すると、階層的なパッケージ化の効果を実現できます。知りたい友達はそれをしてjava -Djarmode=layertools -jar target/springboot-layers-2.0.1.jar extract
、下の図のファイルの内容を見て真実を明らかにすることができます。