Skip to main content

Runbook: Pod in CrashLoopBackOff

Severita: Critical Alert Prometheus: PodCrashLooping

Descrizione

Questo alert si attiva quando un pod nel namespace pos-enterprise entra in stato CrashLoopBackOff, ovvero il container si avvia, fallisce e viene riavviato ripetutamente da Kubernetes con backoff esponenziale. Il pod non riesce a completare la fase di startup e non serve traffico.

La regola Prometheus associata:

increase(kube_pod_container_status_restarts_total{namespace="pos-enterprise"}[1h]) > 5

Impatto

  • Servizio degradato o non disponibile: il nodo Moleculer associato al pod non risponde alle action call via NATS.
  • Cascata di errori: i servizi che dipendono dal nodo in crash ricevono ServiceNotAvailableError o timeout, attivando i circuit breaker.
  • Perdita di capacita: il cluster opera con meno repliche, aumentando il carico sui pod restanti.
  • Impatto utente: se il pod e un gateway (api-gateway), gli utenti ricevono errori HTTP 502/503.

Diagnosi

1. Identificare il pod in crash

kubectl get pods -n pos-enterprise --field-selector=status.phase!=Running
kubectl get pods -n pos-enterprise | grep CrashLoopBackOff

2. Controllare gli eventi del pod

kubectl describe pod <POD_NAME> -n pos-enterprise

Cercare nella sezione Events messaggi come:

  • OOMKilled → vedere runbook OOM Killed
  • Back-off restarting failed container
  • Error: secret "xxx" not found
  • Error: configmap "xxx" not found

3. Leggere i log del container in crash

# Log dell'ultimo tentativo di avvio
kubectl logs <POD_NAME> -n pos-enterprise --previous

# Log in tempo reale (se il pod riesce ad avviarsi brevemente)
kubectl logs <POD_NAME> -n pos-enterprise -f

4. Verificare le variabili d'ambiente

kubectl get pod <POD_NAME> -n pos-enterprise -o jsonpath='{.spec.containers[0].env[*]}' | jq .

5. Controllare la connettivita ai servizi esterni

# Spawn di un pod di debug per testare la rete
kubectl run debug-net --rm -it --image=nicolaka/netshoot -n pos-enterprise -- bash

# Dal pod di debug, testare:
# MongoDB Atlas
nslookup cluster0.xxxxx.mongodb.net
nc -zv cluster0.xxxxx.mongodb.net 27017

# NATS
nc -zv nats.sellogic.cloud 4222

# Redis Cloud
nc -zv redis-xxxxx.cloud.redislabs.com 16379

# Keycloak
curl -s https://auth.sellogic.cloud/realms/pos/.well-known/openid-configuration | head -5

6. Controllare le risorse del nodo

kubectl top nodes
kubectl describe node <NODE_NAME> | grep -A 5 "Allocated resources"

Risoluzione

Causa: Errore di configurazione (env var mancanti o errate)

# Verificare che i secret esistano
kubectl get secrets -n pos-enterprise

# Verificare i valori (decodificati)
kubectl get secret pos-enterprise-secrets -n pos-enterprise -o jsonpath='{.data.MONGO_URI}' | base64 -d

# Se manca un secret, ricrearlo
kubectl create secret generic pos-enterprise-secrets -n pos-enterprise \
--from-literal=MONGO_URI="mongodb+srv://..." \
--from-literal=REDIS_URL="redis://..." \
--dry-run=client -o yaml | kubectl apply -f -

Causa: Connessione al database fallita

# Verificare lo stato di MongoDB Atlas dalla dashboard o con mongosh
mongosh "mongodb+srv://cluster0.xxxxx.mongodb.net/pos_platform" --username admin

# Verificare che l'IP del cluster K8s sia nella whitelist di Atlas
# Dashboard Atlas → Network Access → IP Access List

Causa: Immagine Docker non trovata o corrotta

kubectl get pod <POD_NAME> -n pos-enterprise -o jsonpath='{.spec.containers[0].image}'

# Verificare che l'immagine esista nel registry
docker manifest inspect <IMAGE_NAME>:<TAG>

Causa: OOMKilled

Vedere il runbook dedicato: OOM Killed

Rollback del deployment

Se il crash e stato introdotto da un deploy recente:

# Verificare la storia dei rollout
kubectl rollout history deployment/<DEPLOYMENT_NAME> -n pos-enterprise

# Rollback alla revisione precedente
kubectl rollout undo deployment/<DEPLOYMENT_NAME> -n pos-enterprise

# Rollback a una revisione specifica
kubectl rollout undo deployment/<DEPLOYMENT_NAME> -n pos-enterprise --to-revision=<N>

# Verificare che il rollback sia completato
kubectl rollout status deployment/<DEPLOYMENT_NAME> -n pos-enterprise

Riavvio manuale

# Riavvio rolling del deployment
kubectl rollout restart deployment/<DEPLOYMENT_NAME> -n pos-enterprise

# Se necessario, eliminare il singolo pod per forzare la ri-creazione
kubectl delete pod <POD_NAME> -n pos-enterprise

Prevenzione

  • Readiness e liveness probe configurati correttamente: ogni nodo Moleculer espone l'health check su porta 3001. Assicurarsi che initialDelaySeconds sia sufficiente per il boot del servizio.
  • Resource limits adeguati: impostare requests e limits basati sul profiling reale dei servizi.
  • Pre-deploy validation: verificare che tutti i ConfigMap e Secret referenziati esistano prima del deploy.
  • CI/CD con canary deploy: introdurre cambiamenti gradualmente per individuare problemi prima del rollout completo.
  • Monitoraggio delle immagini: utilizzare image pull policy IfNotPresent con tag immutabili (digest SHA).

Escalation

LivelloCondizioneContatto
L1 - OpsPod singolo in crash, altri pod saniTeam Ops (Slack #pos-ops)
L2 - DevCrash causato da bug applicativoTeam Dev (Slack #pos-dev)
L3 - InfraTutti i pod di un deployment in crashDevOps Lead + CTO
L4 - VendorProblema su MongoDB Atlas / Redis Cloud / NATSAprire ticket con il provider

Tempo massimo di risposta: 15 minuti per alert Critical durante orario di servizio (07:00-24:00).

Questa pagina ti è stata utile?