Un poco de Fn (Plataforma Serverless FaaS multi-cloud)

Fn Project es una plataforma open-source Serverless para contenedores que puede ejecutarse en cualquier lugar (Cloud o CPD), fácilmente extensible y que permite programar las funciones en Java, Python, Go, Node.js, Ruby o C#.

¿Qué es Serverless?

Podríamos decir que se trata de una tendencia en Arquitectura Software que reduce la noción de infraestructura, ya que aunque esta tendencia sigue requiriendo servidores, los desarrolladores no tienen que preocuparse por el balanceo de carga, el multihilo o cualquier otro tema de infraestructura ya que la propia plataforma elegida gestiona los recursos, permitiendo a los desarrolladores centrarse únicamente en su código. En la actualidad hay muchos frameworks y plataformas Serverless de proveedores Cloud como AWS Lambda (Amazon), Azure Functions (Microsoft), Cloud Functions (Google), Cloudflare Workers (Cloudflare) u OpenWhisk (IBM). Estas soluciones Cloud cobran por el número de invocaciones y sólo pueden desplegarse en este proveedor.

En ese sentido Fn Project es Cloud-agnostic, ya que puede ser desplegada en cualquier entorno que soporte Docker (y se integra con Kubernetes) y cuenta con el soporte de Oracle.

Comparando Serverless con MSA

En Serverless, cada trozo de código se denomina, y un proveedor Serverless proporciona funciones como servicio (FaaS: Function As A Service). Incluido todo lo necesario para aprovisionar, escalar, parchear y mantener el entorno.

En una MSA (Arquitectura de Microservicios) en lugar de crear un gran servicio monolítico, un servicio se descompone en servicios más pequeños que proporcionan el mismo conjunto de funciones, esto simplifica el desarrollo y la creación de servicios web, sin embargo, cada microservicio sigue ejecutando su propio servidor, que debe ser escalado y gestionado.

Por tanto vemos como FaaS lleva las cosas un paso más allá:

Arquitectura Fn

Una implementación típica Fn podría ser como esta:

Donde un balanceador de carga proporciona un front end a varios servidores Fn. Cada servidor gestiona y ejecuta el código de la función según sea necesario, los servidores pueden ser escalados hacia arriba o hacia abajo según sea necesario. Con Fn, cada función es un contenedor Docker.

Cómo se despliega Fn

El proceso de despliegue de un proyecto Fn se descompone en 3 pasos:

  1. Se construye una imagen Docker con el código de la función (y se aumenta el número de versión)
  2. Se sube la imagen de contenedor al Registro Docker (DockerHub por defecto).
  3. Se crea un trigger para su ejecución en el servidor.

De modo que al llamar a la función vía URL o comando el contenedor se ejecuta y devuelve los resultados:

Un ejemplo sencillo en Java

1.Comenzaremos con la instalación de Fn, hay varias formas de hacerlo, en Linux y MacOS puedo ejecutar este script:

  curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh 

En Windows lo más sencillo es instalar Docker (https://docs.docker.com/docker-for-windows/install/) y luego descargarme el ejecutable desde https://github.com/fnproject/cli/releases y añadir el fn.exe al PATH.

2.Tras esto puedo ejecutar Fn, con un fn start

Esto iniciará Fn en modo Single Server Mode (como imagen Docker) , utilizando una base de datos y una cola de mensajes embedidas.

Si tenéis una versión antigua de Docker os podéis encontrar con este error:

Para solucionarlo podéis lanzarlo manualmente:

docker run --memory 1024M --memory-swap 1024M --privileged --rm --name functions -it -v /var/run/docker.sock:/var/run/docker.sock -v D:/fn/data:/fn/app/data -p 8080:8080 fnproject/fnserver

En mi caso he optado por actualizar Docker, habilitara WSL 2, instalar una distribución de Ubuntu en Windows y ejecutar Docker desde esta distribución:

3.Ya puedo crear mi primera función, para eso elijo una carpeta y ejecuto

 fn init --runtime java java_fn_example

 Esto inicializará el runtime Java, luego me muevo al directorio java_fn_example, que habrá creado un pom.xml (proyecto Maven), un func.yaml (Descriptor Fn) y una carpeta src para los fuentes:

Tras esto crearé mi app con el comando:

fn create app java_fn_example-app

 Si me fijo en la clase que implementa mi función (HelloFunction) que está en src/main/java/com/example/fn veré que tengo implementado el mítico Hello:

4.Para desplegar la función usaremos la función creada por defecto, para hacer el despliegue en mi entorno local lanzaré (añado el verbose) :

fn deploy --verbose –-local --app java_fn_example-app 

Esto compila el proyecto Maven, genera la imagen Docker,…

5.Ahora que ya tengo desplegada la función puedo ejecutarla, para empezar lo haré con el Fn CLI:

fn invoke java_fn_example-app java_fn_example

Aunque es más interesante poder invocarlo a través del endpoint que habilita Fn, para eso primero ejecuto: fn inspect function java_fn_example-app java_fn_example

Si capturo la URL que aparece podré invocarla vía curl:

curl -X "POST" http://localhost:8080/invoke/01F00Z4AHENG8G00GZJ0000007

Puedo comprobar que la imagen de mi función no está en ejecución, es el FnServer el encargado de lanzarla:

Completando el ejemplo

Una vez que hemos visto cómo se construye una función vamos a completar el ejemplo HelloFunction, para eso en lugar de un String lo configuraremos para que reciba un JSON como entrada y devuelva otro JSON. FDK me ofrece una utilidad para mapear JSON a clases en base al nombre de los atributos, de modo que si envío un JSON como este: { “name”: “Luismi” } y dejo mi función así automáticamente FDK me mapeará name del JSON sobre la clase Input:

Haremos un fn build para construir de nuevo la función, que me fallarán porque no he actualizado el Test de la función, así que lo actualizaré y haré el build:

Ya lo puedo invocar con: 

curl -X "POST" -H "Content-Type: application/json" -d '{"name":"Luismi"}' http://localhost:8080/invoke/01F00Z4AHENG8G00GZJ0000007

Triggers

Otra funcionalidad interesante es la de los triggers, un Trigger representa un punto de entrada para la invocación de funciones. Cada tipo de Trigger requiere una configuración específica que se definen dentro del archivo func.yaml, por ejemplo:

Tras hacer el deploy, esto me permie invocar ahora a la función por su endpoint: http://localhost:8080/t/java_fn_example-app/hello

UI para Fn

Para acabar con este post veremos el proyecto “UI for fn”, que es como su nombre indica una UI para ver el estado de mi instancia Fn.

Lo lanzaré con:

docker run –rm –it –link fnserver:api -p 4000:4000 -e “FN_API_URL=http://api:8080” fnproject/ui

En el UI puedo ver las aplicaciones que tengo creadas, las que están en ejecución, si hay encoladas:

Y puedo probar mi función:

Próximos pasos

Por hoy, y como introducción a Fn es más que suficiente…en próximos posts veremos algunos otros aspectos avanzados de Fn como:

·       Ruteado HTTP a las funciones

·       Configuración avanzada

·       Cómo integrar Fn con Kubernetes

·       Cómo integrar FDK for Java con GraalVM para generar funciones Java que ejecutan más rápido

·       Uso de Fn Flow para orquestación de funciones

·       Cómo integrar Fn con Spring Cloud Functions (la plataforma FaaS de Spring)

·       Cómo crear una Función de una imagen Docker

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s