Wir bauen unser eigenes serverless auf Basis von Fn

Wir bauen unser eigenes serverless auf Basis von Fn

Serverlose Berechnungen — ist einer der auffälligsten Trends in der Cloud-Computing. Das Grundprinzip besteht darin, dass die Infrastruktur nicht die Sorge der DevOps ist, sondern des Dienstanbieters. Die Skalierung der Ressourcen passt sich automatisch an die Last an und verfügt über eine hohe Änderungsrate.

Ein weiteres gemeinsames Merkmal ist die Tendenz zur Minimierung und Fokussierung des Codes, weshalb serverlose Berechnungen manchmal als "Funktion als Dienst" (FaaS) bezeichnet werden.

Historisch gesehen war der erste Anbieter von Cloud-Diensten, der FaaS mit AWS Lambda anbot, Amazon, von wo der Name stammt. Andere Cloud-Dienstanbieter bieten ebenfalls Entsprechungen an:

  • Cloud Functions von Google
  • Azure Functions von Microsoft

All diese Unternehmen bieten serverlose Berechnungen, automatische Skalierung und Zahlung nur für tatsächlich genutzte Ressourcen an, binden jedoch die Kunden an ihr proprietäres Produkt. Es gibt jedoch kostenlose Open-Source-Alternativen, um serverlose Berechnungen zu organisieren. Erwähnenswert sind:

  • Die Plattform Apache OpenWhisk, entwickelt im Inkubator von IBM,
  • Spring Cloud Functions, als Teil eines recht umfangreichen Ökosystems des Spring Frameworks, das auch als Fassade für AWS Lambda, Azure Functions und OpenWhisk verwendet werden kann,
  • Das Projekt Fn, unterstützt von Oracle.

Alle sind vollständig cloudunabhängig, das heißt, sie können in jeder Cloud installiert werden, einschließlich Ihrer eigenen, öffentlichen oder privaten, und natürlich in Exoscale.

Wie das Projekt Fn aufgebaut ist

Fn basiert vollständig auf Docker und besteht aus zwei Hauptkomponenten:

  • CLI-Programmen, die zur Verwaltung aller Aspekte der Fn-Infrastruktur und zur Interaktion mit dem Fn-Server entwickelt wurden,
  • Dem eigentlichen Fn-Server, einer normalen Anwendung, die in einem Container für Docker verpackt ist.

Funktionen, die in Fn bereitgestellt werden, werden ebenfalls in einzelnen Containern ausgeführt, wodurch eine Vielzahl von Programmiersprachen unterstützt wird, zum Beispiel… Clojure!

Die Argumente der Funktionen werden über die Standard-Eingabe (STDIN) übergeben, die Ergebnisse werden auf die Standard-Ausgabe (STDOUT) geschrieben. Wenn die Argumente oder Rückgabewerte keine einfachen Werte sind (z. B. JSON-Objekt), können sie über die von Fn bereitgestellte Abstraktionsschicht mithilfe des Function Development Kits (FDK) umgewandelt werden.

Zur Vereinfachung werden vorgefertigte Vorlagen angeboten, die die Bereitstellung von FaaS in einer breiten Palette von Programmiersprachen und deren Versionen (Go, verschiedene Java-Versionen, Python usw.) erleichtern.

FaaS ist einfach zu erstellen, indem Sie diesem Schema folgen:

  • Bereitstellung der Funktion über die Fn CLI: Eine Konfigurationsdatei für die App wird basierend auf der gewählten Vorlage erstellt.
  • Rollen Sie Ihre eigene Funktion wieder über die Fn CLI aus: Das Container-Image wird in ein Repository eingestellt, woraufhin der Server über dessen Existenz und Standort informiert wird.

Wir bauen unser eigenes serverless auf Basis von Fn
Prinzip der Bereitstellung von Funktionen in Fn

Lokale Installation und Testung von serverlosen Funktionen

Lassen Sie uns mit der Installation von Fn auf dem lokalen Computer beginnen. Zuerst wird Docker installiert, wie von Fn gefordert. Wir nehmen an, dass wir auf Debian/Ubuntu arbeiten:

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

Oder verwenden Sie den Paketmanager beziehungsweise die Docker-Installation entsprechend Ihrer Systemarchitektur. Anschließend können Sie direkt zur Installation der Fn CLI übergehen. Beispielsweise mit curl:

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

Wenn Sie unter OSX mit installiertem Homebrew arbeiten, können Sie auch einen anderen Weg einschlagen:

