Instalación de Apache OpenWhisk: Plataforma Serverless

Apache OpenWhisk es una plataforma serverless de código abierto que ejecuta funciones en respuesta a eventos, permitiendo construir aplicaciones escalables sin gestionar infraestructura. Con soporte para múltiples lenguajes y una arquitectura basada en Docker y Kafka, OpenWhisk es ideal para cargas de trabajo event-driven en servidores Linux propios o en Kubernetes.

Requisitos Previos

  • Ubuntu 20.04/22.04 o CentOS/Rocky Linux 8+
  • Docker Engine 20.10+ y Docker Compose
  • Al menos 4 GB de RAM (8 GB recomendado)
  • Java 11+ (para compilación de actions en Java)
  • Node.js 16+ (opcional, para actions en JavaScript)
  • Acceso root o usuario con privilegios sudo

Instalación con Docker Compose

OpenWhisk se despliega más fácilmente usando el repositorio oficial de Docker Compose:

# Clonar el repositorio de despliegue
git clone https://github.com/apache/openwhisk-deploy-kube.git
cd openwhisk-deploy-kube

# Usar la configuración de Docker Compose
git clone https://github.com/apache/openwhisk.git
cd openwhisk

# Construir las imágenes locales
./gradlew distDocker

# Desplegar con Docker Compose
cd tools/ubuntu-setup
./all.sh

Para una instalación más directa con el script oficial:

# Instalar dependencias del sistema
sudo apt-get update
sudo apt-get install -y git docker.io docker-compose curl

# Asegurarse de que Docker está corriendo
sudo systemctl enable docker
sudo systemctl start docker

# Añadir usuario al grupo docker
sudo usermod -aG docker $USER
newgrp docker

# Clonar y desplegar OpenWhisk
git clone https://github.com/apache/openwhisk-devtools.git
cd openwhisk-devtools/docker-compose

# Iniciar todos los servicios de OpenWhisk
make quick-start

Verificar que los contenedores estén corriendo:

# Listar contenedores activos de OpenWhisk
docker-compose ps

# Ver logs del controlador principal
docker-compose logs controller

# Verificar estado del sistema
curl -s http://localhost:3233/api/v1 | python3 -m json.tool

Instalación de la CLI wsk

La CLI wsk es la herramienta principal para interactuar con OpenWhisk:

# Descargar la CLI para Linux (amd64)
curl -L https://github.com/apache/openwhisk-cli/releases/latest/download/OpenWhisk_CLI-latest-linux-amd64.tgz -o wsk.tgz

# Extraer y mover al PATH
tar -xzf wsk.tgz
sudo mv wsk /usr/local/bin/
chmod +x /usr/local/bin/wsk

# Verificar instalación
wsk --version

# Configurar la CLI con credenciales por defecto
wsk property set --apihost localhost:3233
wsk property set --auth guest:guest

# Verificar conexión con el servidor
wsk list

Creación de Actions

Las actions son las funciones que ejecuta OpenWhisk:

# Crear un archivo JavaScript de ejemplo
cat > hello.js << 'EOF'
// Función de bienvenida - devuelve un saludo
function main(params) {
    var nombre = params.nombre || "Mundo";
    return { mensaje: "Hola, " + nombre + "!" };
}
EOF

# Crear la action en OpenWhisk
wsk action create saludo hello.js

# Invocar la action sincrónicamente
wsk action invoke saludo --param nombre "OpenWhisk" --result

# Ver detalles de la action
wsk action get saludo

# Actualizar la action
wsk action update saludo hello.js

# Crear una action en Python
cat > procesar.py << 'EOF'
# Procesador de datos con validación básica
def main(params):
    datos = params.get("datos", [])
    if not datos:
        return {"error": "No se proporcionaron datos"}
    
    total = sum(datos)
    promedio = total / len(datos)
    return {
        "total": total,
        "promedio": promedio,
        "cantidad": len(datos)
    }
EOF

wsk action create procesador procesar.py --kind python:3

# Invocar con parámetros
wsk action invoke procesador --param-file - --result << 'EOF'
{"datos": [10, 20, 30, 40, 50]}
EOF

Actions con límites de recursos

# Crear action con límites personalizados
wsk action create mi-action hello.js \
    --memory 256 \
    --timeout 30000 \
    --concurrency 10

# Crear action desde un archivo ZIP (dependencias incluidas)
npm install lodash
zip -r action.zip hello.js node_modules/
wsk action create accion-con-deps action.zip --kind nodejs:16

Triggers y Rules

Los triggers lanzan actions en respuesta a eventos:

