Construimos nuestro propio serverless basado en Fn

Construimos nuestro propio serverless basado en Fn

Computación sin servidor — una de las tendencias más destacadas en la computación en la nube. El principio básico de operación es que la infraestructura es responsabilidad del proveedor de servicios, no de los DevOps. La escalabilidad de los recursos se ajusta automáticamente a la carga y tiene una alta velocidad de cambio.

Otra característica común es la tendencia a minimizar y enfocarse en el código, por lo que la computación sin servidor a veces se llama "función como servicio" (FaaS).

Históricamente, el primer proveedor de servicios en la nube que ofreció FaaS con AWS Lambda fue Amazon, de donde proviene este nombre. Otros proveedores de servicios en la nube también ofrecen análogos:

  • Cloud Functions de Google
  • Azure Functions de Microsoft

Todas estas empresas ofrecen computación sin servidor, escalabilidad automática y pago solo por los recursos realmente utilizados, pero al mismo tiempo vinculan a los clientes a su producto propietario. Sin embargo, existen alternativas gratuitas de código abierto para implementar computación sin servidor. Cabe destacar:

  • La plataforma Apache OpenWhisk, desarrollada en el incubador de IBM,
  • Spring Cloud Functions, como parte de un ecosistema bastante rico del Spring Framework, que también puede utilizarse como fachada para AWS Lambda, Azure Functions y OpenWhisk,
  • El proyecto Fn, respaldado por Oracle.

Todos ellos son completamente independientes de la nube, es decir, se pueden instalar en cualquier nube, incluyendo la suya propia, pública o privada, y, por supuesto, en Exoscale.

Cómo está estructurado el proyecto Fn

Fn se basa completamente en Docker, y consta de dos componentes principales:

  • Una herramienta de línea de comandos (CLI), diseñada para gestionar todos los aspectos de la infraestructura de Fn, y que interactúa con el servidor de Fn,
  • El propio servidor de Fn, una aplicación estándar empaquetada en un contenedor de Docker.

Las funciones desplegadas en Fn también se ejecutan en contenedores separados, lo que permite soportar una variedad de lenguajes de programación, por ejemplo… ¡Clojure!

Los argumentos de las funciones se pasan a través de la entrada estándar (STDIN), y los resultados se escriben en la salida estándar (STDOUT). Si los argumentos o los valores devueltos no son valores simples (por ejemplo, un objeto JSON), pueden transformarse utilizando una capa de abstracción proporcionada por Fn en forma de un kit de desarrollo de funciones (FDK).

Para mayor comodidad, se ofrecen conjuntos de plantillas integradas que facilitan el despliegue de FaaS en una amplia gama de lenguajes y versiones diferentes (Go, varias versiones de Java, Python, etc.).

Crear FaaS es sencillo, siguiendo este esquema:

  • Desplegamos la función utilizando CLI Fn: se crea un archivo de configuración de la aplicación para Fn, basado en la plantilla seleccionada.
  • Desplegamos nuestra propia función, de nuevo usando CLI Fn: la imagen del contenedor se coloca en un repositorio, después de lo cual el servidor se notifica sobre la existencia y ubicación de esta imagen.

Construimos nuestro propio serverless basado en Fn
Principio de entrega de funciones en Fn

Instalación local y pruebas de funciones sin servidor

Comencemos a instalar Fn en la máquina local. Primero, se instala Docker, como requiere Fn. Se asume que estamos en Debian/Ubuntu:

$ sudo apt-get update
$ sudo apt-get install docker.io

O bien, usa el gestor de paquetes/compilación de Docker según tu sistema. Luego, se puede pasar directamente a la instalación de Fn CLI. Por ejemplo, usando curl:

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

Si estás trabajando en OSX con Homebrew instalado, puedes optar por otro enfoque:

$ brew install fn

==> Descargando https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Descargando desde https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Vertiendo fn-0.5.8.high_sierra.bottle.tar.gz
  /usr/local/Cellar/fn/0.5.8: 5 archivos, 16.7MB

Ahora todo está listo para el despliegue inicial de nuestra función utilizando CLI. Para simplificar, utilizaremos el entorno incorporado para ejecutar, por ejemplo, Node:

$ fn init --runtime node --trigger http hellonode

Creando función en: /hellonode
Plantilla de función generada.
func.yaml creado.

Se creará un nuevo directorio hellonode para el desarrollo posterior de nuestra función Fn con algunos archivos de configuración básicos. Dentro del nuevo directorio, puedes crear tu aplicación, siguiendo los estándares del lenguaje o entorno de ejecución que elegiste:

