Construire notre propre serveur sans serveur basé sur Fn

Construire notre propre serveur sans serveur basé sur Fn

Informatique sans serveur est l’une des tendances les plus marquantes du cloud computing. Le principe de fonctionnement de base est que l’infrastructure n’est pas l’affaire du DevOps, mais du fournisseur de services. La mise à l'échelle des ressources s'ajuste automatiquement à la charge et présente un taux de changement élevé.

Une autre caractéristique commune est la tendance à minimiser et à concentrer le code, c'est pourquoi l'informatique sans serveur est parfois appelée fonction en tant que service (FaaS).

Historiquement, le premier fournisseur de cloud à proposer FaaS avec AWS Lambda était Amazon, d'où son nom. D’autres fournisseurs de services cloud proposent également des services similaires :

  • Fonctions cloud de Google
  • Fonctions Azure de Microsoft

Toutes ces sociétés proposent une informatique sans serveur, une mise à l'échelle automatique et ne paient que pour ce que vous utilisez réellement, mais elles enferment les clients dans leur produit propriétaire. Cependant, il existe des alternatives gratuites et open source pour l’informatique sans serveur. Il est à noter:

  • Plate-forme Apache OpenWhisk, développé dans un incubateur par IBM,
  • Fonctions Spring Cloud, dans le cadre d'un écosystème Spring Framework assez riche, qui peut également servir de façade pour AWS Lambda, Azure Functions et OpenWhisk,
  • Projet Fn, pris en charge par Oracle.

Tous sont totalement indépendants des cloud, c'est-à-dire qu'ils peuvent être installés dans n'importe quel cloud, y compris le vôtre, public ou privé, et bien sûr dans Exoscale.

Comment fonctionne le projet Fn

Fn est entièrement basé sur Docker et se compose de deux composants principaux :

  • Programme CLI conçu pour gérer tous les aspects de l'infrastructure Fn et interagit avec le serveur Fn,
  • Le serveur Fn lui-même est une application standard conditionnée dans un conteneur Docker.

Les fonctions déployées dans Fn sont également exécutées dans des conteneurs séparés, ce qui permet de supporter de nombreux langages de programmation, par exemple... Clojure !

Les arguments de la fonction sont transmis à l'entrée standard (STDIN), les résultats sont écrits sur la sortie standard (STDOUT). Si les arguments ou les valeurs de retour ne sont pas des valeurs simples (comme un objet JSON), ils peuvent être convertis à l'aide d'une couche d'abstraction fournie par Fn lui-même sous la forme d'un Function Development Kit (FDK).

Pour plus de commodité, des ensembles de modèles intégrés sont proposés pour faciliter le déploiement de FaaS dans une liste complète de différents langages et de leurs versions (Go, différentes versions de Java, Python, etc.).

Créer un FaaS est simple en suivant ce schéma :

  • Déploiement de la fonction à l'aide de la CLI Fn : un fichier de configuration d'application pour Fn est créé en fonction du modèle sélectionné.
  • Nous déployons notre propre fonction, toujours en utilisant CLI Fn : l'image du conteneur est placée dans un certain référentiel, après quoi le serveur est informé de l'existence et du placement de cette image.

Construire notre propre serveur sans serveur basé sur Fn
Le principe de délivrance de fonctions à Fn

Installation locale et test des fonctions sans serveur

Commençons par installer Fn sur la machine locale. Tout d’abord, Docker est installé, comme l’exige Fn. En supposant que nous sommes sur Debian/Ubuntu :

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

Ou utilisez une version de gestionnaire de packages/Docker en fonction de votre système. Ensuite, vous pouvez passer directement à l’installation de la CLI Fn. Par exemple, en utilisant curl :

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

Si vous êtes sous OSX avec Homebrew installé, vous pouvez procéder dans l'autre sens :

$ brew install fn

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

Nous sommes maintenant prêts à déployer initialement notre fonction à l'aide de la CLI. Pour plus de simplicité, nous utiliserons un environnement de lancement intégré, tel que Node :

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

Creating function at: /hellonode
Function boilerplate generated.
func.yaml created.

Un nouveau répertoire sera créé hellonode pour développer davantage notre fonction Fn avec quelques fichiers de configuration de base. Dans le répertoire nouvellement créé, vous pouvez créer votre application en suivant les normes du langage ou du runtime choisi :

# Каталог с 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 crée la structure initiale du projet, crée un fichier func.yaml, contenant les paramètres nécessaires pour Fn, et définit le modèle du code dans la langue que vous avez choisie.

Dans le cas du runtime Node, cela signifie :

$ 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}
})

Nous allons maintenant tester rapidement notre fonction localement pour voir comment tout fonctionne.

Tout d’abord, nous allons démarrer le serveur Fn. Comme déjà mentionné, le serveur Fn est un conteneur Docker, donc après le démarrage, il ira prendre l'image du registre Docker.

$ fn start -d                    # запускаем локальный сервер в фоне

Unable to find image 'fnproject/fnserver:latest' locally
latest: Pulling from fnproject/fnserver
ff3a5c916c92: Pull complete
1a649ea86bca: Pull complete
ce35f4d5f86a: Pull complete

...

Status: Downloaded newer image for fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

Pour exécuter notre fonction, elle doit être « déployée ». Cela nécessite имя приложения: Dans Fn, toutes les applications doivent être spécifiées comme espaces de noms pour les fonctions associées.

Fn CLI recherchera le fichier func.yaml dans le répertoire courant qui sera utilisé pour configurer la fonction. Vous devez donc d'abord vous rendre dans notre annuaire hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # выкатываем функцию локально, имя приложения - fnexo.
                                 # параметр local не заливает образ в удаленный реестр,
                                 # запуская его напрямую

