Instalación de Knative para Serverless en Kubernetes

Knative es la plataforma de referencia para ejecutar cargas de trabajo serverless sobre Kubernetes, ofreciendo escalado automático hasta cero instancias y un modelo de programación basado en eventos. Con Knative Serving y Knative Eventing puedes desplegar funciones y microservicios que reaccionan a eventos sin gestionar infraestructura manualmente. Esta guía cubre la instalación completa de Knative en un clúster Kubernetes existente, incluyendo configuración de red, tráfico dividido y pipelines CI/CD.

Requisitos Previos

  • Clúster Kubernetes 1.28 o superior con al menos 3 nodos
  • kubectl configurado y con acceso al clúster
  • Helm 3.x instalado
  • Mínimo 4 vCPU y 8 GB RAM disponibles en el clúster
  • Un dominio DNS configurable (o uso de sslip.io para pruebas)
  • Permisos de administrador en el clúster

Verifica la versión de Kubernetes antes de empezar:

kubectl version --short

Instalación del Operador de Knative

El operador de Knative simplifica la instalación y las actualizaciones futuras. Instálalo primero:

# Instalar el operador de Knative (versión 1.14)
kubectl apply -f https://github.com/knative/operator/releases/download/knative-v1.14.0/operator.yaml

# Verificar que el operador está corriendo
kubectl get deployment knative-operator -n default

# Esperar a que el operador esté listo
kubectl wait --for=condition=Available deployment/knative-operator --timeout=120s

Instalación de Knative Serving

Knative Serving gestiona el ciclo de vida de los servicios serverless, incluyendo el escalado automático y el enrutamiento de tráfico.

# Crear el namespace para Knative Serving
kubectl create namespace knative-serving

# Aplicar los CRDs de Knative Serving
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-crds.yaml

# Instalar los componentes principales de Knative Serving
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-core.yaml

# Verificar que los pods están corriendo
kubectl get pods -n knative-serving

Espera a que todos los pods estén en estado Running:

# Comprobar el estado de todos los componentes
kubectl wait --for=condition=Ready pod --all -n knative-serving --timeout=300s

Configuración de la Capa de Red

Knative requiere un controlador de ingress. Kourier es la opción más ligera; también puedes usar Istio o Contour.

Opción A: Kourier (recomendado para producción simple)

# Instalar Kourier como capa de red
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.14.0/kourier.yaml

# Configurar Knative Serving para usar Kourier
kubectl patch configmap/config-network \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'

# Obtener la IP externa del load balancer de Kourier
kubectl get service kourier -n kourier-system

Opción B: Istio (para entornos con service mesh)

# Instalar Istio con el perfil mínimo
istioctl install --set profile=minimal -y

# Instalar la integración de Knative con Istio
kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.14.0/net-istio.yaml

Configurar el dominio DNS

# Para entornos de prueba con sslip.io (sin configuración DNS real)
# Obtener la IP del ingress
INGRESS_IP=$(kubectl get svc kourier -n kourier-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Configurar el dominio base usando sslip.io
kubectl patch configmap/config-domain \
  --namespace knative-serving \
  --type merge \
  --patch "{\"data\":{\"${INGRESS_IP}.sslip.io\":\"\"}}"

# Para producción con dominio real
kubectl patch configmap/config-domain \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"tudominio.com":""}}'

Instalación de Knative Eventing

Knative Eventing proporciona un sistema de mensajería basado en CloudEvents para comunicación entre servicios.

# Crear el namespace para Knative Eventing
kubectl create namespace knative-eventing

# Instalar los CRDs de Knative Eventing
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-crds.yaml

# Instalar los componentes principales de Knative Eventing
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-core.yaml

# Instalar el canal InMemory (para pruebas; en producción usa Kafka o RabbitMQ)
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/in-memory-channel.yaml

# Instalar el broker MT Channel Based
kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/mt-channel-broker.yaml

# Verificar que todos los pods de eventing están activos
kubectl get pods -n knative-eventing

Despliegue de tu Primera Función Serverless

Crea un servicio Knative básico que responda a peticiones HTTP:

# Crear el archivo de definición del servicio
cat <<EOF > hola-mundo.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hola-mundo
  namespace: default
spec:
  template:
    metadata:
      annotations:
        # Tiempo máximo de inactividad antes de escalar a cero (segundos)
        autoscaling.knative.dev/scale-to-zero-pod-retention-period: "30s"
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go
          ports:
            - containerPort: 8080
          env:
            - name: TARGET
              value: "Mundo"
EOF

# Aplicar el servicio
kubectl apply -f hola-mundo.yaml

