Skip to main content
Esta guía te ayuda a diagnosticar y resolver problemas comunes al desplegar u operar Midaz en Kubernetes con Helm.

Comandos generales de diagnóstico


Empieza con estos comandos para obtener un panorama amplio del estado de tu despliegue.

Pods atascados en Pending


Síntoma: uno o más pods permanecen en estado Pending y nunca arrancan. Comandos de diagnóstico:
Causas comunes y soluciones:
  • CPU o memoria insuficientes en los nodos. El scheduler no puede encontrar un nodo que satisfaga los resource requests del pod. Revisa la sección Events de kubectl describe pod. Busca mensajes como Insufficient cpu o Insufficient memory. Reduce resources.requests en tu values.yaml o agrega más nodos al cluster.
  • PersistentVolumeClaim sin vincular. Un PVC requerido por una dependencia (PostgreSQL, MongoDB, Valkey) está atascado en Pending.
    Verifica que haya una StorageClass disponible y que sea la predeterminada. Consulta PVC atascado en Pending más abajo.
  • Node selector o afinidad que no coinciden. El pod requiere una etiqueta de nodo específica que ningún nodo del cluster tiene. Revisa los ajustes de nodeSelector o affinity en tu values.yaml y verifica que tus nodos tienen las etiquetas esperadas:

ImagePullBackOff


Síntoma: los pods muestran el estado ImagePullBackOff o ErrImagePull. Comandos de diagnóstico:
Causas comunes y soluciones:
  • Tag de imagen incorrecto. El tag especificado no existe en el registry. Inspecciona el paquete del chart seleccionado y compara ledger.image.tag con sus metadatos y values. La página de versiones del chart de Midaz registra el valor predeterminado auditado.
  • El registry privado requiere autenticación. El cluster no puede descargar imágenes sin credenciales. Crea un image pull secret y referéncialo en tu values.yaml:
  • Falta imagePullSecrets. El secret existe pero la configuración del componente no lo referencia. Define imagePullSecrets para todos los componentes afectados.

CrashLoopBackOff


Síntoma: los pods arrancan y se caen de inmediato, reiniciándose repetidamente. Comandos de diagnóstico:
Usa --previous para ver los logs de la última instancia del contenedor que se cayó, no la que se está reiniciando ahora.
Causas comunes y soluciones:
  • Variables de entorno incorrectas o ausentes. Falta una clave de configuración obligatoria o tiene un valor incorrecto. Revisa los logs en busca de mensajes como missing env var, invalid config o similares. Revisa la sección configmap de tu values.yaml.
  • Falta un Secret de Kubernetes. El pod referencia un secret que no existe.
    Si el secret no existe, créalo manualmente o vuelve a ejecutar la instalación con Helm.
  • Credenciales de base de datos incorrectas. El servicio no puede autenticarse con PostgreSQL, MongoDB o Redis. Revisa los logs en busca de authentication failed o connection refused. Verifica la sección secrets en tu values.yaml y confirma que las credenciales coinciden con las que usaste al provisionar las bases de datos.
  • OOMKilled. El contenedor superó su límite de memoria y el kernel lo terminó.
    Busca OOMKilled en la sección Last State. Aumenta resources.limits.memory en tu values.yaml. Consulta Desalojo de pods / OOMKilled más abajo.

Timeout de instalación de Helm


Síntoma: helm install o helm upgrade falla con un error de timeout antes de que el release alcance el estado deployed. Comandos de diagnóstico:
Causas comunes y soluciones:
  • Descargas de imagen lentas. Las imágenes grandes en una conexión lenta pueden superar el timeout predeterminado. Aumenta el timeout:
  • Init containers que fallan. Un init container (por ejemplo, el Job de bootstrap de la base de datos) se cuelga o reintenta. Revisa los logs del init container:
  • Probes de readiness que fallan. El pod se ejecuta pero no pasa su verificación de readiness, así que Helm espera indefinidamente. Describe el pod y mira las secciones Conditions y Events. Puedes necesitar aumentar initialDelaySeconds en los ajustes de tu probe de readiness, o investigar por qué el servicio no está sano al arrancar.

Servicios inalcanzables


Síntoma: las APIs de Midaz son inalcanzables desde fuera del cluster, o los servicios no pueden comunicarse internamente. Comandos de diagnóstico:
Causas comunes y soluciones:
  • Configuración incorrecta del ingress. El recurso Ingress existe pero el controller no lo toma. Verifica que ingress.className coincide con la clase del ingress controller que instalaste:
    Revisa también que el pod del ingress controller se ejecuta:
  • El DNS no apunta al load balancer. El hostname de tu Ingress no resuelve a la IP externa del controller. Obtén la IP externa y compárala con tu registro de DNS:
  • Configuración incorrecta de TLS. Un secret de TLS ausente o vencido hace que el ingress falle en silencio. Verifica que el secret existe y que no está vencido:
    Si usas cert-manager, revisa el estado del recurso Certificate:

PVC atascado en Pending


Síntoma: un PersistentVolumeClaim permanece en estado Pending y el pod dependiente no puede arrancar. Comandos de diagnóstico:
Causas comunes y soluciones:
  • No hay StorageClass predeterminada. El cluster no tiene una StorageClass predeterminada.
    Si ninguna muestra (default), crea una StorageClass o define una explícitamente en tu values.yaml para la dependencia afectada (por ejemplo, postgresql.primary.persistence.storageClass).
  • Modo de acceso incorrecto. La StorageClass no admite el modo de acceso que solicita el PVC (por ejemplo, ReadWriteMany en un driver de almacenamiento que solo admite ReadWriteOnce). Revisa la sección Events de kubectl describe pvc. Ajusta accessModes en tu values.yaml para que coincida con lo que admite tu StorageClass.
  • El modo de vinculación de volumen es WaitForFirstConsumer. Algunas StorageClasses usan vinculación diferida. El PVC permanece en Pending hasta que se programa un pod que lo consume. Este es el comportamiento normal. Espera a que se programe el pod.

Desalojo de pods / OOMKilled


Síntoma: los pods son desalojados repetidamente o muestran OOMKilled en su último estado. Comandos de diagnóstico:
Causas comunes y soluciones:
  • Límites de memoria demasiado bajos. El resources.limits.memory del contenedor está por debajo de lo que el servicio realmente necesita bajo carga. Revisa el uso actual de memoria con kubectl top pods y luego aumenta el límite en tu values.yaml: Los valores predeterminados del chart son requests: 256Mi / 1500m y limits: 512Mi / 2000m. Tu override los reemplaza, así que trata los valores predeterminados como la base de dimensionamiento. Define el límite de memoria por encima del predeterminado cuando el contenedor sufre OOMKilled:
  • Nodo con presión de memoria. El nodo mismo está bajo presión y el kubelet desaloja los pods de menor prioridad. Revisa las condiciones del nodo:
    Considera agregar nodos o habilitar el cluster autoscaler. También puedes definir PriorityClass en los pods de Midaz para protegerlos del desalojo.

Definiciones de RabbitMQ sin cargar


Síntoma: los servicios de Midaz arrancan pero las transacciones fallan, las colas no existen o los mensajes quedan sin procesar. Los logs pueden mostrar errores de conexión AMQP o exchanges/colas ausentes. Comandos de diagnóstico:
Los nombres de los Jobs de bootstrap son <release>-bootstrap-postgres, <release>-bootstrap-mongodb y <release>-bootstrap-rabbitmq. Definen ttlSecondsAfterFinished: 300, así que se eliminan solos cinco minutos después de terminar. Recolecta sus logs pronto o el comando devuelve NotFound.
Causas comunes y soluciones:
  • Al RabbitMQ externo le falta load_definitions.json. Cuando usas una instancia externa de RabbitMQ, las colas, los exchanges y los bindings requeridos no están presentes. Habilita el Job de bootstrap en tu values.yaml:
    O aplica las definiciones manualmente:
    El archivo load_definitions.json está en charts/midaz/files/rabbitmq/load_definitions.json en el repositorio de Helm.
  • El Job de bootstrap falló en silencio. El job se ejecutó pero encontró un error (credenciales incorrectas, timeout de red, puerto incorrecto).
    Verifica las credenciales de rabbitmqAdminLogin y que el puerto de gestión (predeterminado 15672) es alcanzable desde dentro del cluster.

Recursos relacionados