Cryostatを使用するためのJavaアプリケーションの設定

Red Hat で Java Platform Advocate として OpenJDK を担当している伊藤ちひろ(@chiroito)です。

この記事は、Red Hat Developerのブログ記事、Announcing Cryostat 2.0: JDK Flight Recorder for containers | Red Hat Developer の翻訳記事です。


https://developers.redhat.com/sites/default/files/styles/article_feature/public/2020_Java_ContainerJFR_Featured_Article__A-01.png?itok=K_g-UdJY

Cryostat は、HotSpot JVM アプリケーションにすでに存在する JDK Flight Recorder (JFR) フレームワークを活用したプロファイリングおよび監視ツールです。Cryostatは、クラスタ内の収集拠点を提供し、クラスタ外からJDK Flight Recorderのデータに簡単かつ安全にアクセスできます。

この記事は、先日発表されたCryostat 2.0に続くものです。これは、Java アプリケーションで Cryostat 2.0 を使用するための、いくつかの手引き書の最初のものです。この記事では、Red Hat OpenShift 上で Cryostat を使用するために Quarkus ベースの Java アプリケーションをセットアップして設定する方法について探ります。

このシリーズの全記事を読む

注意: Red Hat ビルドの Cryostat 2.0 は、現在技術プレビューで広く利用可能です。Cryostat 2.0 は、自動化されたルール、より優れた API 応答 JSON 形式、カスタムターゲット、同時ターゲット JMX 接続、WebSocket プッシュ通知など、多くの新機能と改善点を導入しています。Red Hat ビルドには、OpenShift での Cryostat デプロイを簡素化し、自動化するための Cryostat Operator が含まれています。

JMX と Cryostat

Cryostat を使用するための主な前提条件は、アプリケーションが Java Management Extensions (JMX) を有効にして公開していることです。OpenShiftでは、JMXポートを公開するということは、Cryostatのデフォルトのポート番号である9091を使用するか、ポートにjfr-jmxという名前を付けるかのどちらかです。OpenShiftにデプロイされたQuarkusベースのJavaアプリケーションで、JMXを公開する手順を探っていきます。

Step 1: Quarkusサンプル・アプリケーションを生成

それでは、Quarkusのサンプルアプリケーションを使用してみましょう。まず、code.quarkus.ioにアクセスし、新しいアプリケーションを生成します。この記事では、デフォルトのorg.acmeグループとcode-with-quarkusartifactIdを使用します。これらを自由にカスタマイズしてください。生成オプションを設定したら、.zipをダウンロードし、作業ディレクトリに展開します。

$ mv Downloads/code-with-quarkus.zip workspace

$ cd workspace

$ unzip code-with-quarkus.zip

$ cd code-with-quarkus

これで、Quarkusアプリケーションが生成され、変更する準備が整いました。続行する前に、簡単な整合性チェックを行いましょう。mvnwがQuarkusの依存関係をダウンロードし、アプリケーションを構築したら、次のようなメッセージが表示されます。"Listening on: http://localhost:8080."このURLにアクセスし、Quarkusのデフォルトのウェルカムページが表示されることを確認します。

$ ./mvnw compile quarkus:dev

Step 2: JMX用のアプリケーションを設定

ここまでで問題がなければ、QuarkusアプリケーションをJMX用にセットアップできます。Quarkusアプリケーションを実行しているターミナルに戻り、Ctrl-Cを押して、開発サーバを停止します。

開発サーバが停止したので、プロジェクトのDockerfile.jvmを編集します。このファイルには、Podman、Buildah、DockerなどのOpen Container Initiative(OCI)イメージビルダーが、QuarkusアプリケーションをOCIイメージに組み入れる際に従うべき指示が含まれています。(特に、アプリケーションをネイティブイメージモードではなくJVMモードで構築する場合)。JVMモードのアプリケーションをOCIイメージにパッケージングしたら、そのイメージをOpenShiftまたはPodmanのコンテナとしてデプロイして実行できます。続けて、Dockerfileを編集してみましょう。

$ $VISUAL src/main/docker/Dockerfile.jvm

こんな行があるはずです。

ENV JAVA_OPTIONS=”-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager”

この行を修正し、JMXを有効にするためのオプションを追加しましょう。

ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dcom.sun.management.jmxremote.port=9096 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

