--- title: "Instalar Fission en Kubernetes para funciones serverless" description: "Instala Fission en Kubernetes con Helm, crea funciones en Python y Node.js, expónlas con rutas HTTP, prográmalas con triggers cron y reduce el arranque en frío." category: "Serverless en VPS" language: es source: https://cubepath.com/es/docs/serverless-en-vps/instalacion-de-fission-framework-serverless updated: 2026-09-25 --- # Instalar Fission en Kubernetes para funciones serverless Fission es un framework serverless de código abierto para Kubernetes: escribes solo el código de la función y Fission lo carga en un contenedor de un entorno de ejecución (Python, Node.js, Go...) que mantiene precalentado, de modo que la primera invocación tarda del orden de milisegundos en lugar de segundos. En esta guía instalarás Fission con Helm, crearás funciones en Python y Node.js, una de ellas con dependencias, las expondrás con rutas HTTP, programarás una con un trigger de tipo cron y ajustarás el comportamiento de escalado. ## Requisitos previos - Un clúster de Kubernetes y `kubectl` configurado con permisos de administrador. Para un único servidor sirve k3s sobre Ubuntu 24.04, por ejemplo en un VPS de CubePath con al menos 4 GB de RAM y 2 vCPU. - Un usuario no root con privilegios `sudo` en la máquina desde la que gestionas el clúster. - Helm 3 instalado. En Ubuntu 24.04 puedes instalarlo con `sudo snap install helm --classic`. - El paquete `zip` para empaquetar funciones con dependencias: `sudo apt install zip`. Comprueba el acceso al clúster antes de empezar: ```bash kubectl get nodes helm version --short ``` ## Paso 1: Instalar Fission con Helm Define la versión que vas a instalar. Esta guía usa la 1.21.0; consulta la [página de versiones](https://github.com/fission/fission/releases) por si hay una más reciente y usa la misma en todos los comandos: ```bash export FISSION_VERSION=v1.21.0 export FISSION_NAMESPACE=fission ``` Desde la versión 1.18, el chart de Helm no instala las definiciones de recursos (CRD); se aplican primero con `kubectl`: ```bash kubectl create -k "github.com/fission/fission/crds/v1?ref=${FISSION_VERSION}" ``` Añade el repositorio de charts de Fission e instala el chart `fission-all` en su propio namespace: ```bash kubectl create namespace "$FISSION_NAMESPACE" helm repo add fission-charts https://fission.github.io/fission-charts/ helm repo update helm install fission fission-charts/fission-all \ --version "$FISSION_VERSION" \ --namespace "$FISSION_NAMESPACE" \ --set serviceType=NodePort,routerServiceType=NodePort ``` Espera a que los componentes estén listos: ```bash kubectl wait --for=condition=Available deployment --all -n fission --timeout=300s kubectl get pods -n fission ``` ```output NAME READY STATUS RESTARTS AGE buildermgr-5d8f9b7c6d-9kx2p 1/1 Running 0 70s controller-7c9b8d6f5c-h4mzt 1/1 Running 0 70s executor-6f7d9c8b5d-wq7ln 1/1 Running 0 70s kubewatcher-5b8c7d9f6c-2xkqz 1/1 Running 0 70s router-7d6c9b8f5d-l9tqm 1/1 Running 0 70s storagesvc-6c8d7b9f5c-m2vxp 1/1 Running 0 70s timer-5f9c8d7b6c-r8kzn 1/1 Running 0 70s ... ``` Los componentes principales son el **router**, que recibe las peticiones HTTP y las envía a la función; el **executor**, que gestiona los pods de las funciones; el **buildermgr** y **storagesvc**, que compilan y almacenan los paquetes con dependencias; y el **timer**, que ejecuta los triggers programados. ## Paso 2: Instalar la CLI de Fission La CLI `fission` es la forma habitual de crear entornos, funciones y triggers. Descarga el binario de la misma versión que el chart (en ARM, cambia `amd64` por `arm64`): ```bash curl -fsSLo fission "https://github.com/fission/fission/releases/download/${FISSION_VERSION}/fission-${FISSION_VERSION}-linux-amd64" sudo install -m 755 fission /usr/local/bin/fission rm fission fission version ``` La salida muestra la versión del cliente y la del servidor; deben coincidir. Para probar las funciones necesitas llegar al router. La forma más sencilla, que no expone nada a Internet, es un port-forward en segundo plano: ```bash kubectl port-forward svc/router 8888:80 -n fission >/dev/null 2>&1 & export FISSION_ROUTER=127.0.0.1:8888 ``` Más adelante verás cómo publicarlo con un dominio. ## Paso 3: Crear un entorno de Python Un **entorno** es la imagen de contenedor con el runtime de un lenguaje. Fission mantiene un pool de pods de cada entorno ya arrancados y, al invocar una función por primera vez, carga su código en uno de ellos: por eso el arranque en frío es tan corto. La imagen `builder` es opcional y solo se usa para compilar paquetes con dependencias. ```bash fission env create --name python \ --image ghcr.io/fission/python-env \ --builder ghcr.io/fission/python-builder \ --poolsize 3 ``` `--poolsize 3` indica cuántos pods precalentados mantiene el pool. Comprueba el entorno y sus pods: ```bash fission env list kubectl get pods -l environmentName=python -A ``` Los pods del pool aparecen en estado `Running` tras descargar la imagen. ## Paso 4: Crear y probar una función en Python El entorno de Python ejecuta la función `main()` del archivo y se basa en Flask, así que puedes leer la petición con `flask.request`. Crea la función: ```bash mkdir -p ~/fission && cd ~/fission nano hola.py ``` ```python from flask import request def main(): nombre = request.args.get("nombre", "mundo") return f"Hola, {nombre}, desde Fission\n" ``` Regístrala en Fission y pruébala directamente, sin crear todavía una ruta HTTP: ```bash fission function create --name hola --env python --code hola.py fission function test --name hola ``` ```output Hola, mundo, desde Fission ``` La primera invocación carga el código en un pod del pool; las siguientes reutilizan ese pod mientras siga activo. ## Paso 5: Exponer la función con una ruta HTTP Un trigger HTTP (en la CLI, `route` o `httptrigger`) asocia un método y una URL del router a una función: ```bash fission route create --name hola --method GET --url /hola --function hola fission route list ``` Llama a la función a través del router: ```bash curl "http://${FISSION_ROUTER}/hola?nombre=CubePath" ``` ```output Hola, CubePath, desde Fission ``` Para publicar las funciones en Internet, en lugar del port-forward crea un Ingress que apunte al servicio `router` del namespace `fission` con el controlador de ingress de tu clúster, y protégelo con HTTPS (por ejemplo, con cert-manager). El router no tiene autenticación propia: cualquier función con una ruta publicada es accesible para quien conozca la URL. ## Paso 6: Crear una función con dependencias Cuando la función necesita librerías externas, se empaqueta el código junto a un `requirements.txt` y un script de compilación. El builder del entorno instala las dependencias dentro del clúster y guarda el resultado como un **paquete**. Como ejemplo, una función que usa la librería `humanize` para formatear tamaños: ```bash mkdir -p ~/fission/tamano && cd ~/fission/tamano nano main.py ``` ```python import humanize from flask import request def main(): try: num_bytes = int(request.args.get("bytes", "0")) except ValueError: return "El parámetro bytes debe ser un número entero\n", 400 return f"{num_bytes} bytes son {humanize.naturalsize(num_bytes)}\n" ``` Declara la dependencia: ```bash echo "humanize" > requirements.txt ``` Crea el script de compilación. El builder define `SRC_PKG` (el código fuente) y `DEPLOY_PKG` (el directorio que se desplegará): ```bash nano build.sh ``` ```bash #!/bin/sh pip3 install -r "${SRC_PKG}/requirements.txt" -t "${SRC_PKG}" && cp -r "${SRC_PKG}" "${DEPLOY_PKG}" ``` Hazlo ejecutable, empaqueta los tres archivos en la raíz del zip y crea el paquete: ```bash chmod +x build.sh zip -j tamano.zip main.py requirements.txt build.sh fission package create --name tamano-pkg --env python \ --sourcearchive tamano.zip --buildcmd "./build.sh" ``` La compilación tarda unos segundos. Comprueba su estado: ```bash fission package info --name tamano-pkg ``` ```output Name: tamano-pkg Environment: python Status: succeeded Build Logs: Collecting humanize ... Successfully installed humanize-4.12.3 ``` Cuando el estado sea `succeeded`, crea la función indicando el punto de entrada con el formato `módulo.función`, y su ruta: ```bash fission function create --name tamano --pkg tamano-pkg --entrypoint "main.main" fission route create --name tamano --method GET --url /tamano --function tamano curl "http://${FISSION_ROUTER}/tamano?bytes=3500000" ``` ```output 3500000 bytes son 3.5 MB ``` Si cambias el código, vuelve a generar el zip y actualiza el paquete con `fission package update --name tamano-pkg --sourcearchive tamano.zip`; Fission lo recompila y la función usa la versión nueva. ## Paso 7: Añadir una función en Node.js Cada lenguaje necesita su entorno. Crea el de Node.js: ```bash fission env create --name nodejs --image ghcr.io/fission/node-env --poolsize 2 ``` En este entorno la función exporta un manejador asíncrono que recibe `context`, donde `context.request` es la petición de Express: ```bash cd ~/fission nano hora.js ``` ```javascript module.exports = async function (context) { const zona = context.request.query.zona || 'Europe/Madrid'; try { const hora = new Date().toLocaleTimeString('es-ES', { timeZone: zona }); return { status: 200, body: `Son las ${hora} en ${zona}\n` }; } catch { return { status: 400, body: `Zona horaria no válida: ${zona}\n` }; } }; ``` Crea la función y su ruta, y pruébala: ```bash fission function create --name hora --env nodejs --code hora.js fission route create --name hora --method GET --url /hora --function hora curl "http://${FISSION_ROUTER}/hora?zona=America/Mexico_City" ``` ```output Son las 10:42:17 en America/Mexico_City ``` ## Paso 8: Programar funciones con triggers de tiempo Un trigger de tiempo invoca una función según una expresión cron, sin necesidad de un CronJob de Kubernetes. Crea una función de tarea periódica: ```bash nano tarea.py ``` ```python import datetime def main(): ahora = datetime.datetime.now(datetime.timezone.utc).isoformat() print(f"Tarea programada ejecutada a las {ahora}", flush=True) return "ok\n" ``` Regístrala y prográmala cada cinco minutos: ```bash fission function create --name tarea --env python --code tarea.py fission timer create --name cada-5-min --function tarea --cron "*/5 * * * *" fission timer list ``` El componente `timer` interpreta la expresión en UTC. Pasados unos minutos, comprueba las ejecuciones en los logs de la función: ```bash fission function log --name tarea ``` ```output Tarea programada ejecutada a las 2026-09-25T10:45:00.012345+00:00 Tarea programada ejecutada a las 2026-09-25T10:50:00.009876+00:00 ``` ## Paso 9: Ajustar el escalado y el arranque en frío Fission tiene dos modos de ejecución (executors) y cada función usa uno: | Executor | Cómo funciona | Arranque en frío | Úsalo para | |---|---|---|---| | `poolmgr` (por defecto) | Carga la función en un pod precalentado del pool del entorno | Muy bajo | Funciones con tráfico irregular o bajo | | `newdeploy` | Crea un Deployment propio con autoescalado horizontal (HPA) | Alto si escala desde cero | Funciones con tráfico sostenido que necesitan varias réplicas | Para el executor `poolmgr`, el parámetro importante es el tamaño del pool del entorno. Auméntalo si tienes muchas funciones distintas del mismo lenguaje: ```bash fission env update --name python --poolsize 5 ``` Para una función con carga constante, cámbiala a `newdeploy` con un mínimo de réplicas para evitar arranques en frío, un máximo, y los recursos que puede usar (CPU en milicores, memoria en MiB): ```bash fission function update --name tamano \ --executortype newdeploy \ --minscale 1 --maxscale 5 \ --mincpu 100 --maxcpu 500 \ --minmemory 64 --maxmemory 256 ``` Comprueba los pods de la función: ```bash kubectl get pods -A -l functionName=tamano ``` Con `--minscale 1` siempre hay al menos una réplica lista; con `--minscale 0` la función escala a cero cuando no recibe tráfico y la primera petición espera a que arranque el pod. ## Solución de problemas **`fission function test` devuelve un error 500.** El código ha lanzado una excepción. Revisa `fission function log --name `: allí aparece la traza de Python o Node.js. Un error habitual es que el archivo no defina `main()` en Python o que el `--entrypoint` no coincida con `módulo.función`. **El paquete se queda en `failed`.** `fission package info --name ` muestra el log de compilación. Suele deberse a que `build.sh` no es ejecutable o no está en la raíz del zip (usa `zip -j`), o a un nombre de dependencia incorrecto en `requirements.txt`. **`curl` al router devuelve 404.** La ruta no existe o no coincide el método. Compruébalo con `fission route list`. Si el error es de conexión, el port-forward se ha cerrado: vuelve a lanzarlo. **Los pods del entorno se quedan en `ImagePullBackOff`.** El nodo no puede descargar la imagen desde `ghcr.io`. Revisa el nombre de la imagen con `fission env list` y la conectividad del nodo con `kubectl describe pod ` en el namespace donde se ejecuta. ## Conclusión Has instalado Fission en Kubernetes, creado entornos de Python y Node.js, desplegado funciones sencillas y con dependencias, expuesto rutas HTTP, programado una tarea con un trigger de tiempo y ajustado el escalado según el tipo de carga. Como siguientes pasos, guarda la definición de entornos, funciones y triggers en archivos con `fission spec init` y `fission spec apply` para versionarla en Git, publica el router con un Ingress y HTTPS, y explora los triggers de colas de mensajes basados en KEDA para procesar eventos de Kafka o RabbitMQ.