Archive for 5月, 2020
Java 開発者のための Docker Multi Stage Build の活用方法
Java 開発者のために Docker Multi Stage Build を活用した本番用イメージの作成方法と、監視やデバッグが可能な検証用イメージの同時作成方法についてビデオにまとめました。どうぞご覧ください。
下記のような Multi Stage Build に対応した Dockerfile を作成します。(動画中は少し Dockerfile の書き方が変わっていますが、基本的には下記と同じです。)
# syntax = docker/dockerfile:1.0-experimental ############################################### # Create Runtime Bases Image ############################################### FROM mcr.microsoft.com/java/jre:11u6-zulu-alpine as base RUN apk update \ && apk add tzdata \ && rm -rf /var/cache/apk/* ENV LANG ja_JP.UTF-8 ENV LANGUAGE ja_JP ENV LC_ALL ja_JP.UTF-8 ENV TZ='Asia/Tokyo' ENV APP_HOME /home/java RUN addgroup -g 2000 -S java && adduser -u 2000 -S java -G java USER java WORKDIR $APP_HOME ############################################### # Build Source Code ############################################### FROM maven:3.6.3-jdk-11-slim as BUILD #FROM mcr.microsoft.com/java/maven: as BUILD WORKDIR /build COPY pom.xml . COPY src/ /build/src/ ## Maven のローカル・レポジトリをキャッシュ RUN --mount=type=cache,target=/root/.m2 \ mvn clean package ############################################### # Create Final Image ############################################### FROM base as final COPY --from=BUILD /build/target/sample-java-app-0.0.1-SNAPSHOT.jar /home/java/app.jar ENTRYPOINT ["java", "-jar", "/home/java/app.jar"] EXPOSE 8080 ############################################### # Create Debuggable Monitorable Image ############################################### FROM base as debug COPY --from=BUILD /build/target/sample-java-app-0.0.1-SNAPSHOT.jar /home/java/app.jar ENTRYPOINT ["java", "-Xdebug", "-Xrunjdwp:server=y,transport=dt_socket,address=*:5050,suspend=n", "-Dcom.sun.management.jmxremote.local.only=false", "-Djava.rmi.server.hostname=127.0.0.1", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=18686", "-Dcom.sun.management.jmxremote.rmi.port=18686", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false", "-jar", "/home/java/app.jar"] EXPOSE 8080 5050 18686
上記の Dockerfile を元にイメージを作成する際、それぞれ下記のようにターゲットを指定してビルドを行ってください。
本番用イメージの作成 (–target=final)
$ docker build -t tyoshio2002/spring-sample:1.0 . --target=final $ docker run -p 8080:8080 -it tyoshio2002/spring-sample:1.0
検証環境イメージの作成と起動 (–target=debug)
$ docker build -t tyoshio2002/spring-sample-debug:1.0 . --target=debug $ docker run -p 8080:8080 -p 5050:5050 -p 18686:18686 -it tyoshio2002/spring-sample-debug:1.0
その他の特記事項
上記の Dockerfile は先頭行に # syntax = docker/dockerfile:1.0-experimental と記載しています。これを記述すると Docker の Exprimental の機能 (BuildKit) が利用できるようになります。これによりビルド処理を並列で実行できるようになるほか、Dockerfile 中の下記の行のように、Multi-stage Build で Maven のローカル・レポジトリをキャッシュできるようになります。
RUN --mount=type=cache,target=/root/.m2 \ mvn clean package
より詳しく説明すると、今まではマルチステージ・ビルド中では、Maven のローカル・レポジトリをキャッシュできなかったため、ビルドの度に毎回大量の依存ライブラリをパブリック・レポジトリからダウンロードしなければなりませんでしたが、この–mount=type=cacheで毎回のダウンロードは不要になります。
こうした Docker の新しい機能もどうぞご活用ください。
Deploying Java EE apps to Azure: Part 1
この記事は Deploying Java EE apps to Azure: Part 1 の記事の日本語翻訳版です。
クラウド環境用に Java アプリケーションを開発し展開するためには下記のような様々な選択肢があります。
- IaaS(Infrastructure-as-a-Service)
- PaaS(Platform-as-a-Service)
- CaaS(Containers-as-a-Service)
- Kubernetes
- サーバーレス
- その他
上記は、いずれか一つだけを選択して使用するというよりも、それぞれに「長所と短所」があるため、利用者のニーズに応じて適材適所で組み合わせて利用することが必要です。最終的にはビジネス要件に従いどれを使用するかを決定してください。利用者にとって「選択肢」が複数あることはとても良いことです。
ここでは、Azure 上で Java EE アプリケーションを実行するための選択肢をいくつかご紹介します。
はじめに、従来のオンプレミス環境で実施していた方法と同じ手法をご紹介します。まず Microsoft Azure 上に仮想マシンを構築し、その上にアプリケーション・サーバをインストールします。そして Java EE アプリケーションをアプリケーション・サーバにデプロイします。アプリケーションはバックエンドのデータベースに接続をしますが、ここでは Azure Database for PostgreSQL をバックエンドのデータベース・サーバとして利用します。この構成は Java EE アプリケーションの構築・配備において最も典型的な構成で、本質的には IaaS(Azure VM)とPaaS(マネージドPostgreSQL on Azure)を組み合わせた構成です。
コンテナーやKubernetesなどの他の構成については、今後の投稿で取り上げます
本エントリで使用するアプリケーションのサンプルは、JAX-RS、EJB、CDI、JPA、JSF、Bean Validation など Java EE 8 の仕様に準拠した 基本的な3階層アプリケーションです。 今回 IaaS で Payara Server を構成し、バックエンドの PostgreSQL に対して接続をします。
チュートリアルは、下記の手順にしたがい行います。
- Azure 上に仮想マシンと Postgres を構築
- 仮想マシン上に Payara Server をインストール
- Java EEアプリケーションを配備
- アプリケーションの動作確認
このチュートリアルで使用するアプリケーションは一部を除いて、Reza Rahman が作成したこのプロジェクトを利用します。
前提条件
チュートリアルを実行するには、Microsoft Azure アカウントと Azure CLI が必要です。
Microsoft Azureアカウントをお持ちでない場合は、無料アカウントにサインアップしてください! Azure CLIは、Azureリソースを管理するためのクロスプラットフォームのコマンドラインエクスペリエンスです。こちらの手順に従ってインストールしてください。
最初に
Azure CLIを使用して、チュートリアルで使用する Azure のサブスクリプション ID を設定します。
AzureサブスクリプションIDを設定するには下記のコマンドを実行してください。
export AZURE_SUBSCRIPTION_ID=[to be filled] az account set --subscription $AZURE_SUBSCRIPTION_ID
次に、このチュートリアルで作成するサービス(リソース)を含むリソース・グループを作成します。
リソースグループは、Azure 上で構築する関連リソースをまとめて管理する論理的なコンテナー(ディレクトリ)のようなものです。
リソースグループを作成するために、下記のコマンドを実行してください。
export AZURE_RESOURCE_GROUP_NAME=[to be filled] export AZURE_LOCATION=[to be filled] az group create --name $AZURE_RESOURCE_GROUP_NAME ¥ --location $AZURE_LOCATION
Azure 上に PostgreSQL のインストール
Azure Database for PostgreSQL はオープンソースの Postgres データベースを利用した完全マネージドなリレーショナル・データベースサービスです。 単一サーバーもしくは、ハイパースケール(Citus)なクラスターのいずれかを選択し構築出来ます。
このチュートリアルでは、単一サーバーのオプションを選択して構築します。
Azure 上に Postgres Server のインスタンスを作成するには、az postgres server create コマンドを使用します。 まずサーバ名、管理ユーザーやパスワードなどを設定します。
export AZURE_POSTGRES_SERVER_NAME=[to be filled] export AZURE_POSTGRES_ADMIN_USER=[to be filled] export AZURE_POSTGRES_ADMIN_PASSWORD=[to be filled] export SKU=B_Gen5_1 export STORAGE=5120
ストレージとSKU で指定可能なオプションについては、こちらのドキュメントをご参照ください
下記のコマンドを実行してデータベース・インスタンスを作成します。
az postgres server create ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --name $AZURE_POSTGRES_SERVER_NAME ¥ --location $AZURE_LOCATION ¥ --admin-user $AZURE_POSTGRES_ADMIN_USER ¥ --admin-password $AZURE_POSTGRES_ADMIN_PASSWORD ¥ --storage-size $STORAGE ¥ --sku-name $SKU
コマンド実行後、構築完了まで数分かかります。しばらくお待ちください。
作成した Postgres データベースの詳細を確認するには az postgres server show コマンドを実行します。
az postgres server show ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --name $AZURE_POSTGRES_SERVER_NAME
コマンドを実行すると、JSON が表示されます。のちほど、Postgres インスタンスに接続するので、fullyQualifiedDomainName の値を書き留めてください。
[AZURE_POSTGRES_DB_NAME].postgres.database.azure.com
のように表示されています。
Azure 上に仮想マシンをインストール
Azure 上に 仮想マシン(UbuntuベースのLinux VM)を構築し、JavaEE の仕様に準拠した Payara アプリケーションサーバーをインストールします。
Linux VM の構築に必要な情報を設定します。
export AZURE_VM_NAME=[to be filled] export AZURE_VM_USER=[to be filled] export AZURE_VM_PASSWORD=[to be filled] export VM_IMAGE=UbuntuLTS
az vm create コマンドを実行して Linux VM のインスタンスを構築します
az vm create ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --name $AZURE_VM_NAME ¥ --image $VM_IMAGE ¥ --admin-username $AZURE_VM_USER ¥ --admin-password $AZURE_VM_PASSWORD
VM のプロビジョニングには数分かかりますのでしばらくお待ちください。
パブリック IP アドレスを取得するために、az vm list-ip-addresses コマンドを実行してください。
az vm list-ip-addresses ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --name $AZURE_VM_NAME
コマンドを実行すると JSON が表示されます。publicIpAddresses の箇所を確認し、ipAddress プロパティの値を確認します。
以降の手順で使用するため、環境変数に設定しておいてください。
export VM_IP=[to be filled]
Linux VM から Postgres データベースへのアクセス許可設定
Postgres データベースはデフォルトで外部からのアクセスが許可されていません。 Linux VM から Postgres インスタンスにアクセスするために、ファイアウォールでルールを追加し、アクセス許可設定を行います。az postgres server firewall-rule create コマンドを実行し、Linux VM 上にデプロイされた JavaEE アプリケーションから Postgres へ通信できるようにします。
export FIREWALL_RULE_NAME=AllowJavaEECafeAppOnVM az postgres server firewall-rule create ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --server $AZURE_POSTGRES_SERVER_NAME ¥ --name $FIREWALL_RULE_NAME ¥ --start-ip-address $VM_IP ¥ --end-ip-address $VM_IP
Linux VM へ Payara サーバのインストール
Payara Serverは、GlassFish から派生したオープンソースのアプリケーションサーバーです。オンプレミス、クラウド、ハイブリッド環境などいずれの環境でも、高信頼でセキュアな Java EE(Jakarta EE)/ MicroProfile の実行環境を提供します。
詳細については、GitHubのプロジェクトもしくはドキュメントをご参照ください。
Linux VM の IP に対してユーザ名を指定し SSH 接続します。
ssh $AZURE_VM_USER@$VM_IP
プロンプトが表示されたらパスワードを入力してください。Linux VM にログインしたのち、下記の手順を実行してください。
必要なツールセットのインストール
Payara サーバーをインストールする前に、JDK/Maven のインストールを行います。
sudo apt-get update sudo apt install openjdk-11-jdk sudo apt install maven
Payara サーバーのセットアップ
このチュートリアル執筆時点の最新の Payara サーバーのバージョンは Payara Server 5.201 です。
Payara のセットアップは、zipファイルをダウンロードして解凍するだけです。
export PAYARA_VERSION=5.201 wget https://s3-eu-west-1.amazonaws.com/payara.fish/Payara+Downloads/$PAYARA_VERSION/payara-$PAYARA_VERSION.zip sudo apt install unzip unzip payara-$PAYARA_VERSION.zip
asadmin コマンドを実行しサーバの起動
ls ~/payara5/ コマンドを実行し、インストールされたファイルやディレクトリなどのを確認してください。
次に、bin ディレクトリ下にある asadmin コマンドを使用してサーバーを起動します
ls ~/payara5/ ~/payara5/bin/asadmin start-domain
サーバーが起動するまで少し時間がかかります。 起動が完了すると下記のようなログが表示されます。
Waiting for domain1 to start ......... Successfully started the domain : domain1 domain Location: /root/payara5/glassfish/domains/domain1 Log File: /root/payara5/glassfish/domains/domain1/logs/server.log Admin Port: 4848 Command start-domain executed successfully.
アプリケーションのセットアップとデプロイ
以上で Linux VM を構築し Payara サーバをインストールし起動しました。そこでアプリケーションのデプロイを行います。
アプリケーションをデプロイするため Git リポジトリをクローンしてください。
git clone https://github.com/abhirockzz/javaee-on-azure-iaas export APP_FOLDER_NAME=javaee-on-azure-iaas
Azure の Postgres データベースに接続するために、設定ファイル中の JDBC 接続URLを更新する必要があります。
設定ファイルは、web.xmlファイル(javaee-on-azure-iaas/src/main/webapp/WEB-INF のディレクトリ下)に存在し、ファイル中の セクションの 属性を更新してください。
jdbc:postgresql://POSTGRES_FQDN:5432/postgres?user=AZURE_POSTGRES_ADMIN_USER@=AZURE_POSTGRES_SERVER_NAME&password=AZURE_POSTGRES_ADMIN_PASSWORD&sslmode=require
以下は、JDBC URL の設定項目に関するリストです。
- POSTGRES_FQDN は Postgres インスタンスが稼働するサーバの完全修飾ドメイン名を指定
- AZURE_POSTGRES_ADMIN_USER は Postgres インストール時に設定した管理者ユーザー名
- AZURE_POSTGRES_SERVER_NAME は Postgres のインストール時に設定したサーバー名
- AZURE_POSTGRES_ADMIN_PASSWORD は Postgres のインストール時に設定した管理者のパスワード
環境変数に設定します。
export POSTGRES_FQDN=[to be filled] export AZURE_POSTGRES_ADMIN_USER=[to be filled] export AZURE_POSTGRES_SERVER_NAME=[to be filled] export AZURE_POSTGRES_ADMIN_PASSWORD=[to be filled]
下記のコマンドを実行して、設定項目を修正します。
export FILE_NAME=javaee-on-azure-iaas/src/main/webapp/WEB-INF/web.xml sed -i 's/POSTGRES_FQDN/'"$POSTGRES_FQDN"'/g' $FILE_NAME sed -i 's/AZURE_POSTGRES_SERVER_NAME/'"$AZURE_POSTGRES_SERVER_NAME"'/g' $FILE_NAME sed -i 's/AZURE_POSTGRES_ADMIN_USER/'"$AZURE_POSTGRES_ADMIN_USER"'/g' $FILE_NAME sed -i 's/AZURE_POSTGRES_ADMIN_PASSWORD/'"$AZURE_POSTGRES_ADMIN_PASSWORD"'/g' $FILE_NAME
下記に セクションの例を示します。
<data-source> <name>java:global/JavaEECafeDB</name> <class-name>org.postgresql.ds.PGPoolingDataSource</class-name> <url>jdbc:postgresql://foobar-pg.postgres.database.azure.com:5432/postgres?user=foobar@foobar-pg&amp;password=foobarbaz&amp;sslmode=require</url> </data-source>
アプリケーションの設定を変更しましたので、ソースコードをビルドしましょう!
mvn clean install -f $APP_FOLDER_NAME/pom.xml
上記コマンドを実行すると、war ファイルが生成されます。下記のコマンドで war ファイルが生成されているか確認してください。
ls -lrt $APP_FOLDER_NAME/target | grep javaee-cafe.war
アプリケーション設定の最後に、Postgres の JDBC ドライバーをダウンロードして Payara サーバーに追加しましょう。
ここではドライバーのバージョンは 42.2.12 を使用しています
export PG_DRIVER_JAR=postgresql-42.2.12.jar wget https://jdbc.postgresql.org/download/$PG_DRIVER_JAR
asadmin add-library コマンドを実行し入手した jar ファイルを Payara に追加できます。
~/payara5/glassfish/bin/asadmin add-library $PG_DRIVER_JAR
もしくは、Maven の pom.xml ファイルに下記の依存関係を追加してください。
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.12</version> </dependency>
最後に、WAR ファイルを Payara サーバにデプロイします。デプロイは Payara ドメインの autodeploy ディレクトリにコピーするだけでとても簡単です。
cp $APP_FOLDER_NAME/target/javaee-cafe.war ~/payara5/glassfish/domains/domain1/autodeploy
デプロイにはしばらく時間がかかりるため、それまでの間、次のコマンドでログを表示し、作業状況を確認します。
tail -f ~/payara5/glassfish/domains/domain1/logs/server.log
正常に、javaee-cafe アプリケーションのデプロイが完了すると、下記のようなメッセージが表示されます。
[2019-11-18T13:34:21.317+0000] [Payara 5.193] [INFO] [NCLS-DEPLOYMENT-02035] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=104 _ThreadName=payara-executor-service-scheduled-task] [timeMillis: 1574084061317] [levelValue: 800] [[ [AutoDeploy] Successfully autodeployed : /home/abhishgu/payara5/glassfish/domains/domain1/autodeploy/javaee-cafe.war.]]
アプリケーションの動作確認
デプロイが完了したので、JavaEE アプリケーションの動作確認を行います。このアプリケーションは Web ブラウザーを利用してアクセスできます。しかし現時点で、Postgres のインスタンスと同様、Payara サーバーへパブリックのインターネットからは接続できません。アクセスするためには、az vm open-port を使用してファイアウォールルールを作成します。ここでは Payaraサーバーが使用するデフォルトのHTTPポート番号 8080 を公開します。
az vm open-port --port 8080 ¥ --resource-group $AZURE_RESOURCE_GROUP_NAME ¥ --name $AZURE_VM_NAME
JSF のフロントエンドにアクセス
ブラウザで http://[ENTER_VM_IP]:8080/javaee-cafe にアクセスしてください。GUIで、コーヒーの作成、削除、表示できます。
REST API の使用
このアプリケーションは、コーヒーの作成、削除、表示のための REST API も公開しています。
export VM_IP=[to be filled]
コーヒーの作成
curl -X POST $VM_IP:8080/javaee-cafe/rest/coffees ¥ -d '{"name":"cappuccino","price":"10"}' ¥ -H "Content-Type: application/json" curl -X POST $VM_IP:8080/javaee-cafe/rest/coffees ¥ -d '{"name":"caffe-latte","price":"15"}' ¥ -H "Content-Type: application/json"
コーヒー一覧の取得
curl -H "Accept: application/json" ¥ $VM_IP:8080/javaee-cafe/rest/coffees
追加されているコーヒーのオプションのリスをを JSON で表示
ID 指定によるコーヒーの取得
curl -H "Accept: application/json" ¥ $VM_IP:8080/javaee-cafe/rest/coffees/1
ID 指定によるコーヒーの削除
curl -X DELETE $VM_IP:8080/javaee-cafe/rest/coffees/1 curl -H "Accept: application/json" ¥ $VM_IP:8080/javaee-cafe/rest/coffees
カプチーノが削除され、一覧から削除されている事を確認
リソースのクリーンアップ
アプリケーションの動作確認が完了したら、リソースを削除します。今回、リソースグループで一元管理したので、単一のコマンドを実行して削除できます。
これにより、チュートリアルの一部で作成した全リソース(VM、Postgresなど)を削除できます、ご注意ください。
az group delete --name $AZURE_RESOURCE_GROUP_NAME
まとめ
ここでは、仮想マシンにデプロイしたアプリサーバーを使用して、Java EE アプリケーションを Azure にデプロイする方法と、長期的な永続化のためにマネージド・データベースを使用する方法を学びました。
前述したように、各オプションには独自の長所と短所があります。IaaS の場合、アプリケーション、デプロイメント用のインフラストラクチャ、スケーリング方法などを完全に制御できます。一方、インフラの管理、アプリケーションのサイジング、セキュリティ保護などは、 アプリケーション機能の一部として、ご自身で責任を持たなければなりません。
次のパートでは、Dockerコンテナープラットフォームを使用してJava EEアプリケーションをデプロイする方法について説明します。 どうぞお楽しみにみしてください!