# Каталог с node выглядит так:

   hellonode
   ├── func.js
   ├── func.yaml
   └── package.json

# Свежеустановленное окружение Java11 такое:

   hellojava11
   ├── func.yaml
   ├── pom.xml
   └── src
       ├── main
       │   └── java
       │       └── com
       │           └── example
       │               └── fn
       │                   └── HelloFunction.java
       └── test
           └── java
               └── com
                   └── example
                       └── fn
                           └── HelloFunctionTest.java

Fn crea la estructura inicial del proyecto, crea el archivo func.yaml, que contiene las configuraciones necesarias para Fn, y establece la plantilla para el código en el lenguaje que elegiste.

En el caso del entorno de ejecución Node, esto significa:

$ cat hellonode/func.js

const fdk=require('@fnproject/fdk');

fdk.handle(function(input){
  let name = 'World';
  if (input.name) {
    name = input.name;
  }
  return {'message': 'Hello ' + name}
})

Ahora, rápidamente verificaremos nuestra función localmente para ver cómo funciona todo.

Para comenzar, iniciaremos el servidor Fn. Como se mencionó antes, el servidor Fn es un contenedor Docker, por lo tanto, después de iniciarse, irá y tomará la imagen del registro de Docker.

$ fn start -d                    # iniciamos el servidor local en segundo plano

No se pudo encontrar la imagen 'fnproject/fnserver:latest' localmente
latest: Descargando de fnproject/fnserver
ff3a5c916c92: Descarga completa
1a649ea86bca: Descarga completa
ce35f4d5f86a: Descarga completa

...

Estado: Imagen más nueva descargada para fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

Para ejecutar nuestra función, debemos "desplegarla". Para esto se requiere nombre de la aplicación: en Fn, todas las aplicaciones deben estar definidas como espacios de nombres para las funciones relacionadas.

El CLI de Fn buscará el archivo func.yaml en el directorio actual, que se utilizará para configurar la función. Así que primero debemos ir a nuestro directorio hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # desplegamos la función localmente, nombre de la aplicación - fnexo.
                                 # el parámetro local no sube la imagen al registro remoto,
                                 # ejecutándolo directamente

Desplegando hellonode en la aplicación: fnexo
Versión 0.0.2 aumentada
Construyendo la imagen nfrankel/hellonode:0.0.3 .
Actualizando la función hellonode usando la imagen nfrankel/hellonode:0.0.3...
Aplicación creada con éxito:  fnexo
Función creada con éxito: hellonode con nfrankel/hellonode:0.0.3
Desencadenador creado con éxito: hellonode-trigger

Como se puede ver en la salida del comando, se está creando una nueva imagen de contenedor para Docker que contiene nuestra función. La función está lista para ser invocada, y tenemos dos maneras de hacerlo:

  • usando el comando Fn invoke
  • invocándola directamente a través de http

mountsnoop.py invoke a través de Fn simplemente emula el trabajo sobre HTTP para pruebas, lo cual es conveniente para una verificación rápida:

$ fn invoke fnexo hellonode      # invocamos la función hellonode de la aplicación fnexo

{"message":"Hello World"}

Para invocar la función directamente, se debe conocer la URL completa:

$ curl http://localhost:8080/t/fnexo/hellonode-trigger

{"message":"Hello World"}

