Skip to main content

Runbook: Utilizzo Memoria Elevato

Severita: Warning Alert Prometheus: HighMemoryUsage

Descrizione

Questo alert si attiva quando un container nel namespace pos-enterprise utilizza piu dell'80% della memoria allocata come resources.limits.memory. E un segnale proattivo: se il consumo continua a crescere, il container verra terminato con OOMKill.

Regola Prometheus:

(container_memory_working_set_bytes{namespace="pos-enterprise", container!=""}
/ on(pod, container) kube_pod_container_resource_limits{namespace="pos-enterprise", resource="memory"})
> 0.8

Impatto

  • Rischio OOM imminente: se la memoria raggiunge il 100% del limite, il kernel termina il processo.
  • Degradazione prestazioni: il garbage collector di Node.js diventa aggressivo, causando pause frequenti e latenza elevata.
  • Swap thrashing: se il nodo K8s ha swap abilitato (sconsigliato), il sistema diventa estremamente lento.

Diagnosi

1. Identificare i pod con memoria alta

# Top pod per memoria
kubectl top pods -n pos-enterprise --sort-by=memory

# Pod sopra l'80% del limite
kubectl get pods -n pos-enterprise -o json | jq -r '
.items[] |
.metadata.name as $name |
.spec.containers[0].resources.limits.memory as $limit |
"\($name) - Limit: \($limit)"
'

2. Analisi storica in Grafana

Dashboard: https://grafana.sellogic.cloud/d/pos-memory

# Trend memoria ultimi 7 giorni per deployment
avg by (pod) (
container_memory_working_set_bytes{namespace="pos-enterprise", container="moleculer"}
) / 1024 / 1024
# Velocita di crescita (MB/ora) - utile per identificare memory leak
deriv(container_memory_working_set_bytes{namespace="pos-enterprise", container="moleculer"}[1h]) / 1024 / 1024 * 3600
# Confronto tra repliche dello stesso deployment
container_memory_working_set_bytes{namespace="pos-enterprise", pod=~"orders-node.*"}

3. Profiling memoria del processo Node.js

# Statistiche V8 heap via endpoint Moleculer interno
kubectl port-forward <POD_NAME> -n pos-enterprise 3001:3001

curl http://localhost:3001/api/~node/health | jq '.client.mem'
# Risposta: { rss, heapUsed, heapTotal, external, arrayBuffers }

4. Verificare la cache locale

I servizi Moleculer possono accumulare cache locale se Redis non e configurato correttamente:

# Verificare la configurazione del cacher
kubectl exec <POD_NAME> -n pos-enterprise -- \
node -e "const cfg = require('./moleculer.config'); console.log(JSON.stringify(cfg.cacher, null, 2))"

5. Controllare il numero di connessioni

# Connessioni TCP aperte dal processo
kubectl exec <POD_NAME> -n pos-enterprise -- \
sh -c "cat /proc/1/net/tcp | wc -l"

# Socket attivi
kubectl exec <POD_NAME> -n pos-enterprise -- \
sh -c "ls /proc/1/fd | wc -l"

6. Identificare servizi memory-intensive

Profilo tipico di consumo memoria per tipo di nodo:

NodoBaselineSotto caricoSospetto leak se
api-gateway120-180 MB200-350 MB> 400 MB stabile
orders-node100-150 MB180-300 MB> 350 MB stabile
products-node80-120 MB120-200 MB> 250 MB stabile
knowledge-node200-300 MB300-500 MB> 600 MB stabile
warehouse-node100-160 MB180-300 MB> 400 MB stabile

Risoluzione

Azione immediata: aumentare il limite

Se il pod e critico e il nodo ha risorse disponibili:

# Verificare risorse disponibili sul nodo
kubectl top nodes

# Patch del limite (esempio: da 512Mi a 768Mi)
kubectl patch deployment <DEPLOY_NAME> -n pos-enterprise --type='json' -p='[
{"op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/memory", "value": "768Mi"}
]'

Ottimizzazione: tuning GC Node.js

# Impostare il limite heap V8 al 75% del container limit
# Per un container con 512Mi di limit:
kubectl set env deployment/<DEPLOY_NAME> -n pos-enterprise \
NODE_OPTIONS="--max-old-space-size=384"

Ottimizzazione: pulizia cache Redis

# Verificare la dimensione della cache
kubectl run redis-cli --rm -it --image=redis:7-alpine -n pos-enterprise -- \
redis-cli -u "redis://:<password>@redis-xxxxx.cloud.redislabs.com:16379" info memory

# Pulire cache di un servizio specifico
kubectl run redis-cli --rm -it --image=redis:7-alpine -n pos-enterprise -- \
redis-cli -u "redis://:<password>@redis-xxxxx.cloud.redislabs.com:16379" \
--scan --pattern "MOL-pos-enterprise-orders.*" | xargs -L 100 redis-cli DEL

Ottimizzazione: ridurre il pool di connessioni MongoDB

# Verificare e ridurre maxPoolSize nel connection string
# Da: mongodb+srv://...?maxPoolSize=100
# A: mongodb+srv://...?maxPoolSize=20
kubectl edit secret pos-enterprise-secrets -n pos-enterprise

Investigazione memory leak

Se la memoria cresce linearmente nel tempo:

# Abilitare heap snapshot periodici (solo staging)
kubectl set env deployment/<DEPLOY_NAME> -n pos-enterprise \
NODE_OPTIONS="--max-old-space-size=384 --heap-prof --heap-prof-interval=600000"

# Dopo un periodo di osservazione, copiare i profili
kubectl cp pos-enterprise/<POD_NAME>:/app/Heap.*.heapprofile ./heap-profiles/

# Analizzare con Chrome DevTools → Memory → Load Profile

Prevenzione

  • Alert a soglie multiple: 70% (info), 80% (warning), 90% (critical).
  • Dashboard team: pannello dedicato in Grafana con trend di memoria per ogni deployment.
  • Review periodico dei limiti: ogni mese, confrontare l'uso reale con i limiti configurati.
  • Horizontal scaling: per servizi stateless, preferire piu repliche piccole a poche grandi.
  • Load testing mensile: simulare il carico di punta per validare i limiti in condizioni reali.
# Alert multi-soglia
groups:
- name: memory-alerts
rules:
- alert: HighMemoryWarning
expr: container_memory_working_set_bytes / on(pod,container) kube_pod_container_resource_limits > 0.8
for: 5m
labels:
severity: warning
- alert: HighMemoryCritical
expr: container_memory_working_set_bytes / on(pod,container) kube_pod_container_resource_limits > 0.9
for: 2m
labels:
severity: critical

Escalation

LivelloCondizioneContatto
L1 - OpsSingolo pod > 80%, stabileMonitorare, nessuna azione urgente
L1 - OpsTrend in crescita costanteAumentare limite, notificare Dev
L2 - DevSospetto memory leakTeam Dev - profiling e fix
L3 - InfraMultipli deployment > 80%DevOps Lead - scaling cluster

Tempo massimo di risposta: 30 minuti. Monitorare per 15 minuti prima di intervenire per escludere picchi temporanei.

Questa pagina ti è stata utile?