Propuesta de Solución Serverless en Plataforma

Contexto

Serverless es una tendencia en Arquitectura Software que reduce la noción de infraestructura permitiendo que los desarrolladores no tengan que preocuparse por el balanceo de carga, el multihilo y otros temas de infraestructura y centrarse únicamente en su código ya que la propia plataforma serverless gestiona los recursos.

Ventajas e Inconvenientes de una Arquitectura Serverless

A Serverless aún le queda camino para ser una tecnología usada de forma generalizada, pero a su vez, como hemos avanzado, ofrece numerosas ventajas para las organizaciones al proporcionar un modelo de programación simplificado para crear aplicaciones en la nube abstrayendo la mayoría de las preocupaciones operativas por lo que no es aventurado decir que acabará definiendo la forma en que las organizaciones desarrollan, despliegan e integran sus aplicaciones.

Ventajas del Modelo Serverless

  • No más Gestión de Servidores: Aunque la computación "serverless" se hace en servidores, los desarrolladores no tienen que preocuparse por su existencia en el momento del despliegue de la aplicación ya que el proveedor lo gestiona de forma automática, lo que disminuye la inversión requerida en DevOps y el tiempo que los desarrolladores necesitan para construir y ampliar sus aplicaciones. Las aplicaciones ya no estarían limitadas por la capacidad del servidor o la potencia de cálculo.

  • Backend de Pago por Uso: Al igual que con un plan de datos de "pago por uso" en el que sólo se factura por la cantidad de datos consumidos, en la computación serverless, sólo se factura cuando se ejecuta el código de la aplicación. El código de la aplicación sólo se ejecuta cuando las funciones del backend se ejecutan en respuesta a un evento y este se autoescala según la demanda y el aprovisionamiento sigue siendo dinámico, preciso e instantáneo.

  • Computación Serverless = Escalabilidad: Las aplicaciones sin servidor aumentan y reducen su tamaño según la demanda. Esto permite a las aplicaciones pasar de cientos de instancias de computación a una sola y viceversa en cuestión de segundos para adaptarse a curvas de demanda complejas. Los proveedores de la computación serverless emplean algoritmos para iniciar, ejecutar y finalizar esas instancias según sea necesario (en muchos casos utilizando contenedores). En consecuencia, las aplicaciones serverless pueden manejar millones de solicitudes concurrentes o una sola solicitud con el mismo rendimiento.

  • Despliegues y Actualizaciones más Rápidas: La infraestructura sin servidor no necesita complicadas configuraciones de backend para que una aplicación funcione. Una aplicación serverless es una colección de funciones gestionadas por el proveedor en lugar de un gran bloque monolítico inmanejable de código. A la hora de lanzar actualizaciones, parches y correcciones, los desarrolladores sólo tienen que alterar las funciones afectadas. Asimismo, se pueden añadir nuevas funciones para reflejar una nueva característica de la aplicación.

  • Las Localizaciones Permiten Reducir la Latencia: Las aplicaciones serverless no se alojan en el servidor de origen, sino en varias ubicaciones de la infraestructura del proveedor, de modo que, en respuesta a la demanda, la ubicación más cercana activa el evento y la función. Esto reduce la latencia porque ahora las solicitudes no tienen que ir hasta un servidor de origen.

  • La Computación sin Servidor Permite Reducir el Coste para la Mayoría de los Casos de Uso: Las arquitecturas serverless son más eficientes para reducir los costes de las aplicaciones con un uso desigual. Si la aplicación alterna periodos de gran actividad con instancias de poco o ningún tráfico, el alquiler de espacio en el servidor por un periodo de tiempo fijo no tendrá sentido. Pagar por un espacio de servidor disponible y siempre en funcionamiento no es rentable cuando sólo se va a utilizar durante una fracción del periodo de alquiler.

Desventajas del Modelo Serverless

