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
ServiceNotAvailableErroro 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 KilledBack-off restarting failed containerError: secret "xxx" not foundError: 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
initialDelaySecondssia sufficiente per il boot del servizio. - Resource limits adeguati: impostare
requestselimitsbasati 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
IfNotPresentcon tag immutabili (digest SHA).
Escalation
| Livello | Condizione | Contatto |
|---|---|---|
| L1 - Ops | Pod singolo in crash, altri pod sani | Team Ops (Slack #pos-ops) |
| L2 - Dev | Crash causato da bug applicativo | Team Dev (Slack #pos-dev) |
| L3 - Infra | Tutti i pod di un deployment in crash | DevOps Lead + CTO |
| L4 - Vendor | Problema su MongoDB Atlas / Redis Cloud / NATS | Aprire 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?