Skip to main content

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... e NATS connected
  • Incremento della metrica pos_nats_reconnections_total
  • Timeout sporadici nelle chiamate tra servizi
  • Alert NatsReconnectionStorm in 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: -1 e reconnectTimeWait: 2000 nei client
  • Monitorare pos_nats_reconnections_total con 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/MSET cross-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 MongoPoolExhaustion in 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_available con 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 ENOTFOUND o EAI_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: 2 su tutti i Deployment
  • Per servizi esterni, considerare l'uso di hostAliases come fallback

6. Image Pull Errors

Sintomi

  • Pod in stato ImagePullBackOff o ErrImagePull
  • 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

ProviderQuando ContattareCanale
MongoDB AtlasPool exhaustion persistente dopo tuning, performance degradation inspiegabile, backup failureAtlas Support (portale)
Redis CloudCROSSSLOT non risolvibile, latenza anomala persistente, memory issues su piano managedRedis Support (portale)
IBM Cloud (K8s)Nodi unreachable, problemi di rete persistenti, control plane degradatoIBM Cloud Support (ticket)
AWS (S3)Errori 5xx persistenti (estremamente raro), problemi di billingAWS Support (console)
Let's EncryptRate 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

Questa pagina ti è stata utile?