# Esperar a que el servicio esté listo
kubectl wait --for=condition=Ready ksvc/hola-mundo --timeout=120s

# Obtener la URL del servicio
kubectl get ksvc hola-mundo

Prueba el servicio con curl:

# Obtener la URL y hacer una petición
SERVICE_URL=$(kubectl get ksvc hola-mundo -o jsonpath='{.status.url}')
curl "$SERVICE_URL"

Escalado Automático y Scale-to-Zero

Knative incluye el autoescalador KPA (Knative Pod Autoscaler) que escala basándose en métricas de concurrencia:

# Configurar el autoescalado a nivel de servicio
cat <<EOF > servicio-escalado.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: mi-api
spec:
  template:
    metadata:
      annotations:
        # Número de peticiones simultáneas por pod
        autoscaling.knative.dev/target: "10"
        # Mínimo de pods (0 = scale-to-zero habilitado)
        autoscaling.knative.dev/min-scale: "0"
        # Máximo de pods
        autoscaling.knative.dev/max-scale: "20"
        # Tiempo de espera antes de escalar a cero
        autoscaling.knative.dev/scale-to-zero-pod-retention-period: "60s"
    spec:
      # Tiempo máximo para procesar una petición antes de timeout
      timeoutSeconds: 300
      containers:
        - image: tu-registro/mi-api:latest
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "1000m"
              memory: "512Mi"
EOF

kubectl apply -f servicio-escalado.yaml

Configura los parámetros globales del autoescalador:

# Ver la configuración actual del autoescalador
kubectl describe configmap config-autoscaler -n knative-serving

# Modificar el período de scale-to-zero globalmente
kubectl patch configmap/config-autoscaler \
  --namespace knative-serving \
  --type merge \
  --patch '{"data":{"scale-to-zero-grace-period":"60s","scale-to-zero-pod-retention-period":"30s"}}'

División de Tráfico y Canary Deployments

Knative permite dividir el tráfico entre distintas revisiones del mismo servicio:

# Crear una nueva revisión con una etiqueta específica
kubectl apply -f - <<EOF
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: mi-api
spec:
  template:
    metadata:
      name: mi-api-v2  # Nombre explícito de la revisión
    spec:
      containers:
        - image: tu-registro/mi-api:v2
  traffic:
    # Enviar el 80% del tráfico a la versión estable
    - tag: estable
      revisionName: mi-api-v1
      percent: 80
    # Enviar el 20% del tráfico a la nueva versión (canary)
    - tag: canary
      revisionName: mi-api-v2
      percent: 20
EOF

# Ver el estado del tráfico
kubectl describe ksvc mi-api | grep -A 20 "Traffic:"

Integración con CI/CD

Ejemplo de un pipeline básico con GitHub Actions:

# .github/workflows/knative-deploy.yml
name: Deploy a Knative

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Construir y publicar imagen
        run: |
          docker build -t registry.ejemplo.com/mi-app:${{ github.sha }} .
          docker push registry.ejemplo.com/mi-app:${{ github.sha }}

      - name: Desplegar en Knative
        run: |
          # Actualizar la imagen en el servicio Knative
          kubectl set image ksvc/mi-app \
            mi-app=registry.ejemplo.com/mi-app:${{ github.sha }}

Solución de Problemas

El pod no escala a cero:

# Verificar los logs del autoescalador
kubectl logs -n knative-serving deployment/autoscaler

# Verificar la configuración del servicio
kubectl describe ksvc nombre-servicio

Error "RevisionFailed" al desplegar:

# Ver los eventos del namespace
kubectl get events --sort-by='.lastTimestamp' -n default

# Revisar los logs del controlador
kubectl logs -n knative-serving deployment/controller

El dominio no resuelve correctamente:

# Verificar la configuración del dominio
kubectl describe configmap config-domain -n knative-serving

# Comprobar que el ingress tiene IP asignada
kubectl get svc -n kourier-system

Problemas con Eventing: los triggers no reciben eventos:

# Verificar el estado de los triggers
kubectl get trigger -n default

# Revisar los logs del broker
kubectl logs -n knative-eventing deployment/mt-broker-ingress

Conclusión

Knative transforma Kubernetes en una plataforma serverless completa, eliminando la complejidad de gestionar el escalado y el enrutamiento de tráfico. Con Knative Serving obtienes scale-to-zero automático y canary deployments nativos, mientras que Knative Eventing te permite construir arquitecturas event-driven desacopladas. A partir de aquí, explora la integración con Tekton para pipelines CI/CD nativos en Kubernetes o conecta brokers de eventos como Kafka para escenarios de alto volumen.