Kubernetes · Ingress · Traefik

404 page not found en un Ingress de k3s: por qué Traefik no llega a tu aplicación

Creaste el Deployment, el Service y el Ingress, kubectl apply no se quejó de nada, y curl devuelve 404 page not found. Esa respuesta no viene de tu aplicación: viene de Traefik, el controlador de Ingress que trae k3s, y quiere decir que ninguna de sus reglas coincidió con tu petición.

Paso 1. Confirmar quién responde el 404

$ kubectl get ingressclass
$ kubectl -n <ns> get ingress
$ kubectl -n <ns> describe ingress <nombre>

En get ingress mira tres columnas: CLASS, HOSTS y ADDRESS. En describe, cada ruta lista el Service y, entre paréntesis, las direcciones de los Pods que hay detrás. Si ves esas direcciones, Ingress, Service y Pods están conectados y el problema está en cómo haces la petición. Si ADDRESS sigue vacío pasados unos segundos, ningún controlador tomó tu Ingress.

Paso 2. Ubicar tu caso en la tabla

Lo que vesCausaCorrección
curl a la IP da 404 aunque todo está bienFalta el nombre de host: el Ingress solo atiende las peticiones cuyo encabezado Host coincide con host:Pide con el nombre: curl --resolve o -H "Host: app.ejemplo.com"
ADDRESS vacío para siempre y 404ingressClassName no coincide con ninguna clase de get ingressclass; Kubernetes acepta cualquier nombre sin dar errorPon el valor de la columna NAME: traefik en k3s, nginx con NGINX Ingress
describe no muestra direcciones de Pods en la rutaEl Ingress apunta a un Service de otro namespace; un Ingress solo envía tráfico a Services de su propio namespaceCrea el Ingress en el mismo namespace que el Service
https:// funciona y http:// da 404En Traefik, un Ingress con spec.tls no atiende el puerto 80Un segundo Ingress, sin spec.tls, para el puerto 80
Could not resolve hostEl nombre no existe en ningún DNS (sistema de nombres de dominio)curl --resolve o una línea en /etc/hosts

Paso 3. Probar con el nombre, sin tocar el DNS

$ IP_INGRESS=$(kubectl -n <ns> get ingress <nombre> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ curl -i http://"$IP_INGRESS"/                                         # sin nombre: 404 del controlador
$ curl -i --resolve app.ejemplo.com:80:"$IP_INGRESS" http://app.ejemplo.com/   # con nombre: tu aplicación

--resolve le dice a curl a qué IP ir para ese nombre, y manda el encabezado Host correcto. Si la primera da 404 y la segunda responde tu aplicación, no hay nada roto: solo faltaba el nombre. Ese 404 es buena señal, porque prueba que el controlador está vivo.

El YAML corregido

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tienda
  namespace: tienda            # el mismo namespace del Service
spec:
  ingressClassName: traefik    # el NAME de kubectl get ingressclass
  rules:
    - host: app.ejemplo.com    # solo atiende peticiones con este Host
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tienda
                port:
                  name: http   # el puerto del Service por su nombre

Si el 404 desaparece pero la aplicación no contesta, el siguiente sospechoso es el Service: revisa que tenga endpoints con la guía del Service que no responde.

¿Quieres provocarlo y arreglarlo sin romper nada tuyo? El laboratorio 04 del kit monta un Ingress con tres rutas, lo prueba con --resolve y con /etc/hosts, y en el paso 11 te pone una clase que no existe para que veas el síntoma completo.

Por qué pasa tanto

Porque un Ingress mal escrito no da ningún error: Kubernetes guarda el objeto aunque la clase no exista o el Service esté en otro namespace, y el controlador simplemente no encuentra una regla que coincida. El único aviso es ese 404 genérico, que se parece mucho a "mi aplicación no tiene esa ruta" y manda a buscar donde no es.

Practica Kubernetes en tu propio clúster, gratis

Te envío al correo dos laboratorios completos con su solución: el 01 (namespace y deployment) y el 08 (ResourceQuota). Cada uno termina con un comando de verificación, no con "parece que funcionó". El Ingress con Traefik es el laboratorio 04 del kit.

Quiero los 2 laboratorios gratis