$ brew install fn

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

Jetzt ist alles bereit für die erste Bereitstellung unserer Funktion mit der CLI. Zur Vereinfachung verwenden wir die integrierte Runtime-Umgebung, zum Beispiel Node:

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

Funktion wird erstellt unter: /hellonode
Funktionsvorlage generiert.
func.yaml erstellt.

Ein neues Verzeichnis wird erstellt hellonode für die weitere Entwicklung unserer Fn-Funktion mit einigen grundlegenden Konfigurationsdateien. Innerhalb des neu erstellten Verzeichnisses können Sie Ihre Anwendung gemäß den Standards der von Ihnen gewählten Programmiersprache oder Laufzeitumgebung entwickeln:

# Каталог с 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 erstellt die anfängliche Projektstruktur, erstellt die Datei func.yaml, der die erforderlichen Einstellungen für Fn enthält und eine Vorlage für den Code in der von Ihnen gewählten Sprache festlegt.

Im Falle der Node-Laufzeit bedeutet dies:

$ cat hellonode/func.js

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

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

Jetzt werden wir schnell unsere Funktion lokal überprüfen, um zu sehen, wie alles funktioniert.

Zunächst starten wir den Fn-Server. Wie bereits erwähnt, handelt es sich bei dem Fn-Server um einen Docker-Container, der nach dem Start das Image aus dem Docker-Registry abruft.

$ fn start -d                    # starten Sie den lokalen Server im Hintergrund

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

...

Status: Newer image for fnproject/fnserver:latest heruntergeladen
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

Um unsere Funktion zu starten, muss sie "deployed" werden. Dazu benötigen wir den Anwendungsnamen: In Fn müssen alle Anwendungen als Namensräume für die zugehörigen Funktionen definiert werden.

Das Fn-CLI sucht nach einer Datei func.yaml im aktuellen Verzeichnis, die zur Konfiguration der Funktion verwendet wird. Daher wechseln wir zunächst in unser Verzeichnis hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # wir deployen die Funktion lokal, der Anwendungsname ist fnexo.
                                 # Der Parameter local lädt das Image nicht in das entfernte Registry hoch,
                                 # sondern startet es direkt

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

Wie aus der Ausgabe des Befehls zu sehen ist, wird ein neues Container-Image für Docker erstellt, das unsere Funktion enthält. Die Funktion ist bereit für den Aufruf, und wir haben zwei Möglichkeiten, dies zu tun:

  • unter Verwendung des Fn-Befehls invoke
  • die Funktion direkt über http

Aufruf invoke über Fn emuliert einfach die HTTP-Verarbeitung für Tests, was praktisch ist für eine schnelle Überprüfung:

$ fn invoke fnexo hellonode      # wir rufen die Funktion hellonode der Anwendung fnexo auf

{"message":"Hallo Welt"}

Um die Funktion direkt aufzurufen, muss die vollständige URL bekannt sein:

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

{"message":"Hallo Welt"}