Pero “nadie es perfecto” y como sucede con el modelo de microservicios, la computación serverless no es adecuada para todos los casos de uso y además su uso genera otras complejidades.

  • Cargas de Trabajo Prolongadas: si tus aplicaciones necesitan ejecutar cargas de trabajo prolongadas (como procesos Batch que ocupan doce horas diarias, vídeo bajo demanda o entrenamiento de modelos) en los que las aplicaciones estarían funcionando la mayor parte del tiempo la computación serverless no será práctica y su coste será mayor en el proveedor Cloud que provisionando infraestructura.

  • Dependencia de la Red: construir una aplicación sobre una Arquitectura Serverless implicará en muchas ocasiones flujos de eventos que llaman a funciones que se comunican exclusivamente a través de protocolos de red estándar, lo que significa que un corte de red o una interrupción de cualquier tipo (a menudo fuera del control) interferirá con las operaciones de negocio; y, a medida que aumenta el número de funciones desplegados, también lo hace el riesgo de una interrupción de la red, poniendo en peligro uno de estos servicios.

  • Latencia: Por otro lado, la red también implica que se introduce latencia en el sistema, y eso hay que tenerlo en cuenta.

  • Sobrecarga en la Gestión: Con una Arquitectura Serverless, se divide un producto en una red de funciones más pequeñas. Como resultado, hay una sobrecarga que se crea en la gestión de estas funciones, que es un motivo por el que muchas organizaciones no están preparadas para adoptar plenamente los microservicios y menos las funciones.

  • Dependencias: Imaginemos cientos de componentes de aplicaciones que dependen de una función con un contrato establecido (especificación de la API). Después, imaginemos que el equipo de microservicios quiere rediseñar (o incluso modificar ligeramente) su especificación. La organización no sólo debe coordinar este cambio entre equipos, sino que también debe hacer un seguimiento de quién depende de quién en todo momento.

  • Contratos Estrictos: en relación con el punto anterior, los desarrolladores deben tener cuidado de definir una especificación de API de la función lo suficientemente robusta como para proporcionar valor de negocio mucho después del lanzamiento inicial. Este tipo de previsión es poco frecuente, si no imposible en algunas organizaciones.

  • Orquestación: en muchos escenarios será necesario orquestar diversas funciones para componer un servicio de negocio. No todos los proveedores lo soportan y entre los que lo soportan cada proveedor ha optado por una solución para esto.

  • Transaccionalidad: el proceso de negocio que orqueste las funciones tendrá que gestionar las compensaciones antes un problema en la ejecución de una función.

  • Demasiado Fácil Crear una Función: Esto podemos catalogarlo como una fortaleza, pero también como una debilidad. La capacidad de desplegar e incorporar funciones de forma tan sencilla puede llevar a un exceso de funciones.

Offering Serverless

Los principales proveedores de la nube ya tienen ofertas sobre este paradigma serverless. Además de las ofertas de Amazon Web Service y Microsoft Azure, la computación serverless es un mercado prometedor para todos los proveedores de computación en la nube y las principales tecnologías de desarrollo de aplicaciones (como Spring) le dan soporte.

Offering Serverless

Diferenciación

AWS Lambda

Es la propuesta serverless de AWS. Permite cargar el código como un archivo ZIP o una imagen de contenedor y Lambda asigna de manera automática y precisa la potencia de ejecución informática y ejecuta el código en función de la solicitud o el evento entrante para cualquier escala de tráfico. Puede configurarse para que se active automáticamente desde más de 200 servicios AWS o desde cualquier aplicación web o móvil. Las funciones pueden escribirse en casi cualquier lenguaje (Node.js, Python, Go, Java y más).

Microsoft Azure Functions

La propuesta serverless de Azure permite programar en diversos lenguajes (.Net, Java, Python, Powershell, …). Destaca el soporte de flujos de trabajo que permiten orquestar los eventos y que además ofrece conectores con más de 250 conectores de Azure Logic Apps. Azure ofrece diversos planes de hospedaje para sus funciones (por uso, Kubernetes, …).

Google Cloud Functions

La propuesta de Google Cloud Functions ofrece integración con los recursos GCP (p. ej. Google Assistant o PubSub) de modo que se activan por una acción en uno de estos. Pueden escribirse en Node.js, Java, Go y Python.

