Todos los productos
Search
Centro de documentos

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

Última actualización: Sep 04, 2026

Capture volcados de heap .hprof que persisten entre reinicios de pods por OOM al montar un volumen NAS respaldado por CNFS.

Requisitos previos

Asegúrese de cumplir con lo siguiente:

Notas de uso

Configure el tamaño máximo del heap de JVM por debajo del límite de memoria del pod. Mantenga el parámetro -Xmx inferior al límite de memoria asignado al pod. Si el heap de JVM alcanza primero el límite del pod, el OOM killer de Linux finalizará el proceso antes de que la JVM pueda escribir el volcado.

Utilice un CNFS dedicado para los volcados de heap. Un solo evento de OOM puede generar un archivo .hprof de varios gigabytes que podría agotar la cuota compartida e interrumpir las operaciones.

Sincronice la imagen de File Browser antes de comenzar. Es posible que no se pueda extraer la imagen docker.io/filebrowser/filebrowser:v2.18.0 debido a restricciones de red. Sincronícela con su instancia de ACR Enterprise Edition mediante subscribing to images from outside China:

Campo

Valor

Artifact source

Docker Hub

Source repository coordinates

filebrowser/filebrowser

Subscription policy

v2.18.0

Después de la sincronización, configure password-free image pulling entre la instancia de ACR Enterprise Edition y su clúster de ACK.

Despliegue de la aplicación Java

Despliegue un Deployment de Java con almacenamiento respaldado por CNFS como destino para los volcados de heap. La imagen de ejemplo registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 ejecuta Mycode con un límite de heap de 80 MiB.

El Deployment utiliza subPathExpr: $(POD_NAMESPACE).$(POD_NAME) para crear subdirectorios individuales por pod dentro del volumen NAS compartido. Esto evita que los reinicios de los pods sobrescriban los volcados de otros.

subPathExpr utiliza paréntesis redondos — $(POD_NAME) — y no llaves. Los valores provienen de las variables de entorno de la Downward API POD_NAME y 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

Verificación del evento OOM

Una vez que inicia el Deployment, Mycode asigna memoria hasta que la JVM agota el heap de 80 MiB y desencadena un error OOM. El pod se reinicia y ACK registra una alerta de back-off restarting en Event Center.

Para confirmar que ocurrió el evento OOM:

  1. Inicie sesión en la consola de ACK. En el panel de navegación izquierdo, haga clic en Clusters.

  2. Localice su clúster y haga clic en su nombre. En el panel de navegación izquierdo, seleccione Operations > Event Center.

  3. Revise la lista de eventos para buscar una alerta de back-off restarting en el pod java-application.

    3e0492283c067026c9cfd348a898ecb1

Exploración de los archivos de volcado de heap

Despliegue File Browser con el mismo PVC de CNFS montado en rootDir para explorar y descargar los volcados de heap.

Despliegue de 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

Salida esperada:

configmap/filebrowser unchanged
deployment.apps/filebrowser configured

Creación de un Service

  1. Inicie sesión en la consola de ACK. En el panel de navegación izquierdo, haga clic en Clusters.

  2. Localice su clúster y haga clic en su nombre. En el panel de navegación izquierdo, seleccione Network > Services.

  3. En la página Services, seleccione el namespace default y haga clic en Create. Configure los siguientes parámetros:

    Consulte NLB billing overview .

    Parámetro

    Valor

    Name

    filebrowser

    Service type

    SLB > SLB type: CLB. Seleccione Create Resource y establezca Access method en Public Access.

    Backend

    Haga clic en +Reference Workload Label. Establezca Resource type en Deployments y Resources en filebrowser.

    Port mapping

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

  4. Envíe la configuración.

Acceso a File Browser

  1. Copie la dirección del endpoint desde la página de Services.

  2. Abra <endpoint-address>:8080 en un navegador. Aparecerá la página de inicio de sesión de File Browser.

  3. Inicie sesión con las credenciales predeterminadas: nombre de usuario admin, contraseña admin.

    20fe4dcde1759ebc64cbe0b1bb3168da

  4. Haga doble clic en rootdir para acceder al punto de montaje de NAS.

    image

Resultado

Dentro de rootdir, el directorio de volcado de cada pod sigue la nomenclatura definida por la regla subPathExpr: $(POD_NAMESPACE).$(POD_NAME); por ejemplo, default.java-application-76d8cd95b7-prrl2.

image

Abra el directorio para localizar el archivo java_pid1.hprof. Descárguelo y analícelo con Eclipse Memory Analyzer (MAT) para identificar el código que provocó el error OOM.

lQLPJxMFSGyoLcnNAqTNB2awoAbbe3-kh8AIV2X4pMttAA_1894_676

Funcionamiento

Tres mecanismos trabajan en conjunto para preservar los volcados de heap entre reinicios de pods:

  • PVC de CNFS con ReadWriteMany: El PVC respaldado por NAS se monta tanto en el pod java-application como en el de File Browser. NAS conserva los archivos independientemente del ciclo de vida del pod, por lo que los volcados sobreviven a las caídas.

  • subPathExpr con Downward API: Cada pod se monta en su propio subdirectorio (<namespace>.<pod-name>) en lugar de la raíz de NAS. Esto impide que los reinicios sobrescriban los volcados y facilita el rastreo hacia el pod correspondiente.

  • -XX:+HeapDumpOnOutOfMemoryError: La JVM escribe el estado del heap en la ruta definida por -XX:HeapDumpPath antes de finalizar por OOM. Dado que dicha ruta reside en NAS, el archivo persiste tras la salida del pod.