Tous les produits
Search
Centre de documentation

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

Dernière mise à jour :Aug 11, 2026

Capturez les vidages de tas .hprof qui persistent lors des redémarrages de pods dus à une erreur de mémoire insuffisante (OOM) en montant un volume NAS pris en charge par CNFS.

Prérequis

Vérifiez les points suivants :

Notes d'utilisation

Définissez la taille maximale du tas JVM en dessous de la limite de mémoire du pod. Maintenez la valeur -Xmx inférieure à la limite de mémoire du pod. Si le tas JVM atteint d'abord la limite du pod, le tueur OOM de Linux termine le pod avant que la JVM ne puisse écrire le vidage.

Utilisez un CNFS dédié pour les vidages de tas. Un seul événement OOM peut générer un fichier .hprof de plusieurs gigaoctets, susceptible d'épuiser le quota partagé et de perturber les opérations.

Synchronisez l'image File Browser avant de commencer. L'image docker.io/filebrowser/filebrowser:v2.18.0 peut échouer au téléchargement en raison de restrictions réseau. Synchronisez-la avec votre instance ACR Enterprise Edition en vous abonnant aux images provenant de l'extérieur de la Chine :

Champ Valeur
Artifact source Docker Hub
Source repository coordinates filebrowser/filebrowser
Subscription policy v2.18.0
Après la synchronisation, configurez le téléchargement d'images sans mot de passe entre l'instance ACR Enterprise Edition et votre cluster ACK.

Déploiement de l'application Java

Déployez un déploiement Java avec un stockage pris en charge par CNFS comme destination des vidages de tas. L'image d'exemple registry.cn-hangzhou.aliyuncs.com/acs1/java-oom-test:v1.0 exécute Mycode avec une limite de tas de 80 MiB.

Le déploiement utilise subPathExpr: $(POD_NAMESPACE).$(POD_NAME) pour créer des sous-répertoires par pod dans le volume NAS partagé, empêchant ainsi les redémarrages de pods d'écraser les vidages des autres.

subPathExpr utilise des parenthèses — $(POD_NAME) — et non des accolades. Les valeurs proviennent des variables d'environnement Downward API POD_NAME et 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

Vérification de l'événement OOM

Une fois le déploiement démarré, Mycode alloue de la mémoire jusqu'à ce que la JVM épuise le tas de 80 MiB et déclenche une erreur OOM. Le pod redémarre et ACK enregistre une alerte back-off restarting dans le centre d'événements.

Pour confirmer la survenue de l'erreur OOM :

  1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Recherchez votre cluster et cliquez sur son nom. Dans le volet de navigation de gauche, choisissez Operations > Event Center.

  3. Vérifiez la liste des événements pour détecter une alerte back-off restarting sur le pod java-application.

    3e0492283c067026c9cfd348a898ecb1

Parcours des fichiers de vidage de tas

Déployez File Browser avec le même PVC CNFS monté sur rootDir pour parcourir et télécharger les vidages de tas.

Déploiement 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

Sortie attendue :

configmap/filebrowser unchanged
deployment.apps/filebrowser configured

Création d'un service

  1. Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Recherchez votre cluster et cliquez sur son nom. Dans le volet de navigation de gauche, choisissez Network > Services.

  3. Sur la page Services, sélectionnez l'espace de noms default et cliquez sur Create. Configurez les paramètres suivants :

    Consultez la présentation de la facturation NLB .
    Paramètre Valeur
    Name filebrowser
    Service type SLB > SLB type: CLB. Sélectionnez Create Resource, puis définissez Access method sur Public Access.
    Backend Cliquez sur +Reference Workload Label. Définissez Resource type sur Deployments et Resources sur filebrowser.
    Port mapping Service port : 8080, Container port : 80, Protocol : TCP
  4. Envoyez la configuration.

Accès à File Browser

  1. Copiez l'adresse du point de terminaison depuis la page Services.

  2. Ouvrez <endpoint-address>:8080 dans un navigateur. La page de connexion File Browser s'affiche.

  3. Connectez-vous avec les identifiants par défaut : nom d'utilisateur admin, mot de passe admin.

    20fe4dcde1759ebc64cbe0b1bb3168da

  4. Double-cliquez sur rootdir pour accéder au point de montage NAS.

    image

Résultat

Dans rootdir, le répertoire de vidage de chaque pod est nommé selon la règle subPathExpr: $(POD_NAMESPACE).$(POD_NAME) — par exemple, default.java-application-76d8cd95b7-prrl2.

image

Ouvrez le répertoire pour trouver java_pid1.hprof. Téléchargez-le et analysez-le avec Eclipse Memory Analyzer (MAT) pour identifier le code ayant provoqué l'erreur OOM.

lQLPJxMFSGyoLcnNAqTNB2awoAbbe3-kh8AIV2X4pMttAA_1894_676

Fonctionnement

Trois mécanismes permettent de conserver les vidages de tas lors des redémarrages de pods :

  • PVC CNFS avec ReadWriteMany : Le PVC sauvegardé par NAS est monté dans les pods java-application et File Browser. NAS conserve les fichiers indépendamment du cycle de vie des pods, de sorte que les fichiers de vidage survivent aux plantages des pods.

  • subPathExpr avec Downward API : Chaque pod monte son propre sous-répertoire (<namespace>.<pod-name>) plutôt que la racine NAS, ce qui empêche les redémarrages d'écraser les vidages et facilite le traçage des vidages vers les pods.

  • -XX:+HeapDumpOnOutOfMemoryError : La JVM écrit l'état du tas dans -XX:HeapDumpPath avant de quitter en cas d'erreur OOM. Comme ce chemin est sauvegardé par NAS, le fichier survit à la sortie du pod.