アプリケーションが Java で開発され、JVM ヒープ領域が小さすぎると、メモリ不足 (OOM) の問題が発生する可能性があります。Container Network File System (CNFS) をコンテナー内の対応するディレクトリにマウントすることで、ロギングのキャリアとして使用できます。JVM OOM が発生すると、CNFS は適切なディレクトリにログを記録できます。このトピックでは、CNFS を使用して異常終了時に JVM ヒープダンプを自動的に収集する方法について説明します。
前提条件
CNFS を使用して NAS ファイルシステムを管理していること。詳細については、「CNFS を使用して NAS ファイルシステムを管理する (推奨)」をご参照ください。
Container Network File System (CNFS) は、Alibaba Cloud ファイルストレージを Kubernetes オブジェクト (CRD) として抽象化し、作成、削除、記述、マウント、監視、スケーリング操作などの独立した管理を可能にします。
Container Registry Enterprise Edition インスタンスを作成済みであること。詳細については、「Enterprise Edition インスタンスの作成」をご参照ください。
考慮事項
Java に設定された最大ヒープ値 (Xmx) は、JVM より先に Pod が OOM を経験する状況を防ぐために、Pod のメモリ制限よりも小さくする必要があります。
Java ヒープダンプを使用する場合、新しい CNFS を作成し、ビジネス用の CNFS と Java ヒープダンプ用の CNFS を分離することをお勧めします。これにより、ダンプ中に .hprof ファイルが大きくなりすぎて過剰なビジネスリソースを消費し、ビジネス運用に影響を与えるのを防ぎます。
この例で使用されているイメージ
docker.io/filebrowser/filebrowser:v2.18.0は、ネットワークアクセス制限によりプルに失敗する可能性があります。中国国外からのイメージのサブスクライブにより、ACR Enterprise Edition インスタンスに同期する必要があります。具体的な構成は次のとおりです。アーティファクトソース: Docker Hub
ソースリポジトリの座標: filebrowser/filebrowser
サブスクリプションポリシー: v2.18.0
イメージのサブスクリプションが完了したら、ACR Enterprise Edition インスタンスと ACK クラスター間でパスワードなしのプルポリシーを設定する必要があります。詳細については、「同じアカウントからイメージをプルする」をご参照ください。
手順
registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 サンプルイメージを Java プログラムとして使用して OOM をシミュレートし、JVM OOM をトリガーします。
次の例を使用して、java-application という名前の Deployment を作成します。
この例では、Java プログラム Mycode を開始するときに、要求されるヒープサイズが 80 MB に設定され、ヒープダンプディレクトリは /mnt/oom/logs です。JVM ヒープサイズが不足すると、HeapDumpOnOutOfMemoryError エラーがキャプチャされます。
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: java-application spec: selector: matchLabels: app: java-application template: metadata: labels: app: java-application spec: containers: - name: java-application image: registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 #このトピックのサンプルプログラムのイメージアドレス。 imagePullPolicy: Always env: #2 つのキーと値のペアを定義します: POD_NAME を metadata.name、POD_NAMESPACE を metadata.namespace として定義します。 - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace args: - java #コマンドを実行します。 - -Xms80m #ヒープメモリの最小ヒープ値。 - -Xmx80m #ヒープメモリの最大ヒープ値。 - -XX:HeapDumpPath=/mnt/oom/logs #OOM 発生時のヒープメモリダンプのパス。 - -XX:+HeapDumpOnOutOfMemoryError #ヒープ OOM エラーをキャプチャします。 - Mycode #プログラムを実行します。 volumeMounts: - name: java-oom-pv mountPath: "/mnt/oom/logs" #コンテナー内のマウントディレクトリとして /mnt/oom/logs を使用します。 subPathExpr: $(POD_NAMESPACE).$(POD_NAME) #作成されたサブディレクトリとして $(POD_NAMESPACE).$(POD_NAME) を使用して、サブディレクトリに OOM ダンプファイルを生成します。 volumes: - name: java-oom-pv persistentVolumeClaim: claimName: cnfs-nas-pvc #cnfs-nas-pvc という名前の CNFS PVC を使用します。 --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: cnfs-nas-pvc spec: accessModes: - ReadWriteMany storageClassName: alibabacloud-cnfs-nas resources: requests: storage: 70Gi # ディレクトリクォータ機能が有効な場合、storage フィールドが有効になり、動的に作成されたディレクトリに書き込めるデータの最大量は 70 GiB です。 --- EOFContainer Service コンソールのイベントセンターを通じて、Pod に Back-off restarting アラートイベントがあることがわかります。これは、java-application アプリケーションが OOM を経験したことを示しています。
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、 を選択します。
対応するイベントを表示します。

現在、NAS にはファイルの参照、アップロード、ダウンロード機能がないため、Web ベースのアクセスツールとして File Browser を使用できます。まず、NAS マウントポイントを File Browser の rootDir にマウントし、次に File Browser のコンテナーポートをマッピングする Service を作成し、最後にブラウザ経由で NAS に保存されているファイルにアクセスします。
次のテンプレートを使用して、File Browser の Deployment と File Browser に必要な ConfigMap を作成します。デフォルトでポート 80 が有効になっています。
cat << EOF | kubectl apply -f - apiVersion: v1 data: .filebrowser.json: | { "port": 80, "address": "0.0.0.0" } kind: ConfigMap metadata: labels: app.kubernetes.io/instance: filebrowser app.kubernetes.io/name: filebrowser name: filebrowser namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/instance: filebrowser app.kubernetes.io/name: filebrowser name: filebrowser namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app.kubernetes.io/instance: filebrowser app.kubernetes.io/name: filebrowser template: metadata: labels: app.kubernetes.io/instance: filebrowser app.kubernetes.io/name: filebrowser spec: containers: - image: XXXX-registry-vpc.cn-hangzhou.cr.aliyuncs.com/test/test:v2.18.0 #サンプルイメージ docker.io/filebrowser/filebrowser:v2.18.0 は、ネットワークアクセス制限によりプルに失敗する可能性があります。注意事項のセクションをご参照ください。 imagePullPolicy: IfNotPresent name: filebrowser ports: - containerPort: 80 name: http protocol: TCP resources: {} securityContext: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /.filebrowser.json name: config subPath: .filebrowser.json - mountPath: /db name: rootdir - mountPath: /rootdir name: rootdir dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 volumes: - configMap: defaultMode: 420 name: filebrowser name: config - name: rootdir persistentVolumeClaim: claimName: cnfs-nas-pvc EOF予想される出力:
configmap/filebrowser unchanged deployment.apps/filebrowser configuredACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、 を選択します。
[Services] ページで、デフォルトの名前空間を選択し、[作成] をクリックして、次のパラメーターを設定します。
パラメーター
説明例
サービス名
filebrowser
サービスタイプ
Server Load Balancer (LoadBalancer)
ロードバランサータイプ: Classic Load Balancer (CLB)
[リソースの作成] を選択し、[CLB リソースの作成] ドロップダウンリストをクリックし、[アクセス方法] を [インターネットアクセス] に設定し、[課金方法] を [従量課金] に設定します。
CLB の課金に関する詳細については、「CLB 課金の概要」をご参照ください。
サービス関連付け
[+参照ワークロードラベル] を選択します。
リソースタイプ: Deployments
リソースリスト: filebrowser
ポートマッピング
サービスポート: 8080
コンテナーポート: 80
プロトコル: TCP
ダイアログボックスで、サービスタイプとして [Server Load Balancer (LoadBalancer)] を選択します。[リソースの作成] を選択し、[アクセス方法] を [インターネットアクセス] に、[課金方法] を [従量課金 (PayByCLCU)] に設定し、プロンプトに従って設定変更を送信します。
CLB の課金に関する詳細については、「CLB 課金の概要」をご参照ください。
ブラウザを開き、アドレスバーに エンドポイントアドレス:8080 と入力します。File Browser のログインインターフェイスが表示されます。デフォルトのアカウント (admin) とパスワード (admin) を入力して、コンテナー内部にアクセスします。

File Browser は cnfs-nas-pvc という名前の PVC を rootDir にマウントするため、rootDir をダブルクリックして NAS マウントポイントに入ります。

結果
File Browser に、default.java-application-76d8cd95b7-prrl2 という名前のディレクトリが表示されます。このディレクトリは、java-application の subPathExpr: $(POD_NAMESPACE).$(POD_NAME) ルールによって生成されます。

次に、このディレクトリに入ると、ディレクトリ内にダンプファイル java_pid1.hprof が表示されます。プログラムで OOM が発生したコード行を特定するには、java_pid1.hprof をローカルマシンにダウンロードし、MAT (Eclipse Memory Analyzer Tools) を使用して JVM スタック情報をさらに分析できます。
