Dockerfileを使用して、ソースコードをコンテナイメージにビルドし、イメージを配布およびデプロイできます。 企業は通常、Mavenリポジトリなどの自己管理リポジトリでJavaプロジェクトに基づいてコンテナイメージを構築します。 これにより、Javaプロジェクトのイメージ構築タスクは、GolangおよびPythonプロジェクトのイメージ構築タスクよりも難しくなります。 さらに、企業はDockerfilesのキャッシュメカニズムに精通していない可能性があります。 これにより、コンテナイメージのイメージ構築プロセスが遅くなります。 このトピックでは、Dockerfileを使用してJavaプロジェクトに基づいてコンテナイメージをビルドする方法と、ビルドプロセスを高速化する方法について説明します。 このトピックでは、Container Registry Enterprise Editionを使用してイメージの構築を自動化する方法についても説明します。 このトピックのシナリオには、クラウド内の自己管理GitLabコードベースと自己管理Mavenリポジトリが含まれます。
前提条件
GitLabコードベースが作成されます。
Mavenリポジトリが作成されます。
Container Registry Enterprise Editionインスタンスが作成されました。 詳細については、「Container Registry Enterprise Editionインスタンスの作成」をご参照ください。
Projects
このトピックでは、依存関係を持つ次のJavaプロジェクトを使用します。
Provider: サービスを提供するためにConsumerプロジェクトによって呼び出されます。
コアモジュール: 共通のインターフェイスを提供します。
サービスモジュール: サービスを実装します。
Consumer: プロバイダーサービスを呼び出します。
サービスモジュール: ProviderプロジェクトのCoreモジュールに依存します。 サンプルコード:
. ├── consumer │ ├── Dockerfile │ ├── consumer.iml │ ├── pom.xml │ └── service │ ├── pom.xml │ ├── src │ └── target └── provider ├── Dockerfile ├── core │ ├── pom.xml │ ├── src │ └── target ├── pom.xml ├── provider.iml └── service ├── pom.xml ├── src └── target
出力:
プロデューサアプリケーションイメージは、Providerプロジェクトに基づいて構築されます。
consumerアプリケーションイメージは、Consumerプロジェクトに基づいて作成されます。
ステップ1: 共通の依存関係をアップロードする
Javaプロジェクトをビルドする前に、Javaプロジェクトによって参照される共通の依存関係を自己管理型Mavenリポジトリにアップロードする必要があります。 この例では、Providerプロジェクトのディレクトリで次のuploadコマンドを実行します。
mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests
ステップ2: 独自のMavenベースイメージを作成する
コンテナ化された建物環境で自己管理のMavenリポジトリにアクセスするには、Mavenリポジトリの構成をMavenベースイメージに配置する必要があります。 公式のMavenイメージに基づいて、エンタープライズ独自のパブリックMavenベースイメージを作成することをお勧めします。 アプリケーションプロジェクトでMavenベースイメージを参照して、Mavenリポジトリにアクセスできます。
次のファイルをDockerfileとして保存し、Mavenリポジトリのsettings.xmlファイルと同じディレクトリにDockerfileを保存します。
FROM maven:3.8-openjdk-8 # Specifies a Maven image for the projects. In this example, a Maven image of version 3.8 is specified. ADD settings.xml /root/.m2/ # Puts the configuration of the self-managed Maven repository into the corresponding position.
次のコマンドを実行してイメージをビルドし、イメージをリモートイメージリポジトリにプッシュします。
ls Dockerfile settings.xml docker build -t demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 -f Dockerfile . Sending build context to Docker daemon 7.68kB Step 1/2 : FROM maven:3.8-openjdk-8 ---> a3f42bfde036 Step 2/2 : ADD settings.xml /root/.m2/ ---> db0d5a5192e3 Successfully built db0d5a5192e3 Successfully tagged demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 docker push demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8
ステップ3: Consumerアプリケーションイメージをビルドする (Providerプロジェクトを使用する場合は、この手順をスキップしてください)
次のコマンドを実行します。 Consumerプロジェクトの構築に必要なすべてのベースイメージをAlibaba Cloudイメージリポジトリにプッシュすることを推奨します。
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./service service/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]
ステップ4: Javaプロジェクトに基づくコンテナイメージの構築プロセスを加速する
手順3: Consumerアプリケーションイメージのビルド (Providerプロジェクトを使用する場合はこの手順をスキップ) で、イメージをビルドできます。 ただし、コードを変更してイメージの構築を繰り返すたびに、JARパッケージがプルされます。 JARパッケージキャッシュを使用しない場合、イメージは低速で構築されます。 Dockerfileには独自のキャッシュメカニズムがあります。 ソースコードを変更すると、ADDコマンドのファイルコンテンツはハッシュアルゴリズムを使用して処理され、ADDコマンドの値が変更されます。 その結果、RUNコマンドを再構築しなければならず、以前の構築結果キャッシュを使用することができない。 詳細については、「Dockerfilesの作成のベストプラクティス」をご参照ください。
イメージ構築を高速化するために、Maven依存関係をキャッシュして再利用できます。 次の操作を実行します。
プロジェクトのpom.xmlファイルをコンテナーにコピーし、依存関係をダウンロードします。 このようにして、pom.xmlファイルのみが変更されない場合、キャッシュを後続のイメージ構築で再利用できます。
プロジェクトのソースコードをコピーし、ソースコードをコンパイルします。
次のサンプルコードは、改善されたDockerfileの例を示します。 初めてJavaプロジェクトをビルドするとき、ビルドプロセスに必要な時間は43秒です。 後続のプロジェクトでは、ソースコードを変更するだけの場合、ビルドプロセスに必要な時間は7秒です。
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# To resolve dependencies in a safe way (no re-download when the source code changes)
ADD ./pom.xml pom.xml
ADD ./service/pom.xml service/pom.xml
RUN mvn install
ADD ./service service/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]
ステップ5: Container Registry Enterprise Editionを使用したイメージ構築の自動化
Container Registry Enterprise Editionは、エンタープライズレベルのサービス構築機能を提供します。 Container Registry Enterprise Editionを使用してイメージ構築を自動化することを推奨します。 詳細については、次をご参照ください: Container Registry Enterprise Editionインスタンスを使用してイメージをビルドします。
次の部分では、Container Registry Enterprise Editionインスタンスを使用してイメージを作成するときに使用できるいくつかのベストプラクティスについて説明します。
VPCモードの使用
クラウドにデプロイされた自己管理型GitLabコードベースのソースコードを、仮想プライベートクラウド (VPC) のコンテナイメージにパッケージ化することを推奨します。 このようにして、サービスをインターネットに公開する必要はありません。 詳細については、次をご参照ください: VPCにコンテナーイメージを構築します。
リポジトリ内のイメージタグを不変に設定する
オンラインタグが上書きされないように、リポジトリ内のイメージタグを不変に設定することをお勧めします。
コミットIDに基づく構築ルールの作成
イメージを作成するたびに、2つのイメージタグが生成されます。 1つのタグはコードコミットIDを使用して表されます。 画像タグはコードバージョンにマッピングされます。 他方のタグは、最新のタグを示すために最新を使用することによって表される。
ビルドをトリガーするコードをコミットします。 ビルドをトリガーするコードをコミットします。 次の図は、コードが2回コミットされた後に自動的にトリガーされる2つのビルドプロセスを示しています。 各構築プロセスで2つの画像タグが生成されます。 第2の構築プロセスは、キャッシュヒットのため、第1の構築プロセスよりも高速である。