El servidor Fn proporciona sus funciones a través del puerto 8080, y, al parecer, la URL de la función corresponde al esquema t/app/function, aunque no completamente. A través de HTTP, la función no se invoca directamente, sino a través de lo que se llama un desencadenador, que, como su nombre indica, "activa" la invocación de la función. Los desencadenadores se definen en `func.yml el proyecto:

schema_version: 20180708
name: hellonode
version: 0.0.3
runtime: node
entrypoint: node func.js
format: json
triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode-trigger    # URL del desencadenador

Podemos cambiar el nombre del desencadenador para que coincida con el nombre de la función, lo que simplificará todo:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # coincide con el nombre de la función

Luego, reiniciamos el despliegue de la función y la invocamos desde el nuevo desencadenador:

$ fn deploy --app fnexo hellonode --local
$ curl http://localhost:8080/t/fnexo/hellonode

{"message":"Hola Mundo"}

¡Todo funciona! ¡Es el momento perfecto para experimentar y publicar nuestro FaaS en el servidor!

Instalación de servicios de funciones sin servidor en la infraestructura propia

Rápidamente instalemos una máquina virtual usando la CLI de Exoscale. Si aún no la has configurado, puedes utilizar nuestro tutorial para un inicio rápido. Esta es una excelente herramienta que mejorará aún más tu productividad. ¡No olvides configurar una regla para abrir el puerto 8080 en el Grupo de Seguridad! Los siguientes comandos lanzarán una máquina virtual limpia, lista para alojar nuestras funciones:

$ exo firewall create fn-securitygroup
$ exo firewall add fn-securitygroup ssh --my-ip
$ exo firewall add fn-securitygroup -p tcp -P 8080-8080 -c 0.0.0.0/0
$ exo vm create fn-server -s fn-securitygroup

Luego, puedes entrar por ssh a la máquina virtual e instalar el servidor Fn remoto:

$ exo ssh fn-server

No se puede establecer la autenticidad del host '185.19.30.175 (185.19.30.175)'.
La huella digital de la clave ECDSA es SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
¿Estás seguro de que deseas continuar conectándote (sí/no)? sí
Advertencia: '185.19.30.175' (ECDSA) se ha añadido permanentemente a la lista de hosts conocidos.
Bienvenido a Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

Luego, instalamos Docker y el servidor Fn de la misma manera que ya se hizo en la máquina local, iniciamos el servidor:

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo systemctl start docker
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
$ sudo fn start

...

    ______
   / ____/___
  / /_  / __ 
 / __/ / / / / 
/_/   /_/ /_/ 
    v0.3.643

Fn está listo para recibir funciones. Para la transmisión de funciones al servidor remoto, utilizaremos el comando deploy desde la computadora local, omitiendo la bandera --local.

Además, Fn requiere que se especifiquen la ubicación del servidor Fn y el registro de Docker. Estos parámetros pueden establecerse a través de variables de entorno FN_API_URL y FN_REGISTRY respectivamente, pero también se propone una forma más conveniente para la gestión fácil de la creación y gestión de configuraciones para el despliegue.

En términos de Fn, la configuración para el despliegue se llama contexto. El siguiente comando creará el contexto:

$ fn create context exoscale --provider default --api-url http://185.19.30.175:8080 --registry nfrankel

Puedes ver los contextos disponibles así:

$ fn list contexts

CURRENT NAME      PROVIDER      API URL                      REGISTRY
    default       default       http://localhost:8080/
    exoscale      default       http://185.19.30.175:8080    nfrankel

Y cambiar al contexto que acaba de ser creado así:

 $ fn use context exoscale

 Ahora usando el contexto: exoscale

A partir de este punto, la entrega de funciones Fn cargará imágenes Docker utilizando la cuenta seleccionada en DockerHub (en mi caso — nfrankel), después de lo cual notificará al servidor remoto (en este ejemplo — http://185.19.30.175:8080) sobre la ubicación y la versión de la última imagen que contiene tu función.

$ fn deploy --app fnexo .   # ejecutado en la máquina local desde el directorio hellonode

Desplegando función en: \/.
Desplegando hellonode en la aplicación: fnexo
Actualizado a la versión 0.0.5
Construyendo imagen nfrankel\/hellonode:0.0.5 .

Finalmente:

$ curl http:\/\/185.19.30.175:8080\/t\/fnexo\/hellonode

{"message":"Hola Mundo"}

Construimos nuestro propio serverless basado en Fn
Ciclo de vida de la función en computación sin servidor basada en Fn

Ventajas de la computación sin servidor en sus propias instalaciones

La computación sin servidor es una solución conveniente para la rápida implementación de partes independientes de la aplicación que interactúan con aplicaciones más complejas o microservicios.

A menudo, esto está asociado con el costo oculto de estar atado a un proveedor elegido, lo que, dependiendo del caso de uso específico y del volumen, puede llevar a mayores costos y a una disminución de la flexibilidad en el futuro.

Las arquitecturas multicloud e híbridas también sufren en este caso, ya que uno puede encontrarse fácilmente en una situación en la que se desearía utilizar la computación sin servidor, pero debido a la política corporativa, esto puede ser imposible.

Fn es bastante fácil de usar, puede proporcionar casi la misma interfaz FaaS, con pocos gastos. Elimina cualquier dependencia del proveedor, se puede instalar localmente o en cualquier proveedor de servicios en la nube de tu elección. También hay libertad en la elección del lenguaje de programación.

El artículo presenta solo los fundamentos de Fn, pero crear tu propio entorno de ejecución es bastante sencillo, y la arquitectura general se puede ampliar utilizando el equilibrador de carga Fn, o alojando Fn detrás de un proxy para protección.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster