Metodología sistemática para resolver incidencias en despliegues de Kubernetes

Al desplegar una aplicación en Kubernetes, la arquitectura de red se fundamenta en tres recursos primordiales: el Deployment (que gestiona los réplicas de Pods), el Service (que actúa como balanceador de carga interno) y el Ingress (que enruta el tráfico externo hacia el Service). Comprender la interconexión exacta de estos elementos es el primer paso para diagnosticar errores de conectividad y dsepliegue.

Interconexión de los recursos fundamentales

Un error conceptual común es asumir que el Deployment y el Service están vinculados directamente. En realidad, el Service apunta a los Pods, ignorando por completo al Deployment. Por lo tanto, el enfoque debe estar en cómo los Pods y los Services se asocian entre sí.

A continuación, se presenta una configuración moderna y actualizada que ilustra estas relaciones:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-backend-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      component: api
  template:
    metadata:
      labels:
        component: api
    spec:
      containers:
      - name: api-container
        image: registry.internal/api-service:v2.4
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: api-backend-svc
spec:
  selector:
    component: api
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-backend-ingress
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-backend-svc
            port:
              number: 8080

Para evitar conflictos de red, es crucial verificar las siguientes reglas de enlace:

  • El selector del Service (component: api) debe coincidir exactamente con las etiquetas definidas en la plantilla del Pod.
  • El targetPort del Service (3000) debe ser idéntico al containerPort expuesto por el contenedor.
  • El port del Service (8080) es el puerto interno del clúster y puede ser cualquier valor disponible; múltiples Services pueden usar el mismo puerto interno.
  • En el Ingress (utilizando la API v1), el campo service.name debe coincidir con el nombre del Service, y service.port.number debe coincidir con el port del Service.

Validación de la conectividad

Para verificar que el Service enruta correctamente el tráfico a los Pods, se puede utilizar el reenvío de puertos local:

kubectl port-forward svc/api-backend-svc 4000:8080

Al acceder a localhost:4000, la solicitud se reenvía al puerto 8080 del Service, que a su vez la dirige al puerto 3000 del Pod. Si la conexión falla, el problema reside en las etiquetas o en la configuración de puertos.

Para validar el Ingress, el reenvío de puertos debe apuntar directamente al Pod del controlador de Ingress (por ejemplo, NGINX Ingress Controller):

kubectl get pods -n ingress-nginx
kubectl port-forward pod/ingress-nginx-controller-xyz 4000:80 -n ingress-nginx

Protocolo de diagnóstico en tres niveles

Cuando un despliegue falla, el diagnóstico debe seguir un enfoque ascendente: comenzar desde la capa más baja (el Pod) y avanzar hacia la capa de red externa (Ingress).

1. Diagnóstico a nivel de Pod

La mayoría de los fallos se originan en el propio Pod. El primer paso es verificar su estado:

kubectl get pods -l component=api

Si el Pod no está en estado Running o Ready, se deben utilizar los siguientes comandos para extraer información:

  • kubectl logs <pod-name>: Para inspeccionar los registros de la aplicación.
  • kubectl describe pod <pod-name>: Para revisar eventos del clúster y errores de programación.
  • kubectl exec -it <pod-name> -- sh: Para ejecutar comandos interactivos dentro del contenedor.

Errores de inicio comunes:

  • ImagePullBackOff / ErrImagePull: Indica que el contenedor no puede descargar la imagen. Las causas típicas son errores tipográficos en el nombre de la imagen, etiquetas (tags) inexistentes o falta de credenciales (imagePullSecrets) para repositorios privados.
  • CrashLoopBackOff: El contenedor se inicia pero termina abruptamente. Esto suele deberse a errores en el código de la aplicación, configuraciones de entorno incorrectas o fallos en las sondas de liveness (livenessProbe). Si el contenedor se reinicia muy rápido, use kubectl logs <pod-name> --previous para ver los registros de la instancia anterior.
  • RunContainerError: Fallo antes de que la aplicación se ejecute, generalmente por montar volúmenes inexistentes (ConfigMaps o Secrets faltantes) o problemas de permisos de sistema de archivos.

Estado Pending o Not Ready:

  • Si el Pod está Pending, el planificador (scheduler) no puede asignarlo. Esto ocurre por falta de recursos (CPU/Memoria) en los nodos, violaciones de ResourceQuota o dependencias de PersistentVolumeClaim no resueltas.
  • Si el Pod está Running pero no Ready, la sonda de preparación (readinessProbe) está fallando. El Pod no recibirá tráfico del Service hasta que esta sonda sea exitosa.

2. Diagnóstico a nivel de Service

Si los Pods están sanos pero la aplicación no responde, el problema puede estar en el Service. El objetivo es verificar si el Service está descubriendo los Pods correctos mediante sus Endpoints:

kubectl describe svc api-backend-svc | grep Endpoints

Si la lista de Endpoints está vacía, el Service no encuentra ningún Pod. Las causas son:

  • Los Pods no tienen la etiqueta exacta que busca el selector del Service.
  • Los Pods y el Service están en namespaces diferentes y no se está utilizando un servicio externo o DNS cruzado.

Si los Endpoints están poblados pero la conexión falla, verifique que el targetPort del Service coincida con el puerto real en el que escucha el proceso dentro del contenedor.

3. Diagnóstico a nivel de Ingress

Si el Service funciona correctamente pero el tráfico externo no llega, el fallo reside en la configuración del Ingress o en el controlador subyacente.

Verifique la configuración del recurso Ingress:

kubectl describe ingress api-backend-ingress

Revise la columna Backends. Si está vacía o muestra errores, hay un desajuste entre el service.name o service.port.number definidos en el Ingress y el Service real.

Para aislar si el problema es del Ingress o de la infraestructura de red (como un balanceador de carga externo o reglas de firewall), realice un port-forward directamente al Pod del controlador de Ingress, como se mostró anteriormente. Si el tráfico fluye mediante el port-forward al controlador, el Ingress está bien configurado y el problema es de red externa.

Depuración específica para Ingress NGINX

Si se utiliza el controlador Ingress-NGINX, existe un plugin oficial de kubectl que facilita la inspección profunda. Tras instalarlo, se pueden ejecutar comandos específicos:

  • kubectl ingress-nginx lint: Valida la sintaxis y configuración del archivo nginx.conf genreado.
  • kubectl ingress-nginx backends: Muestra los backends configurados y sus endpoints actuales, útil para confirmar si NGINX ha sincronizado los Endpoints del Service.
  • kubectl ingress-nginx logs: Inspecciona los registros de acceso y error del controlador NGINX para identificar rechazos de conexión o errores 502/504.

Es fundamental especificar el namespace correcto utilizando la bandera --namespace o -n al ejecutar estos comandos, ya que el controlador suele desplegarse en un namespace dedicado como ingress-nginx o kube-system.

Etiquetas: Kubernetes kubernetes-deployment kubernetes-ingress kubectl k8s-debugging

Publicado el 7-11 09:26