# Crear un trigger manual
wsk trigger create mi-trigger

# Crear una rule que conecta trigger con action
wsk rule create mi-regla mi-trigger saludo

# Disparar el trigger (activa la action asociada)
wsk trigger fire mi-trigger --param nombre "Evento"

# Ver activaciones recientes
wsk activation list

# Ver resultado de una activación específica
wsk activation get <ID_DE_ACTIVACION>

# Crear un trigger con feed (periódico - cada minuto)
wsk trigger create trigger-periodico \
    --feed /whisk.system/alarms/alarm \
    --param cron "*/1 * * * *"

# Asociar el trigger periódico a una action
wsk rule create regla-periodica trigger-periodico saludo

Packages y Namespaces

Los packages agrupan actions relacionadas:

# Crear un package
wsk package create mis-utilidades

# Añadir actions al package
wsk action create mis-utilidades/formatear hello.js
wsk action create mis-utilidades/validar procesar.py --kind python:3

# Listar contenido del package
wsk package get mis-utilidades

# Establecer parámetros por defecto del package
wsk package update mis-utilidades \
    --param entorno "produccion" \
    --param version "1.0"

# Compartir un package (hacerlo público)
wsk package update mis-utilidades --shared yes

# Usar un package del sistema (feeds integrados)
wsk package list /whisk.system
wsk package get /whisk.system/utils

Despliegue en Kubernetes

Para producción, OpenWhisk se despliega mejor en Kubernetes:

# Instalar Helm si no está disponible
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Añadir el repositorio de OpenWhisk
helm repo add openwhisk https://openwhisk.apache.org/charts
helm repo update

# Crear namespace dedicado
kubectl create namespace openwhisk

# Crear archivo de configuración
cat > mycluster.yaml << 'EOF'
# Configuración del clúster OpenWhisk en Kubernetes
whisk:
  ingress:
    type: NodePort
    apiHostName: localhost
    apiHostPort: 31001

nginx:
  httpsNodePort: 31001

invoker:
  containerFactory:
    impl: "kubernetes"
EOF

# Instalar OpenWhisk con Helm
helm install owdev openwhisk/openwhisk \
    -n openwhisk \
    --set whisk.ingress.apiHostName=$(hostname -I | awk '{print $1}') \
    -f mycluster.yaml

# Verificar el despliegue
kubectl get pods -n openwhisk
kubectl rollout status deployment/owdev-controller -n openwhisk

API Gateway

Exponer actions como endpoints HTTP:

# Crear una action para la API
cat > api-handler.js << 'EOF'
// Manejador de API REST
function main(params) {
    var metodo = params.__ow_method;
    var ruta = params.__ow_path;
    
    return {
        statusCode: 200,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
            metodo: metodo,
            ruta: ruta,
            timestamp: new Date().toISOString()
        })
    };
}
EOF

wsk action create api-handler api-handler.js --web true

# Crear la API en el gateway
wsk api create /mi-api GET api-handler

# Crear API con múltiples rutas
wsk api create /mi-api /usuarios GET listar-usuarios
wsk api create /mi-api /usuarios POST crear-usuario

# Listar las APIs configuradas
wsk api list

# Obtener la URL de la API
wsk api get /mi-api

Solución de Problemas

Los contenedores no arrancan:

# Ver logs detallados de todos los servicios
docker-compose logs --tail=50

# Verificar que los puertos no estén ocupados
ss -tlnp | grep -E "3233|5984|9092|2181"

# Reiniciar todos los servicios
docker-compose restart

Error de autenticación con wsk:

# Verificar la configuración actual
wsk property get

# Restablecer credenciales
wsk property set --apihost localhost:3233
wsk property set --auth $(cat ansible/files/auth.guest)

La action devuelve timeout:

# Aumentar el timeout de la action (en milisegundos)
wsk action update mi-action --timeout 60000

# Ver el log de la activación fallida
wsk activation logs <ID_ACTIVACION>

Problemas de memoria en Kafka:

# Verificar el estado de Kafka
docker-compose logs kafka | tail -20

# Revisar el uso de memoria del sistema
free -h
docker stats --no-stream

Conclusión

Apache OpenWhisk proporciona una plataforma serverless robusta y autoalojada que ofrece control total sobre la infraestructura de funciones event-driven. Con su arquitectura basada en Docker y Kafka, y soporte para múltiples lenguajes de programación, es una solución sólida para organizaciones que necesitan capacidades serverless sin depender de proveedores cloud. Para producción, el despliegue en Kubernetes con Helm garantiza escalabilidad y alta disponibilidad.