すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:CNFS を使用して異常終了時に JVM ヒープダンプを自動的に収集する

最終更新日:Nov 09, 2025

アプリケーションが Java で開発され、JVM ヒープ領域が小さすぎると、メモリ不足 (OOM) の問題が発生する可能性があります。Container Network File System (CNFS) をコンテナー内の対応するディレクトリにマウントすることで、ロギングのキャリアとして使用できます。JVM OOM が発生すると、CNFS は適切なディレクトリにログを記録できます。このトピックでは、CNFS を使用して異常終了時に JVM ヒープダンプを自動的に収集する方法について説明します。

前提条件

考慮事項

  • 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 クラスター間でパスワードなしのプルポリシーを設定する必要があります。詳細については、「同じアカウントからイメージをプルする」をご参照ください。

手順

  1. registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 サンプルイメージを Java プログラムとして使用して OOM をシミュレートし、JVM OOM をトリガーします。

  2. 次の例を使用して、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 です。
    ---          
    EOF
  3. Container Service コンソールのイベントセンターを通じて、Pod に Back-off restarting アラートイベントがあることがわかります。これは、java-application アプリケーションが OOM を経験したことを示しています。

    1. ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。

    2. クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、[操作] > [イベントセンター] を選択します。

    3. 対応するイベントを表示します。

      3e0492283c067026c9cfd348a898ecb1

  4. 現在、NAS にはファイルの参照、アップロード、ダウンロード機能がないため、Web ベースのアクセスツールとして File Browser を使用できます。まず、NAS マウントポイントを File Browser の rootDir にマウントし、次に File Browser のコンテナーポートをマッピングする Service を作成し、最後にブラウザ経由で NAS に保存されているファイルにアクセスします。

    1. 次のテンプレートを使用して、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 configured
    2. ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。

    3. クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、[ネットワーク] > [サービス] を選択します。

    4. [Services] ページで、デフォルトの名前空間を選択し、[作成] をクリックして、次のパラメーターを設定します。

      パラメーター

      説明例

      サービス名

      filebrowser

      サービスタイプ

      Server Load Balancer (LoadBalancer)

      • ロードバランサータイプ: Classic Load Balancer (CLB)

      • [リソースの作成] を選択し、[CLB リソースの作成] ドロップダウンリストをクリックし、[アクセス方法][インターネットアクセス] に設定し、[課金方法][従量課金] に設定します。

      CLB の課金に関する詳細については、「CLB 課金の概要」をご参照ください。

      サービス関連付け

      [+参照ワークロードラベル] を選択します。

      • リソースタイプ: Deployments

      • リソースリスト: filebrowser

      ポートマッピング

      • サービスポート: 8080

      • コンテナーポート: 80

      • プロトコル: TCP

    5. ダイアログボックスで、サービスタイプとして [Server Load Balancer (LoadBalancer)] を選択します。[リソースの作成] を選択し、[アクセス方法][インターネットアクセス] に、[課金方法][従量課金 (PayByCLCU)] に設定し、プロンプトに従って設定変更を送信します。

      CLB の課金に関する詳細については、「CLB 課金の概要」をご参照ください。
    6. ブラウザを開き、アドレスバーに エンドポイントアドレス:8080 と入力します。File Browser のログインインターフェイスが表示されます。デフォルトのアカウント (admin) とパスワード (admin) を入力して、コンテナー内部にアクセスします。

      20fe4dcde1759ebc64cbe0b1bb3168da

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

      image

結果

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

image

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

lQLPJxMFSGyoLcnNAqTNB2awoAbbe3-kh8AIV2X4pMttAA_1894_676