付録F JVM のチューニングによる Linux コンテナー内での実行
F.1. 概要
JVM エルゴノミクス による、ガベッジコレクター、ヒープサイズ、およびランタイムコンパイラーのデフォルト値の設定を許可すると、Linux コンテナー内部で実行している Java プロセスは想定どおりに動作しません。java -jar mypplication-fat.jar
などのチューニングパラメーターを使用せずに Java アプリケーションを実行すると、JVM はコンテナーの制限ではなく、ホストの制限を基にして複数のパラメーターを自動的に設定します。
本セクションでは、コンテナーの制限を考慮してデフォルト値が算出されるよう、Linux コンテナー内部で Java アプリケーションをパッケージ化するための情報を提供します。
F.2. JVM のチューニング
現在の Java JVM はコンテナー対応でないため、コンテナーのサイズではなく、物理ホストのサイズを基にしてリソースを割り当てます。たとえば、通常 JVM は最大ヒープサイズを、ホスト上の物理メモリーの 1/4 に設定します。大型のホストマシンでは、この値はコンテナーに定義されたメモリー制限を簡単に越えてしまいます。実行時にコンテナー制限を越えてしまうと、OpenShift はアプリケーションを強制終了します。
この問題に対応するには、Java JVM が制限されたコンテナー内で実行されることを認識でき、かつ最大ヒープサイズが手動で調整されない場合は自動的に調整されることを認識できる、Fuse on OpenShift ベースのイメージを使用します。これにより、アプリケーションを実行する JVM の最大メモリー制限とコア制限を設定できます。Fuse on OpenShift イメージは以下を行うことができます。
- コンテナーのコアを基にした CICompilerCount の設定。
- コンテナーメモリー制限が 300MB 未満の場合に C2 JIT コンパイラーを無効にする。
- コンテナーメモリー制限が 300MB 未満の場合に、コンテナーメモリー制限の 1/4 をデフォルトのヒープサイズに使用する。
F.3. Fuse on OpenShift イメージ のデフォルト動作
Fuse on OpenShift では、アプリケーションビルドのベースイメージは Java イメージ (Spring Boot アプリケーションの場合) または Karaf イメージ (Karaf アプリケーションの場合) のいずれかになります。Fuse on OpenShift イメージはコンテナー制限を読み取るスクリプトを実行し、その制限をリソース割り当てのベースとして使用します。デフォルトでは、スクリプトは以下のリソースを JVM に割り当てます。
- コンテナーメモリー制限の 50%
- コンテナーコア制限の 50%
これには一部の例外があります。Karaf と Java イメージでは、物理メモリーが 300MB のしきい値未満になると、ヒープサイズはデフォルトの半分ではなく、1/4 に回復されます。
F.4. Fuse on OpenShift イメージのカスタムチューニング
スクリプトは、内部リソースをチューニングするためにカスタムアプリケーションによる読み取りが可能な CONTAINER_MAX_MEMORY
および CONTAINER_CORE_LIMIT
環境変数を設定します。さらに、アプリケーションを実行する JVM の設定をカスタマイズ可能にする以下のランタイム環境変数を指定できます。
-
JAVA_OPTIONS
-
JAVA_MAX_MEM_RATIO
制限を明示的にカスタマイズするには、Maven プロジェクトで JAVA_MAX_MEM_RATIO
ファイルを編集し、deployment.yml
環境変数を設定します。以下に例を示します。
spec: template: spec: containers: - resources: requests: cpu: "0.2" memory: 256Mi limits: cpu: "1.0" memory: 256Mi env: - name: JAVA_MAX_MEM_RATIO value: 60
F.5. サードパーティーライブラリーのチューニング
Red Hat は、Jetty などのサードパーティー Java ライブラリーの制限をカスタマイズすることを推奨します。このようなライブラリーは、制限を手作業でカスタマイズしないと、指定のデフォルト制限を使用します。
起動スクリプトは、アプリケーションが使用できるコンテナー制限を記述する一部の環境変数を公開します。
CONTAINER_CORE_LIMIT
- 算出されたコア制限
CONTAINER_MAX_MEMORY
- コンテナーに指定されたメモリー制限