Deploying hellonode to app: fnexo
Bumped to version 0.0.2
Building image nfrankel/hellonode:0.0.3 .
Updating function hellonode using image nfrankel/hellonode:0.0.3...
Successfully created app:  fnexo
Successfully created function: hellonode with nfrankel/hellonode:0.0.3
Successfully created trigger: hellonode-trigger

Comme vous pouvez le voir sur le résultat de la commande, une nouvelle image de conteneur Docker est créée contenant notre fonction. La fonction est prête à être appelée, et nous avons deux manières de le faire :

  • en utilisant la commande Fn invoke
  • appeler directement via http

Défi invoke via Fn, il émule simplement le travail via HTTP pour les tests, ce qui est pratique pour des tests rapides :

$ fn invoke fnexo hellonode      # вызываем функцию hellonode приложения fnexo

{"message":"Hello World"}

Pour appeler directement une fonction, vous devez connaître l'URL complète :

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

{"message":"Hello World"}

Le serveur Fn expose ses fonctions sur le port 8080 et l'URL de la fonction semble correspondre au modèle t/app/function, mais pas complètement. Grâce à HTTP, une fonction n'est pas appelée directement, mais via ce qu'on appelle un déclencheur qui, selon son nom, « démarre » l'appel de fonction. Les déclencheurs sont définis dans `func.yml projet:

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 триггера

Nous pouvons changer le nom du déclencheur pour qu'il corresponde au nom de la fonction, cela simplifiera tout :

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # совпадает с именем функции

Ensuite, nous exécutons à nouveau la livraison de la fonction et l'appelons à partir d'un nouveau déclencheur :

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

{"message":"Hello World"}

Tout fonctionne ! Il est temps de passer aux expérimentations grandeur nature et de publier notre FaaS sur le serveur !

Installation de services de fonctions sans serveur sur votre propre infrastructure

Installons rapidement une machine virtuelle à l'aide de la CLI Exoscale. Si vous ne l'avez pas encore configuré, vous pouvez utiliser notre guide de démarrage rapide. C'est un outil sympa qui augmentera encore plus votre productivité. N'oubliez pas que vous devez configurer une règle pour ouvrir le port 8080 dans le groupe de sécurité ! Les commandes suivantes lanceront une machine virtuelle propre, prête à héberger nos fonctions :

$ 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

Ensuite, vous pouvez vous connecter à la machine virtuelle et installer le serveur Fn distant :

$ exo ssh fn-server

The authenticity of host '185.19.30.175 (185.19.30.175)' can't be established.
ECDSA key fingerprint is SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '185.19.30.175' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

Installez ensuite Docker et le serveur Fn de la même manière que cela a déjà été fait sur la machine locale, démarrez le serveur :

$ 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 prêt à recevoir des fonctions ! Pour un transfert ciblé de fonctions vers un serveur distant, nous utiliserons la commande deploy depuis l'ordinateur local en omettant le drapeau --local.

De plus, Fn vous demande de spécifier l'emplacement du serveur Fn et du registre Docker. Ces options peuvent être définies via des variables d'environnement FN_API_URL и FN_REGISTRY respectivement, mais offre également un moyen plus pratique de gérer facilement la création et la gestion des configurations pour le déploiement.

En termes Fn, la configuration de déploiement s'appelle context. La commande suivante créera le contexte :

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

Vous pouvez afficher les contextes disponibles comme ceci :

$ fn list contexts

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

Et passez au contexte qui vient d'être créé comme ceci :

 $ fn use context exoscale

 Now using context: exoscale

À partir de là, la fonctionnalité Fn téléchargera les images Docker à l'aide du compte DockerHub sélectionné (dans mon cas - nfrankel), puis informez le serveur distant (dans cet exemple - http://185.19.30.175:8080) sur l'emplacement et la version de la dernière image contenant votre fonction.

$ fn deploy --app fnexo .   # выполняется на локальной машине из каталога hellonode

Deploying function at: /.
Deploying hellonode to app: fnexo
Bumped to version 0.0.5
Building image nfrankel/hellonode:0.0.5 .

Enfin:

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

{"message":"Hello World"}

Construire notre propre serveur sans serveur basé sur Fn
Cycle de vie des fonctions dans l'informatique sans serveur basée sur Fn

Avantages de l'informatique sans serveur selon vos propres capacités

L'informatique sans serveur est une solution pratique pour implémenter rapidement des parties indépendantes d'une application qui interagissent avec des applications ou des microservices plus complexes.

Cela est souvent dû au coût caché lié au choix du fournisseur choisi, qui, en fonction du cas d'utilisation spécifique et du volume, peut entraîner des coûts plus élevés et une flexibilité réduite à l'avenir.

Les architectures multi-cloud et cloud hybride souffrent également dans ce cas, car vous pouvez facilement vous retrouver dans une situation où vous souhaiteriez utiliser l'informatique sans serveur, mais en raison des politiques de l'entreprise, cela peut ne pas être possible.

Fn est assez simple à utiliser et peut fournir presque la même interface FaaS, avec peu de frais généraux. Il élimine toute dépendance vis-à-vis d'un fournisseur et peut être installé localement ou chez n'importe quel fournisseur de solution cloud pratique de votre choix. Il y a également la liberté de choisir un langage de programmation.

Cet article ne couvre que les bases de Fn, mais la création de votre propre environnement d'exécution est assez simple et l'architecture globale peut être déployée plus largement à l'aide d'un équilibreur de charge Fn ou en plaçant Fn derrière un proxy pour plus de protection.

Source: habr.com

Ajouter un commentaire