Der Fn-Server stellt seine Funktionen über Port 8080 bereit, und anscheinend entspricht die URL der Funktion dem Schema t/app/function, jedoch nicht vollständig. Über HTTP wird die Funktion nicht direkt aufgerufen, sondern über einen sogenannten Trigger, der entsprechend seinem Namen den Funktionsaufruf "startet". Trigger werden in `func.yml Projekt definiert:

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 des Triggers

Wir können den Namen des Triggers ändern, damit er dem Namen der Funktion entspricht, das vereinfacht alles:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # stimmt mit dem Namen der Funktion überein

Dann starten wir die Bereitstellung der Funktion erneut und rufen sie über den neuen Trigger auf:

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

{"message":"Hallo Welt"}

Alles funktioniert! Jetzt ist es an der Zeit, praktische Experimente durchzuführen und unseren FaaS auf dem Server zu veröffentlichen!

Installation von Serverless-Funktion-Diensten auf der eigenen Infrastruktur

Lassen Sie uns schnell eine virtuelle Maschine mit der Exoscale CLI einrichten. Wenn Sie diese noch nicht konfiguriert haben – können Sie unsere Schnellstartanleitung verwenden. Es ist ein großartiges Werkzeug, das Ihre Produktivität weiter steigern wird. Vergessen Sie nicht, eine Regel zum Öffnen des Ports 8080 in der Sicherheitsgruppe einzurichten! Die folgenden Befehle starten eine saubere virtuelle Maschine, die bereit ist, unsere Funktionen zu hosten:

$ 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

Dann können Sie sich per SSH auf die virtuelle Maschine einloggen und den Fn-Server installieren:

$ exo ssh fn-server

Die Authentizität des Hosts '185.19.30.175 (185.19.30.175)' kann nicht festgestellt werden.
ECDSA-Schlüsselfingerabdruck ist SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Sind Sie sicher, dass Sie mit der Verbindung fortfahren möchten (ja/nein)? ja
Warnung: Permanently added '185.19.30.175' (ECDSA) to the list of known hosts.
Willkommen bei Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

Dann installieren wir Docker und den Fn-Server ebenso, wie wir es bereits auf der lokalen Maschine gemacht haben, und starten den Server:

$ 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 ist bereit, Funktionen zu empfangen! Um Funktionen auf den entfernten Server zu übertragen, verwenden wir den Befehl deploy von einem lokalen Computer aus und lassen das Flag weg --local.

Darüber hinaus muss Fn den Standort des Fn-Servers und des Docker-Registries angeben. Diese Parameter können über Umgebungsvariablen eingestellt werden FN_API_URL und FN_REGISTRY entsprechend, aber es wird auch eine bequemere Möglichkeit angeboten, um die Erstellung und Verwaltung von Konfigurationen für die Bereitstellung zu erleichtern.

In den Begriffen von Fn wird die Konfiguration für die Bereitstellung als context. Der folgende Befehl erstellt den Kontext:

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

Sie können die verfügbaren Kontexte wie folgt einsehen:

$ fn list contexts

AKTUELLER NAME      ANBIETER      API URL                      REGISTRIERUNG
    default       default       http://localhost:8080/
    exoscale      default       http://185.19.30.175:8080    nfrankel

Und um zum gerade erstellten Kontext zu wechseln, so:

 $ fn use context exoscale

 Jetzt wird der Kontext verwendet: exoscale

Ab diesem Punkt wird die Fn-Deployment-Funktion Docker-Images mithilfe des gewählten Kontos auf DockerHub laden (in meinem Fall — nfrankel), bevor es den entfernten Server (in diesem Beispiel — http://185.19.30.175:8080) über den Standort und die Version des letzten Images informiert, das Ihre Funktion enthält.

$ fn deploy --app fnexo .   # wird auf der lokalen Maschine aus dem Verzeichnis hellonode ausgeführt

Funktion wird bereitgestellt unter: /.
Helleonode wird an die App: fnexo bereitgestellt
Auf Version 0.0.5 erhöht
Bild nfrankel/hellonode:0.0.5 wird erstellt.

Schließlich:

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

{"message":"Hallo Welt"}

Wir bauen unser eigenes serverless auf Basis von Fn
Der Lebenszyklus einer Funktion in serverlosen Berechnungen basierend auf Fn

Vorteile von serverlosen Berechnungen auf Ihrem eigenen Infrastruktur

Serverlose Berechnungen sind eine bequeme Lösung für die schnelle Einführung unabhängiger Teile einer Anwendung, die mit komplexeren Anwendungen oder Mikrodiensten interagieren.

Oft ist dies mit versteckten Kosten aufgrund der Bindung an einen bestimmten Anbieter verbunden, was, abhängig vom spezifischen Anwendungsfall und Volumen, zu höheren Kosten und verminderten Flexibilität in der Zukunft führen kann.

Multicloud- und hybride Cloud-Architekturen leiden ebenfalls in solchen Fällen, da man leicht in eine Situation geraten kann, in der man serverlose Berechnungen nutzen möchte, dies aber aufgrund von Unternehmensrichtlinien nicht möglich ist.

Fn ist einfach zu handhaben und kann nahezu die gleiche FaaS-Oberfläche bieten, mit minimalen Kosten. Es befreit von jeglicher Anbieterbindung und kann lokal oder bei einem beliebigen Cloud-Anbieter Ihrer Wahl installiert werden. Sie haben auch die Freiheit, die Programmiersprache zu wählen.

Der Artikel behandelt nur die Grundlagen von Fn, aber das Erstellen Ihrer eigenen Laufzeitumgebung ist einfach, und Sie können die gesamte Architektur mit einem Fn-Load-Balancer erweitern oder Fn hinter einem Proxy zur Sicherung betreiben.

Quelle: habr.com

60GB SSD 8Gb DDR4