Troubleshooting Infrastrutturale
Catalogo Problemi Comuni
Ogni problema e documentato con: sintomi, diagnosi, risoluzione e prevenzione.
1. NATS Reconnection Loop
Sintomi
- Log ripetuti:
NATS connection lost. Reconnecting...eNATS connected - Incremento della metrica
pos_nats_reconnections_total - Timeout sporadici nelle chiamate tra servizi
- Alert
NatsReconnectionStormin firing
Diagnosi
# Verificare lo stato dei pod NATS
kubectl get pods -n pos-enterprise -l app=nats
# Log del server NATS
kubectl logs -n pos-enterprise nats-0 --tail=50
# Verificare connessioni attive
kubectl exec -n pos-enterprise nats-0 -- nats server info
# Verificare rete tra nodi
kubectl exec -n pos-enterprise pos-core-xxxxx -- nslookup nats.pos-enterprise.svc.cluster.local
kubectl exec -n pos-enterprise pos-core-xxxxx -- nc -zv nats.pos-enterprise.svc.cluster.local 4222
Risoluzione
# Caso 1: Pod NATS in stato anomalo - restart
kubectl rollout restart statefulset -n pos-enterprise nats
# Caso 2: Rete instabile - verificare i nodi K8s sottostanti
kubectl get nodes -o wide
kubectl describe node <node-name> | grep -A10 "Conditions"
# Caso 3: Troppe connessioni - verificare il numero di client
kubectl exec -n pos-enterprise nats-0 -- nats server report connections
# Se > 500, verificare che non ci siano pod zombie
Prevenzione
- Configurare
maxReconnectAttempts: -1ereconnectTimeWait: 2000nei client - Monitorare
pos_nats_reconnections_totalcon alert a soglia 5/10min
2. Redis CROSSSLOT Error
Sintomi
- Errore nei log:
CROSSSLOT Keys in request don't hash to the same slot - Operazioni multi-key falliscono (MGET, pipeline, transazioni)
- Errori intermittenti nelle azioni che usano cache Moleculer
Diagnosi
# Identificare il servizio che genera l'errore
# Cercare nei log Loki:
# {namespace="pos-enterprise"} |= "CROSSSLOT"
# Verificare la configurazione Redis
kubectl exec -n pos-enterprise pos-core-xxxxx -- node -e "
const redis = require('ioredis');
const client = new redis(process.env.REDIS_URI);
client.cluster('info').then(console.log);
"
Risoluzione
Il problema si verifica con Redis Cluster quando le chiavi di un'operazione multi-key appartengono a slot diversi.
// Soluzione 1: Usare hash tags per forzare le chiavi nello stesso slot
// PRIMA (chiavi in slot diversi):
await redis.mget("MOL-products:list", "MOL-products:count");
// DOPO (chiavi nello stesso slot via hash tag):
await redis.mget("MOL-{products}:list", "MOL-{products}:count");
// Soluzione 2: Sostituire operazioni multi-key con pipeline individuali
const pipeline = redis.pipeline();
keys.forEach(k => pipeline.get(k));
const results = await pipeline.exec();
Prevenzione
- Nella configurazione del cacher Moleculer, il prefisso chiave include gia il nome del servizio
- Evitare operazioni
MGET/MSETcross-servizio nel codice custom - Testare con Redis Cluster in ambiente staging
3. MongoDB Connection Pool Exhaustion
Sintomi
- Errore:
MongoServerError: connection pool exhausted - Timeout nelle operazioni di lettura/scrittura
- Latenza improvvisamente alta su tutte le azioni che accedono a MongoDB
- Alert
MongoPoolExhaustionin firing
Diagnosi
# Verificare le connessioni attive nel pool
kubectl exec -n pos-enterprise pos-core-xxxxx -- node -e "
const client = require('./src/db-connection').getClient();
const pool = client.topology.s.pool;
console.log('Available:', pool.availableConnectionCount);
console.log('Total:', pool.totalConnectionCount);
console.log('WaitQueue:', pool.waitQueueSize);
"
# Verificare connessioni lato MongoDB Atlas
# Atlas UI > Database > Metrics > Connections
# Cercare query lente che tengono occupate le connessioni
kubectl exec -n pos-enterprise pos-core-xxxxx -- node -e "
const client = require('./src/db-connection').getClient();
client.db('admin').command({ currentOp: true, secs_running: { \$gt: 5 } })
.then(ops => console.log(JSON.stringify(ops.inprog.length, null, 2)));
"
Risoluzione
# Caso 1: Query lente - identificare e terminare
# Dall'Atlas UI: Activity > Real-Time Performance Panel
# Oppure terminare manualmente:
mongosh --eval "db.currentOp().inprog.filter(o => o.secs_running > 30).forEach(o => db.killOp(o.opid))"
# Caso 2: Pool troppo piccolo - aumentare temporaneamente
# Modificare il ConfigMap e restart
kubectl edit configmap -n pos-enterprise moleculer-config
# Cambiare maxPoolSize da 50 a 100
kubectl rollout restart deployment -n pos-enterprise pos-core
# Caso 3: Leak di connessioni - restart del pod
kubectl delete pod -n pos-enterprise pos-core-xxxxx
Prevenzione
- Monitorare
pos_mongodb_pool_availablecon alert a < 10% - Timeout su tutte le query:
socketTimeoutMS: 45000 - Review periodica delle query lente (Atlas Performance Advisor)
4. Certificate Renewal Failure
Sintomi
- Errore nei browser:
NET::ERR_CERT_DATE_INVALID - Pod non raggiungibili via Ingress HTTPS
- Log cert-manager:
Failed to renew certificate
Diagnosi
# Verificare lo stato dei certificati
kubectl get certificates -n pos-enterprise
kubectl get certificaterequests -n pos-enterprise
kubectl get orders.acme.cert-manager.io -n pos-enterprise
# Dettaglio del certificato problematico
kubectl describe certificate -n pos-enterprise pos-tls
# Log di cert-manager
kubectl logs -n cert-manager deployment/cert-manager --tail=50
kubectl logs -n cert-manager deployment/cert-manager-webhook --tail=30
# Verificare la scadenza del certificato attuale
kubectl get secret -n pos-enterprise pos-tls -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -noout -dates
Risoluzione
# Caso 1: Challenge DNS/HTTP fallita - verificare la configurazione
kubectl describe challenge -n pos-enterprise
# Caso 2: Rate limit Let's Encrypt - attendere o usare staging
kubectl get clusterissuer letsencrypt-prod -o yaml | grep -A5 "status"
# Caso 3: Forzare il rinnovo (eliminare il secret per triggerare il rinnovo)
kubectl delete secret -n pos-enterprise pos-tls
# cert-manager creera automaticamente un nuovo certificato
# Caso 4: Certificato scaduto e cert-manager non funziona
# Usare un certificato self-signed temporaneo
openssl req -x509 -nodes -days 7 -newkey rsa:2048 \
-keyout /tmp/tls.key -out /tmp/tls.crt \
-subj "/CN=platform.sellogic.cloud"
kubectl create secret tls pos-tls-temp -n pos-enterprise \
--cert=/tmp/tls.crt --key=/tmp/tls.key
# Aggiornare l'Ingress per usare pos-tls-temp
Prevenzione
- Alert su certificati in scadenza entro 14 giorni:
certmanager_certificate_expiration_timestamp_seconds - time() < 14 * 24 * 3600 - Verificare che cert-manager sia healthy:
kubectl get pods -n cert-manager
5. DNS Resolution Issues
Sintomi
- Errore nei log:
getaddrinfo ENOTFOUNDoEAI_AGAIN - Timeout nella connessione a servizi esterni (MongoDB Atlas, Redis Cloud, Keycloak)
- Intermittente: funziona e poi non funziona
Diagnosi
# Testare la risoluzione DNS dall'interno di un pod
kubectl exec -n pos-enterprise pos-core-xxxxx -- nslookup pos-production.xxxxx.mongodb.net
kubectl exec -n pos-enterprise pos-core-xxxxx -- nslookup redis-cloud.xxxxx.cloud.redislabs.com
# Verificare lo stato di CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=30
# Verificare la configurazione DNS del pod
kubectl exec -n pos-enterprise pos-core-xxxxx -- cat /etc/resolv.conf
# Test di latenza DNS
kubectl exec -n pos-enterprise pos-core-xxxxx -- \
sh -c "time nslookup pos-production.xxxxx.mongodb.net"
Risoluzione
# Caso 1: CoreDNS sovraccarico - restart
kubectl rollout restart deployment -n kube-system coredns
# Caso 2: ndots troppo alto (troppe query DNS ricorsive)
# Aggiungere dnsConfig ai deployment:
# spec.template.spec.dnsConfig:
# options:
# - name: ndots
# value: "2" # Default e 5, ridurre a 2
# Caso 3: Cache DNS scaduta - forzare il flush
kubectl exec -n pos-enterprise pos-core-xxxxx -- \
sh -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf.tmp"
# NOTA: non modificare resolv.conf in produzione, usare solo per debug
Prevenzione
- Monitorare la latenza DNS tramite la dashboard CoreDNS in Grafana
- Configurare
dnsConfig.options.ndots: 2su tutti i Deployment - Per servizi esterni, considerare l'uso di
hostAliasescome fallback
6. Image Pull Errors
Sintomi
- Pod in stato
ImagePullBackOffoErrImagePull - Evento:
Failed to pull image "registry.sellogic.cloud/impronto/core:2.4.1"
Diagnosi
# Verificare lo stato del pod
kubectl describe pod -n pos-enterprise pos-core-xxxxx | grep -A10 "Events"
# Verificare il secret per il registry
kubectl get secret -n pos-enterprise regcred -o yaml
# Testare l'accesso al registry
kubectl run test-pull --image=registry.sellogic.cloud/impronto/core:2.4.1 \
--restart=Never -n pos-enterprise --dry-run=client -o yaml
Risoluzione
# Caso 1: Credenziali scadute - ricreare il secret
kubectl delete secret -n pos-enterprise regcred
kubectl create secret docker-registry regcred \
-n pos-enterprise \
--docker-server=registry.sellogic.cloud \
--docker-username=<user> \
--docker-password=<password>
# Caso 2: Tag immagine non esistente - verificare
# Controllare nel CI/CD che il tag sia stato pushato
# Usare un tag esistente o rilanciare la pipeline
# Caso 3: Registry non raggiungibile - verificare rete
kubectl exec -n pos-enterprise pos-core-xxxxx -- \
nc -zv registry.sellogic.cloud 443
7. Comandi Diagnostici Generali
# Panoramica rapida dello stato del namespace
kubectl get all -n pos-enterprise
# Pod con problemi
kubectl get pods -n pos-enterprise --field-selector=status.phase!=Running,status.phase!=Succeeded
# Eventi recenti (ordinati per tempo)
kubectl get events -n pos-enterprise --sort-by='.lastTimestamp' | tail -30
# Risorse utilizzate vs disponibili
kubectl top pods -n pos-enterprise --sort-by=cpu
kubectl top nodes
# Log aggregati di un deployment (ultime 100 righe)
kubectl logs -n pos-enterprise deployment/pos-core --tail=100 --all-containers
# Log del container precedente (dopo un crash)
kubectl logs -n pos-enterprise pos-core-xxxxx --previous
# Esecuzione di debug in un pod
kubectl exec -it -n pos-enterprise pos-core-xxxxx -- /bin/sh
Quando Contattare i Cloud Provider
| Provider | Quando Contattare | Canale |
|---|---|---|
| MongoDB Atlas | Pool exhaustion persistente dopo tuning, performance degradation inspiegabile, backup failure | Atlas Support (portale) |
| Redis Cloud | CROSSSLOT non risolvibile, latenza anomala persistente, memory issues su piano managed | Redis Support (portale) |
| IBM Cloud (K8s) | Nodi unreachable, problemi di rete persistenti, control plane degradato | IBM Cloud Support (ticket) |
| AWS (S3) | Errori 5xx persistenti (estremamente raro), problemi di billing | AWS Support (console) |
| Let's Encrypt | Rate limit raggiunto su produzione (non staging) | Community forum |
Prima di Contattare il Provider
Raccogliere sempre: timestamp dell'inizio del problema, log rilevanti, metriche (screenshot Grafana), comandi diagnostici eseguiti e loro output. Questo accelera significativamente la risoluzione.
Riferimenti Incrociati
- Stack di Monitoring: Panoramica - Strumenti di osservabilita
- Analisi Log con Loki - Query per trovare la causa root
- Sistema di Alerting - Alert correlati ai problemi
- Disaster Recovery e Backup - Quando il troubleshooting non basta
- Health Check e Probes - Diagnosi via endpoint di health
Questa pagina ti è stata utile?