Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ(@chiroito)です。
この記事は、Red Hat Developerのブログ記事、Creating and deploying a Java 8 runtime container image | Red Hat Developer の翻訳記事です。
Javaの実行環境はコンパイルされたソースコードを実行できるものでなければならないが、例えばOpenJDKのような開発キットには、ソースコードをコンパイルして実行するためのライブラリ/バイナリがすべて含まれている。基本的に、後者は実行環境の上位集合です。OpenJDKのサポートとライフサイクルに関する詳細はこちらをご覧ください。
Red Hat は、Java 8 と 11 の両方の OpenJDK を搭載したコンテナイメージを出荷し、サポートしています。詳細はこちらを参照してください。Red Hat Middleware を使用している場合、出荷された s2i イメージは、Red Hat Openshift Container Platform などにデプロイするのにも便利です。
Red HatはOpenJDKベースのJava 8と11のイメージしか提供していないことに注意してください。とはいえ、開発者が独自のJavaランタイムイメージを作成したい場合もあるでしょう。例えば、ランタイムイメージを実行するためにストレージを最小化するといった理由が考えられます。その一方で、JolokioやHawkularなどのライブラリや、セキュリティパラメータの設定など、多くの手作業が必要になります。そういった細かい作業をしたくない場合は、Red Hatが出荷しているOpenJDK用のコンテナイメージを使うことをお勧めします。
この記事では、以下のことを行います。
- DockerとBuildahでイメージを構築します。
- DockerとPodmanを使って、イメージをlocalhostで実行します。
- イメージをQuayにプッシュします。
- 最後に、OpenShiftにストリームをインポートしてアプリを実行します。
この記事は、OpenShift 3.11と4.0のベータ版の両方で書かれています。早速ですが、ご紹介します。
設定方法
私たちのイメージを使用し、その動作を確認するために、バンドルの一部としてWebアプリを使用します。最近、Microprofile.ioは、MicroProfile Starter betaを発表しました。これは、ダウンロード可能なパッケージを作成することで、MicroProfileの使用を開始するのに役立ちます。Microprofile.ioにアクセスして、MicroProfile with Thorntail V2のパッケージを入手してください。
ダウンロードボタンをクリックしてアーカイブファイルを取得します。
Red Hat Enterprise Linux(RHEL)のマシンでは、まず、demoapp
などの一時ディレクトリを作成し、ダウンロードした成果物をそこに解凍します。
tempディレクトリで、次のように実行します:
$ mvn clean compile package
これで、ビルドされたデモアプリができあがり、fat jarができました。このjarを呼び出して、Thorntailを実行できます。
target/demo-thorntail.jar`をtempディレクトリにコピーしましょう。
ここでは、各レイヤーにコメントをつけたDockerfile
を紹介します。このファイルのソースコードは、こちらのGitHubでもご覧いただけます。
# Java 8 ランタイムの例 # Red Hatの公式レジストリとベースイメージ FROM registry.access.redhat.com/rhel7-minimal USER root # Javaランタイムのインストール RUN microdnf --enablerepo=rhel-7-server-rpms \ install java-1.8.0-openjdk --nodocs ;\ microdnf clean all # Javaがどこにあるかを明確にするためにJAVA_HOME変数を設定する ENV JAVA_HOME /etc/alternatives/jre # 自分のアプリのためのディレクトリ RUN mkdir -p /app # リッスンするポートを公開する EXPOSE 8080 # MicroProfile starter appをコピーする COPY demo-thorntail.jar /app/ # スクリプトをソースからコピー: run-java.shは、コンテナ内でコマンドラインからThorntailアプリを実行するための特定のパラメータを持っています。スクリプトの詳細は https://github.com/sshaaf/rhel7-jre-image/blob/master/run-java.sh にあります。 COPY run-java.sh /app/ # スクリプトを実行するためのパーミッションの設定 RUN chmod 755 /app/run-java.sh # 最後に、スクリプトを実行する CMD [ "/app/run-java.sh" ]
さて、Dockerfile
の詳細がわかったところで、イメージの構築を進めていきましょう。
重要な点として、OpenJDKのJavaランタイムは「java-1.8.0-openjdk」としてパッケージされています。これには、-devel
パッケージに含まれているコンパイラやその他の開発ライブラリは含まれていません。
上記のDockerfile
はRHELでビルドされています。つまり、ホストにはすでにサブスクリプションが添付されているので、subscription-manager
に登録する必要はありません。
以下に、これを構築する2つの方法を紹介します。私のように RHEL を使用している場合は、2 つのバイナリのいずれかを選択してデプロイできます。両方とも rhel7-server-extras-rpms
にあるはずです。
次のようにして extras
リポジトリを有効にします。
# subscription-manager repos --enable rhel-7-server-extras-rpms
ローカルでイメージをビルドと実行
docker
でイメージを構築します。
$ docker build -t quay.io/sshaaf/rhel7-jre8-mpdemo:latest .
イメージを docker
で実行し、localhost:8080 をコンテナのポート 8080 に指定します。
$ docker run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest
また、buildahコマンドも使用できます。これは、作業中のコンテナから、Dockerfileから、またはスクラッチからコンテナイメージを作成するのに役立ちます。作成されたイメージはOCIに準拠しているので、OCIランタイム仕様を満たしたランタイム(DockerやCRI-Oなど)で動作します。
buildah
でビルドします:
$ buildah bud -t rhel7-jre8-mpdemo .
buildah
でコンテナを作ります:
$ buildah from rhel7-jre8-mpdemo
また、Podmanを使ってもコンテナを実行できます。これはBuildahやSkopeoを補完するもので、Dockerのコマンドラインに似た体験を提供するものです。これにより、ユーザーはスタンドアロンの(オーケストレーションされていない)コンテナを実行できるようになります。また、Podmanはコンテナやポッドを実行するためのデーモンを必要としません。Podmanはextras
チャンネルの一部でもあり、以下のコマンドでコンテナを実行できます。
$ podman run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest
Podmanの詳細については、Containers without daemons: Podman and Buildah available in RHEL 7.6 and RHEL 8 BetaおよびPodman and Buildah for Docker usersをご覧ください。
イメージができたので、それを OpenShift にデプロイしてアプリをテストしたいと思います。そのためには、oc
クライアントライブラリが必要です。私は自分のクラスタを設定していますが、Red Hat Container Development Kit (CDK)/minishift、Red Hat OpenShift Online、または自分のクラスタも使用できます。手順は同じになるはずです。
OpenShiftにデプロイ
OpenShiftにデプロイするためには、以下のような構成が必要です。
- 新しく作成したコンテナイメージのイメージストリーム
- OpenShift用のデプロイメント構成
- サービスとルーティングの設定
イメージストリーム
イメージストリームを作成するために、私のOpenShiftクラスタはどこかからコンテナイメージを引き出せるようにしなければなりません。これまで、イメージは私自身のマシンに存在していました。これを Quay にプッシュしてみましょう。Red Hat Quayのコンテナとアプリケーションのレジストリは、あらゆるインフラ上でコンテナの安全な保管、配布、デプロイを提供します。スタンドアロンのコンポーネントとしても、OpenShiftと組み合わせても利用可能です。
まずQuayにログインする必要がありますが、これは以下のように行います。
$ docker login -u="sshaaf" -p="XXXX" quay.io
そして、新しく作ったイメージをQuayにプッシュします:
$ docker push quay.io/sshaaf/rhel7-jre8-mpdemo
ここでは、デプロイする前の構成を見てみましょう。気になる方は、デプロイテンプレートの詳細を読み飛ばして、プロジェクトの作成に進んでください。
イメージができたので、ストリームを定義します。
- apiVersion: v1 kind: ImageStream metadata: name: rhel7-jre8-mpdemo spec: dockerImageRepository: quay.io/sshaaf/rhel7-jre8-mpdemo
上の例では、Quay.ioのイメージリポジトリに直接アクセスしています。
デプロイメントコンフィグ
次は、デプロイメント設定です。ここでは、ポッドやトリガーを設定し、新しく作成したストリームを指定するなどします。
コンテナやOpenShiftのデプロイメントに慣れていない方は、こちらの便利なebookをご覧になるとよいでしょう。
- apiVersion: v1 kind: DeploymentConfig metadata: name: rhel7-jre8-mpdemo spec: template: metadata: labels: name: rhel7-jre8-mpdemo spec: containers: - image: quay.io/sshaaf/rhel7-jre8-mpdemo:latest name: rhel7-jre8-mpdemo ports: - containerPort: 8080 protocol: TCP replicas: 1 triggers: - type: ConfigChange - imageChangeParams: automatic: true containerNames: - rhel7-jre8-mpdemo from: kind: ImageStreamTag name: rhel7-jre8-mpdemo:latest type: ImageChange
サービス
これでデプロイメントができたので、内部のロードバランシングやポッドのIPアドレスなどを確保するサービスも定義したいと思います。
サービスは、新しく作成したアプリを最終的に外部のトラフィックに公開したい場合に重要です。
- apiVersion: v1 kind: Service metadata: name: rhel7-jre8-mpdemo spec: ports: - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 selector: deploymentconfig: rhel7-jre8-mpdemo
ルート
そして、デプロイメントの最後の部品は、ルートです。ルートを使ってアプリを外部に公開する時が来ました。このルートがどの内部サービスを指すのか、どのポートをターゲットにするのかを定義できます。OpenShift はルートにフレンドリーな URL を与えます。この URL を指定することで、新しく作成した Java 8 ランタイムベースのデプロイメント上で MicroProfile アプリが実行されるのを確認できます。
- apiVersion: v1 kind: Route metadata: name: rhel7-jre8-mpdemo spec: port: targetPort: 8080-tcp to: kind: Service name: rhel7-jre8-mpdemo weight: 100
上記の完全なテンプレートはGitHubのここにあります。
また、このようにOpenShiftでプロジェクトを作成してみましょう。
$ oc new-project jredemos
そして、テンプレートを処理して、OpenShift上でJava 8ランタイムを使ったデモを取得します。そのためには、以下のコマンドを実行します。
$ oc process -f deployment.yaml | oc create -f -
これでデプロイメント全体が作成され、以下のように表示されるはずです。
ここで、次のコマンドを実行します。
$ oc get routes
これにより、以下のようなルートが表示されます。
このルートをブラウザにコピーすると、RHEL 7上でJava 8ランタイムが動作するWebアプリがデプロイされていることが確認できます。(以下のアドレスは、クラスタのテスト専用であり、クラスタごとに異なります)
http://rhel7-jre8-mpdemo-jredemos.apps.cluster-1fda.1fda.openshiftworkshop.com/
まとめ
DockerまたはBuildahを使って、Java 8ランタイムのコンテナイメージを構築・作成することに成功しました。以下の点に注意してください。
- この画像は、どのようにして実現するかを示すためのものであることに注意してください。JolokioやHawkularのような、デプロイに必要なものは含まれていません。
- さらに、コンテナ内でJavaアプリを実行するために必要なパラメータは考慮されていません。これについては、Rafael Benevides氏の記事で非常によく説明されています。
- さらに、独自のコンテナイメージをデプロイする際には、Red Hat の OpenJDK ビルドを実行している場合、サポートおよびライフサイクルポリシー こちら を確認することを常に忘れないでください。
その後、MicroProfile Starter betaから基本的なMicroProfileのデモアプリを使ってOpenShiftにデプロイしました。
より包括的なデモアプリの作成を検討されている方は、以下の資料をご参照ください。
- Deploying MicroProfile apps on Microsoft Azure using the Azure Open Service Broker
- The MicroProfile ebook こちら
本記事の全資料はこちらからご覧いただけます。