IBM Cloud Functions

La propuesta comercial de IBM está basada en el software open-source Apache OpenWhisk, que es una plataforma serverless multilenguaje y que combina componentes como NGINX, Kafka, Docker y CouchDB.

Red Hat OpenShift Serverless

La propuesta serverless de Red Hat se basa en Knative, que es una tecnología open-source multi-vendor nativa para Kubernetes (como no podía ser de otra forma). Empaqueta las funciones como contenedores OCI.

Oracle Cloud Functions

La propuesta serverless de Oracle se basa en el software open-source Fn Project, que es una plataforma multilenguaje (Java, Go, Python, Node.js), que se integra con GraalVM para generar imágenes nativas, se integra con Spring Cloud Functions.

Spring Cloud Functions

Es el proyecto dentro del ecosistema Spring Cloud que da soporte al paradigma serverless/FaaS. Permite la creación de lógica de negocio a través de funciones ofreciendo un modelo de programación uniforme independiente a nivel de desarrollo y despliegue de los proveedores serverless (AWS Lambda, Google Functions, …) habilitando las características de Spring Boot (autoconfiguración, inyección de dependencias, métricas) en estos proveedores.

Actualmente, Amazon es líder en esta computación capturando más del 80% de la cuota de mercado en 2020 y Microsoft está en segundo lugar.

Análisis de la Elección de Tecnología Serverless en Onesait Platform

A continuación, se recoge un resumen del análisis que se ha realizado en Plataforma para la elección de la tecnología serverless más adecuada a incorporar/soportar en Plataforma.

  • Independencia Cloud: Uno de los mantras de Onesait Platform es poder trabajar con las diversas nubes, además de hacer compatibles las arquitecturas en Cloud y On Premise. Estas consideraciones arquitecturales no recomendaban el uso de tecnologías propietarias como AWS Lambda, Azure Functions o Google Functions que salvo en escenarios muy concretos implican la ejecución en la Cloud del proveedor.

  • Despliegue Sencillo/Nativo en los Proveedores Cloud: Por otro lado, aunque se busque la independencia de las Cloud, está clara la apuesta de Plataforma por el Cloud, incluyendo el ofrecimiento en modo SaaS de la plataforma. Por tanto, la tecnología serverless seleccionada debería poder desplegarse de forma sencilla, incluso nativa en los principales proveedores Clouds.

  • Soportar Despliegue On Premise: Aunque nuestra apuesta por el Cloud es clara, no podemos olvidar que aún seguimos teniendo muchos proyectos y productos en Plataforma desplegados en los CPDs de los clientes (y que muchos de estos grandes clientes tienen su propia estrategia de Cloud privada) lo que nos obliga a asegurar que esta tecnología pudiera desplegarse On Premise.

  • Tecnología Open-Source: Onesait Platform es un software open-source publicado en GitHub bajo licencia Apache2 y al que el equipo de producto da el soporte empresarial. Idealmente además la tecnología debería tener licencia Apache2 para poderla integrar y comercializar sin restricciones.

  • Soporte Multilenguaje: de los puntos anteriores salía un claro ganador, Spring Cloud Functions, ya que por un lado forma parte del ecosistema Spring que es la tecnología base de Plataforma (y de Onesait Technology), y por otro lado ofrece soporte para el despliegue en los principales Clouds. Sin embargo, carecía de un soporte de primer nivel para el desarrollo de funciones en diversos lenguajes como Python, Go, Node.js o C#, y Plataforma tiene numerosos casos de uso en los que se usan tecnologías como estas para el desarrollo, por ejemplo, para el desarrollo de modelos IA sobre base Python, que además encajan muy bien para una vez entrenados ejecutar como funciones.

  • Estrategia de Despliegue Compatible: la estrategia de despliegue de plataforma se basa en contenedores orquestados por Kubernetes y gestionados por un CaaS con capacidad para integrar con servicios Cloud (más detalle en este Link) por lo que para evitar gestión de múltiples tecnologías era muy recomendable que las funciones FaaS se pudieran desplegar como contenedores dentro de un clúster Kubernetes (incluidos los de los proveedores Clouds).

  • Sencillez y Extensibilidad de la Tecnología: no podemos ni queremos olvidar que uno de los objetivos de la plataforma es simplificar el uso de las tecnologías, por tanto, el desarrollador de Funciones debería ser capaz de hacerlo de forma sencilla y el equipo de plataforma debería poder extender esta tecnología para integrarla en Plataforma y extenderla cuando sea necesario.

  • Madurez, Comunidad, Popularidad, Extensibilidad, Documentación y Soporte: en este último punto del análisis hemos agregado diversas consideraciones (en la fase de análisis se estudiaron por separado) como eran la madurez de la tecnología, la comunidad que existía alrededor de la tecnología, la popularidad de esta tecnología, la documentación existente (calidad y cantidad) y el soporte de un gran player que garantice la evolución y mantenimiento de la tecnología.

