Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Collect JVM heap dumps on abnormal exits with CNFS

Última atualização: Jun 27, 2026

Capture heap dumps .hprof que persistem entre reinicializações de pods por OOM ao montar um volume NAS com suporte a CNFS.

Pré-requisitos

Verifique os seguintes itens:

Observações de uso

Defina o heap máximo da JVM abaixo do limite de memória do pod. Mantenha o parâmetro -Xmx inferior ao limite de memória do pod. Se o heap da JVM atingir o limite do pod primeiro, o OOM killer do Linux encerrará o pod antes que a JVM consiga gravar o dump.

Utilize um CNFS dedicado para heap dumps. Um único evento de OOM pode gerar um arquivo .hprof de vários gigabytes, capaz de esgotar a cota compartilhada e interromper as operações.

Sincronize a imagem do File Browser antes de começar. A imagem docker.io/filebrowser/filebrowser:v2.18.0 pode falhar no pull devido a restrições de rede. Sincronize-a com sua instância do ACR Enterprise Edition assinando imagens de fora da China:

Campo

Valor

Artifact source

Docker Hub

Source repository coordinates

filebrowser/filebrowser

Subscription policy

v2.18.0

Após a sincronização, configure o pull de imagens sem senha entre a instância do ACR Enterprise Edition e seu cluster ACK.

Implante a aplicação Java

Implante um Deployment Java com armazenamento suportado por CNFS como destino dos heap dumps. A imagem de exemplo registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 executa Mycode com um limite de heap de 80 MiB.

O Deployment utiliza subPathExpr: $(POD_NAMESPACE).$(POD_NAME) para criar subdiretórios individuais por pod dentro do volume NAS compartilhado. Isso evita que reinicializações de pods sobrescrevam os dumps uns dos outros.

O campo subPathExpr usa parênteses — $(POD_NAME) — e não chaves. Os valores provêm das variáveis de ambiente da Downward API POD_NAME e POD_NAMESPACE .
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:
        - name: POD_NAME          # Inject pod name via Downward API
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE     # Inject pod namespace via Downward API
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        args:
        - java
        - -Xms80m                         # Minimum heap size
        - -Xmx80m                         # Maximum heap size (keep below pod memory limit)
        - -XX:HeapDumpPath=/mnt/oom/logs  # Write heap dumps to the CNFS-backed mount
        - -XX:+HeapDumpOnOutOfMemoryError # Trigger heap dump on OOM
        - Mycode
        volumeMounts:
        - name: java-oom-pv
          mountPath: "/mnt/oom/logs"
          subPathExpr: $(POD_NAMESPACE).$(POD_NAME)  # Round brackets, not curly brackets
      volumes:
      - name: java-oom-pv
        persistentVolumeClaim:
          claimName: cnfs-nas-pvc
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: cnfs-nas-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: alibabacloud-cnfs-nas
  resources:
    requests:
      storage: 70Gi  # If directory quota is enabled, limits the subdirectory to 70 GiB
---
EOF

Verifique o evento de OOM

Após o início do Deployment, o Mycode aloca memória até que a JVM exaura o heap de 80 MiB e dispare um OOM. O pod é reiniciado e o ACK registra um alerta de back-off restarting no Event Center.

Para confirmar a ocorrência do OOM:

  1. Faça login no console do ACK. No painel de navegação à esquerda, clique em Clusters.

  2. Localize seu cluster e clique no nome dele. No painel de navegação à esquerda, escolha Operations > Event Center.

  3. Verifique na lista de eventos se há um alerta de back-off restarting no pod java-application.

    3e0492283c067026c9cfd348a898ecb1

Navegue pelos arquivos de heap dump

Implante o File Browser com o mesmo PVC do CNFS montado em rootDir para navegar e baixe os heap dumps.

Implante o File Browser

cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebrowser
  namespace: default
  labels:
    app.kubernetes.io/instance: filebrowser
    app.kubernetes.io/name: filebrowser
data:
  .filebrowser.json: |
    {
      "port": 80,
      "address": "0.0.0.0"
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: filebrowser
  namespace: default
  labels:
    app.kubernetes.io/instance: filebrowser
    app.kubernetes.io/name: filebrowser
spec:
  replicas: 1
  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:
      - name: filebrowser
        # Replace with your ACR image address after syncing filebrowser/filebrowser:v2.18.0
        image: XXXX-registry-vpc.cn-hangzhou.cr.aliyuncs.com/test/test:v2.18.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        volumeMounts:
        - mountPath: /.filebrowser.json
          name: config
          subPath: .filebrowser.json
        - mountPath: /db
          name: rootdir
        - mountPath: /rootdir
          name: rootdir
      volumes:
      - name: config
        configMap:
          name: filebrowser
          defaultMode: 420
      - name: rootdir
        persistentVolumeClaim:
          claimName: cnfs-nas-pvc  # Same PVC as the java-application Deployment
EOF

Saída esperada:

configmap/filebrowser unchanged
deployment.apps/filebrowser configured

Crie um Service

  1. Faça login no console do ACK. No painel de navegação à esquerda, clique em Clusters.

  2. Localize seu cluster e clique no nome dele. No painel de navegação à esquerda, escolha Network > Services.

  3. Na página Services, selecione o namespace default e clique em Create. Configure os seguintes parâmetros:

    Consulte a visão geral de faturamento do NLB .

    Parâmetro

    Valor

    Name

    filebrowser

    Service type

    SLB > SLB type: CLB. Selecione Create Resource e defina Access method como Public Access.

    Backend

    Clique em +Reference Workload Label. Defina Resource type como Deployments e Resources como filebrowser.

    Port mapping

    Service port: 8080, Container port: 80, Protocol: TCP

  4. Envie a configuração.

Acesse o File Browser

  1. Copie o endereço do endpoint na página de Services.

  2. Abra <endpoint-address>:8080 no navegador. A página de login do File Browser será exibida.

  3. Faça login com as credenciais padrão: nome de usuário admin, senha admin.

    20fe4dcde1759ebc64cbe0b1bb3168da

  4. Clique duas vezes em rootdir para acessar o ponto de montagem do NAS.

    image

Resultado

Dentro de rootdir, o diretório de dump de cada pod segue a nomenclatura definida pela regra subPathExpr: $(POD_NAMESPACE).$(POD_NAME) — por exemplo, default.java-application-76d8cd95b7-prrl2.

image

Abra o diretório para localizar o arquivo java_pid1.hprof. Baixe-o e analise-o com o Eclipse Memory Analyzer (MAT) para identificar o código que causou o OOM.

lQLPJxMFSGyoLcnNAqTNB2awoAbbe3-kh8AIV2X4pMttAA_1894_676

Como funciona

Três mecanismos atuam em conjunto para persistir os heap dumps entre reinicializações de pods:

  • PVC CNFS com ReadWriteMany: O PVC suportado por NAS é montado tanto nos pods da java-application quanto nos do File Browser. O NAS persiste os arquivos independentemente do ciclo de vida do pod, garantindo que os dumps sobrevivam a falhas.

  • subPathExpr com Downward API: Cada pod monta seu próprio subdiretório (<namespace>.<pod-name>) em vez da raiz do NAS. Isso evita que reinicializações sobrescrevam dumps e facilita o rastreamento dos arquivos até seus respectivos pods.

  • -XX:+HeapDumpOnOutOfMemoryError: A JVM grava o estado do heap no caminho definido por -XX:HeapDumpPath antes de sair devido a OOM. Como esse caminho reside no NAS, o arquivo permanece disponível após o encerramento do pod.