Capitulo 9: Ingress con Traefik

Por: Artiko
k3skubernetestraefikingressnetworking

Capitulo 9: Ingress con Traefik

< Volver al Indice del Tutorial

Traefik en K3s

K3s incluye Traefik como Ingress Controller por defecto. Cuando instalas K3s, Traefik se despliega automaticamente como un DaemonSet en el namespace kube-system. No necesitas instalar nada adicional para empezar a exponer tus aplicaciones al exterior.

Puedes verificar que Traefik esta corriendo:

kubectl get pods -n kube-system | grep traefik

La salida mostrara algo como:

traefik-6b84f97bf4-xxxxx   1/1   Running   0   5m

Traefik escucha en los puertos 80 (HTTP) y 443 (HTTPS) del nodo donde corre.

Que es un Ingress

Un Service de tipo ClusterIP solo es accesible dentro del cluster. Un NodePort expone un puerto alto en cada nodo. Ninguno de los dos permite routing basado en dominios o paths.

Un Ingress resuelve esto. Es un recurso de Kubernetes que define reglas de routing HTTP/HTTPS:

El Ingress por si solo no hace nada. Necesita un Ingress Controller (como Traefik) que lea las reglas y las aplique.

Ingress Basico

Supongamos que tienes un Deployment y un Service llamado mi-app corriendo en el puerto 80. Para exponerlo con un dominio:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mi-app-ingress
spec:
  rules:
    - host: app.midominio.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mi-app
                port:
                  number: 80

Aplica con:

kubectl apply -f mi-app-ingress.yaml

Verifica el Ingress creado:

kubectl get ingress

Ahora cualquier peticion HTTP a app.midominio.com sera enrutada al Service mi-app.

Routing por Host

Puedes dirigir multiples dominios a diferentes Services desde un solo Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  rules:
    - host: app1.midominio.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 80
    - host: app2.midominio.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service2
                port:
                  number: 80

Cada dominio debe apuntar a la IP de tu nodo K3s en tu DNS (registro A o CNAME).

Routing por Path

Para aplicaciones donde frontend y backend comparten dominio:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-routing-ingress
spec:
  rules:
    - host: midominio.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80

El orden importa: Kubernetes evalua las rutas mas especificas primero. /api matchea antes que /.

Traefik Dashboard

Traefik incluye un dashboard web para visualizar routers, services, middlewares y su estado. Por defecto en K3s esta deshabilitado por seguridad.

Para acceder temporalmente via port-forward:

kubectl port-forward -n kube-system \
  $(kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik -o name) \
  9000:9000

Abre http://localhost:9000/dashboard/ en tu navegador. El dashboard muestra:

Es una herramienta util para diagnosticar problemas de routing.

Middlewares de Traefik

Los middlewares modifican las peticiones antes de llegar al backend. Se configuran como anotaciones en el Ingress o como CRDs.

Redirect HTTP a HTTPS

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-https
spec:
  redirectScheme:
    scheme: https
    permanent: true

Basic Auth

Primero genera las credenciales (necesitas htpasswd):

htpasswd -nb usuario password | base64
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth
spec:
  basicAuth:
    secret: auth-secret
---
apiVersion: v1
kind: Secret
metadata:
  name: auth-secret
type: Opaque
data:
  users: <output-base64-de-htpasswd>

Rate Limiting

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
spec:
  rateLimit:
    average: 100
    burst: 50

Strip Prefix

Elimina un prefijo del path antes de enviarlo al backend. Util cuando el backend no conoce el prefijo:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: strip-api
spec:
  stripPrefix:
    prefixes:
      - /api

Con este middleware, una peticion a /api/users llega al backend como /users.

IngressRoute vs Ingress Estandar

Traefik soporta dos formas de definir routing:

Ingress estandar (networking.k8s.io/v1): el recurso nativo de Kubernetes. Compatible con cualquier Ingress Controller. Limitado en features avanzados.

IngressRoute (CRD de Traefik): recurso propio de Traefik con acceso a todas sus funcionalidades. No es portable a otros controllers.

Un IngressRoute equivalente al Ingress basico:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: mi-app-ingressroute
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`app.midominio.com`)
      kind: Rule
      services:
        - name: mi-app
          port: 80
      middlewares:
        - name: redirect-https

La ventaja principal de IngressRoute es que los middlewares se referencian directamente en la definicion, sin anotaciones.

Usa Ingress estandar si quieres portabilidad. Usa IngressRoute si necesitas features avanzados de Traefik.

Ejemplo Completo

Vamos a exponer una aplicacion Nginx con dominio personalizado. Primero el Deployment y Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-app
spec:
  selector:
    app: web-app
  ports:
    - port: 80
      targetPort: 80

Ahora el Ingress con redirect HTTP a HTTPS:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-https
spec:
  redirectScheme:
    scheme: https
    permanent: true
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: default-redirect-https@kubernetescrd
spec:
  rules:
    - host: app.midominio.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-app
                port:
                  number: 80

Aplica todo:

kubectl apply -f web-app.yaml
kubectl apply -f web-app-ingress.yaml

Verifica que todo este corriendo:

kubectl get deploy,svc,ingress

Asegurate de que el DNS de app.midominio.com apunte a la IP de tu nodo K3s. Luego accede desde el navegador.


Siguiente: Capitulo 10: TLS con cert-manager —>