ここでは、9096番ポートでJMXを有効にしています。この記事のために、JMX SSL と JMX 認証を無効にしています。実稼働環境では、両方とも有効にする必要があります(JMXの管理については、Oracleのドキュメントを参照してください)。

さて、最後にDockerfileにもう一つ変更を加える必要があります。EXPOSE 8080の行は、EXPOSE 8080 9096にする必要があります。これにより、OCIイメージにメタデータが追加され、中のアプリケーションがポート80809096をリッスンすることを示します。これにより、後でOpenShift上にこれをデプロイしたときに、これらの2つのポートが自動的にクラスタ内のネットワークトラフィックのために生成されたサービスに含まれるようになります。

QuarkusをJVMモードで動作させている理由:Dockerfile.jvmのみを編集し、Dockerfile.nativeなどの他のDockerfileを編集していないことにお気づきかもしれません。これは、ネイティブイメージモードのQuarkusは、現在JMXをサポートしていないためです。JMXにアクセスするためには、QuarkusをJVMモードで実行する必要があり、その結果、Cryostatに対応します。

Step 3: 試してみる(オプション)

この設定により、サンプルQuarkusアプリケーションをビルドしてOCIイメージとして実行する際に、JMXを使用するように設定されます。この段階に至る前に、QuarkusでJMXとJFRを試したい場合は、以下を実行できます。

$ ./mvnw -Djvm.args=”-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dcom.sun.management.jmxremote.port=9096 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false” compile quarkus:dev

これにより、JMXが有効になり、Dockerfile.jvmで指定したのと同じ方法で設定されたquarkus:devサーバーが実行されます。ここで、JDK Mission Controlを開くと、JVMブラウザパネルにQuarkusアプリケーションが表示されるはずです。

Step 4: アプリケーションをコンテナイメージにビルド

設定に満足したら、アプリケーションをコンテナイメージにビルドしてみましょう。このアプリケーションをOpenShiftにデプロイしたいので、例としてquay.ioタグを付けますが、これは自分のユーザー名とアプリケーション名に置き換えてください。

$ ./mvnw package

$ podman build -f src/main/docker/Dockerfile.jvm -t quay.io/<namespace>/code-with-quarkus .

もう1回正常性を確認し、良さそうならquay.ioにプッシュします。

$ podman run -i --rm -p 8080:8080 -p 9096:9096 quay.io/<namespace>/code-with-quarkus

$ # ブラウザで http://localhost:8080 を開き、Quarkus のウェルカムページが表示されることを確認

$ podman push quay.io/<namespace>/code-with-quarkus

そのイメージがプッシュされたら、quay.ioにアクセスして(例えば、https://quay.io//code-with-quarkus?tab=settings)、イメージリポジトリを公開します。その後、OpenShiftクラスターにデプロイすることができます。

$ oc new-app quay.io/<namespace>/code-with-quarkus:latest

$ oc edit svc code-with-quarkus

$ # ポート「9096-tcp」を「jfr-jmx」にリネーム、port、targetPortなどはそのまま

$ oc expose --port=8080 svc code-with-quarkus

$ oc status # code-with-quarkusアプリがアクセス可能で、Quarkusのウェルカムページが表示されていることを確認します。

Step 5: Cryostat 2.0をOpenShiftにインストール

Cryostat Operator を使用して OpenShift クラスタに Cryostat をインストールする方法については、Cryostat 2.0 のアナウンスを参照してください。Cryostat をインストールし、code-with-quarkus サンプルアプリケーションと同じ OpenShift ネームスペースに存在させたら、すべてが正しく接続されたことを確認できます。

$ oc get flightrecorders

code-with-quarkus-5645dbdd47-z7pl7というような項目があるはずです。これは、Cryostat Operatorが動作しており、私たちのQuarkusアプリケーションがCryostatに対応していると認識されたことを示します。

oc status を再度確認し、Cryostat の URL にアクセスします。OpenShiftアカウントのトークンを入力し(OpenShiftコンソールから、またはoc whoami -tで取得できます)、code-with-quarkusアプリケーションを選択して、Eventビューに移動してください。読み込まれたイベントテンプレートのリストが表示されれば、CryostatとQuarkusインスタンスが正常に通信していることになります!

まとめ

この記事は、あなたのJavaアプリケーションでCryostatを使用するための入門書を提供するいくつかの記事の最初のものでした。次回は、Cryostat のカスタムターゲットの定義について紹介します。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。