De este análisis quedaron tres tecnologías finalistas:

  • Apache OpenWhisk sobre la que IBM es el principal contribuidor y lo ofrece como servicio en su Cloud.

  • Spring Cloud Functions que, además de ser parte del ecosistema Spring, puede ser usada como fachada para AWS Lambda o Azure Functions, …

  • Fn Project soportado por Oracle y ofrecido como servicio en su Cloud.

El primero que descartamos fue Spring Cloud Functions porque carecía de una característica que resultaba fundamental que era el soporte multi-tecnología y que las otras dos si soportaban.

En el análisis final entre OpenWhisk y Fn Project finalmente nos decantamos por Fn Project, porque, aunque OpenWhisk es algo más popular y tiene buena documentación es bastante más complejo en cuanto a su uso que Fn Project (por ejemplo, arrastra diversas tecnologías). Además, Fn Project ofrece integraciones con tecnologías como Spring Cloud Functions (lo que permite crear funciones Spring Cloud Functions que ejecuten en el Engine Fn) y GraalVM.

Tecnología Seleccionada para Incorporar en Plataforma: Fn Project

¿Cómo Funciona?

Fn está construido en Go y su arquitectura se basa en Docker. Está compuesto por dos componentes principales:

  • La línea de comandos de Fn, que permite controlar todos los aspectos del framework (como creación de funciones, despliegue, …) e interactuar con el servidor de Fn:

  • El servidor Fn, que es una aplicación Docker simple.

 

Crear una función con Fn es tan sencillo como:

  • Crear la función con la CLI de Fn: Fn genera el archivo de configuración de Fn y un proyecto simple basado en la plantilla de la tecnología seleccionada.

  • Desplegar la función con la CLI de Fn: con esto se hace el Push de la imagen Docker de la función al repositorio Docker elegido (local o remoto) y notifica al servidor sobre la existencia y la ubicación de esta última versión.

Las funciones desplegadas en Fn se ejecutan en contenedores aislados, lo que permite el soporte de muchos lenguajes. En sus ejemplos incluso explican como generar una función desde una imagen Docker existente (ver). Además, para mayor comodidad, Fn ofrece un conjunto de plantillas de tiempo de ejecución incorporadas, facilitando el arranque en una gran variedad de lenguajes y versiones (Go, múltiples versiones de Java, múltiples versiones de Python, etc.).

En Fn, los argumentos de las funciones se pasan vía STDIN, y su valor de retorno se escribe en STDOUT. Si los argumentos y valores de retorno no son valores simples (por ejemplo, un objeto JSON), entonces son serializados por una capa de abstracción proporcionada por el propio Fn en forma de un Kit de Desarrollo de Funciones o FDK.

En Java

En Python

 

 

Arquitectura

En ejecución, la arquitectura de Fn es esta:

 

Donde un balanceador de carga proporciona un frontend a varios servidores Fn y cada servidor gestiona y ejecuta el código de la función según sea necesario. Los servidores pueden ser escalados según sea necesario.

Fn UI

Fn tiene una UI que permite gestionar e interactuar con el servidor Fn, permitiendo ver métricas sobre las funciones desplegadas:

Así como invocarlas: