Construim propriul serverless pe baza Fn

Construim propriul serverless pe baza Fn

Calculatoare fără server — una dintre cele mai vizibile tendințe în calculul cloud. Principiul de bază este că infrastructura nu reprezintă o preocupare pentru DevOps, ci pentru furnizorul de servicii. Scalarea resurselor se ajustează automat în funcție de sarcină și are o viteză mare de schimbare.

O altă caracteristică comună este tendința de a minimiza și de a se concentra pe cod, prin urmare, calculul fără server este uneori denumit „funcție ca serviciu” (FaaS).

Furnizorul de servicii cloud care a oferit pentru prima dată FaaS cu AWS Lambda a fost Amazon, de unde provine și acest nume. Alte furnizori de servicii cloud oferă, de asemenea, echivalente:

  • Cloud Functions de la Google
  • Azure Functions de la Microsoft

Toate aceste companii oferă calculatoare fără server, scalare automată și plată doar pentru resursele efectiv utilizate, însă acestea leagă clienții de produsul lor proprietar. Cu toate acestea, există alternative gratuite și open-source pentru organizarea calculului fără server. Este important de menționat:

  • Platforma Apache OpenWhisk, dezvoltată în incubator de IBM,
  • Spring Cloud Functions, ca parte a unei ecosisteme destul de bogate a Spring Framework, care poate fi folosită și ca un fațadă pentru AWS Lambda, Azure Functions și OpenWhisk,
  • Proiectul Fn, susținut de Oracle.

Toate acestea sunt complet independente de cloud, adică se instalează în orice cloud, inclusiv cel propriu, public sau privat, și bineînțeles în Exoscale.

Cum este structurat proiectul Fn

Fn se bazează pe Docker, constând din două componente principale:

  • CLI-ul programului, destinat gestionării tuturor aspectelor infrastructurii Fn și interacționării cu serverul Fn,
  • Serverul Fn propriu-zis, o aplicație obișnuită, ambalată într-un container Docker.

Funcțiile desfășurate în Fn sunt, de asemenea, executate în containere separate, ceea ce permite suportul pentru o varietate mare de limbaje de programare, cum ar fi… Clojure!

Argumentele funcțiilor sunt transmise la standard input (STDIN), iar rezultatele sunt scrise la standard output (STDOUT). Dacă argumentele sau valorile returnate nu sunt valori simple (de exemplu, un obiect JSON) — acestea pot fi transformate folosind un strat de abstractizare furnizat de Fn sub forma unui kit de dezvoltare a funcțiilor (FDK).

Pentru comoditate, sunt disponibile seturi de șabloane integrate care facilitează desfășurarea FaaS într-o listă extinsă de diferite limbaje și versiunile acestora (Go, diverse versiuni Java, Python etc.).

Crearea FaaS este simplă, urmând acest plan:

  • Desfășurăm funcția cu ajutorul CLI Fn: se creează un fișier de configurare a aplicației pentru Fn, bazat pe șablonul ales.
  • Desfășurăm funcția proprie, de asemenea cu ajutorul CLI Fn: imaginea containerului este plasată într-un anumit depozit, după care serverul este notificat despre existența și amplasarea acestei imagini.

Construim propriul serverless pe baza Fn
Principiul livrării funcțiilor în Fn

Instalare și testare locală a funcțiilor fără server

Să începem instalarea Fn pe mașina locală. Mai întâi se instalează Docker, așa cum cere Fn. Se presupune că suntem pe Debian/Ubuntu:

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

Sau folosiți managerul de pachete/compilarea Docker conform sistemului dumneavoastră. Apoi, putem trece direct la instalarea Fn CLI. De exemplu, cu ajutorul curl:

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

Dacă lucrați pe OSX cu Homebrew instalat, puteți merge pe o altă cale:

$ brew install fn

==> Descărcare https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Descărcare de la https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Turnare fn-0.5.8.high_sierra.bottle.tar.gz
  /usr/local/Cellar/fn/0.5.8: 5 fișiere, 16.7MB

Acum totul este gata pentru desfășurarea inițială a funcției noastre folosind CLI. Pentru simplitate, vom folosi mediu integrat de rulare, de exemplu Node:

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

Crearea funcției la: /hellonode
Structura de bază a funcției generată.
func.yaml creat.

Va fi creat un nou director hellonode pentru dezvoltarea ulterioară a funcției noastre Fn cu unele fișiere de configurare esențiale. În interiorul directorului nou creat, puteți crea aplicația dumneavoastră, conform standardelor limbajului sau mediului de execuție ales:

# Каталог с 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 creează structura inițială a proiectului, creează fișierul func.yaml, conținând setările necesare pentru Fn, și stabilește șablonul pentru cod în limbajul ales.

În cazul mediului de execuție Node, aceasta înseamnă:

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

Acum vom verifica rapid funcția noastră local, pentru a vedea cum funcționează totul.

Pentru început, vom porni serverul Fn. Așa cum a fost menționat, serverul Fn este un container Docker, prin urmare, după lansare, acesta va merge și va prelua imaginea din registrul Docker.

$ fn start -d                    # pornim serverul local în fundal

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

Pentru a lansa funcția noastră, trebuie să "o publicăm". Pentru aceasta, este necesar numele aplicației: în Fn, toate aplicațiile trebuie să fie definite sub formă de spații de nume pentru funcțiile asociate.

Fn CLI va căuta un fișier func.yaml în directorul curent, care va fi utilizat pentru configurarea funcției. Așadar, mai întâi trebuie să ne mutăm în directorul nostru hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # publicăm funcția local, numele aplicației - fnexo.
                                 # parametrul local nu încarcă imaginea în registrul remote,
                                 # o rulează direct

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

După cum se poate observa din ieșirea comenzii, se creează o nouă imagine a containerului Docker care conține funcția noastră. Funcția este pregătită pentru apel, iar noi avem două modalități de a face acest lucru:

  • folosind comanda Fn invoke
  • apelând direct prin http

Apel invoke prin Fn emulează pur și simplu funcția HTTP pentru teste, ceea ce este util pentru verificări rapide:

$ fn invoke fnexo hellonode      # apelăm funcția hellonode a aplicației fnexo

{"message":"Hello World"}

Pentru a apela funcția direct, trebuie să cunoaștem URL-ul complet:

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

{"message":"Hello World"}

Serverul Fn oferă funcțiile sale prin intermediul portului 8080, iar, după cum se pare, URL-ul funcției corespunde schemei t/app/function, dar nu în întregime. Prin HTTP, funcția nu este apelată direct, ci prin așa-numitul trigger, care, conform numelui său, "activează" apelul funcției. Triggers sunt definite în `func.yml proiectul:

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-ul triggerului

Putem schimba numele triggerului pentru a corespunde numelui funcției, ceea ce va simplifica totul:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # se potrivește cu numele funcției

Apoi, relansăm livrarea funcției și o apelăm din noul trigger:

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

{"message":"Hello World"}

Totul funcționează! Este momentul perfect să trecem la experimentele reale și să publicăm FaaS-ul nostru pe server!

Instalarea serviciilor funcțiilor serverless pe propria infrastructură

Hai să instalăm rapid o mașină virtuală folosind CLI Exoscale. Dacă nu ați configurat-o încă — puteți folosi ghidul nostru pentru un start rapid. Este un instrument genial care va crește și mai mult productivitatea dumneavoastră. Nu uitați să configurați o regulă pentru a deschide portul 8080 în Security Group! Următoarele comenzi vor lansa o mașină virtuală curată, gata pentru găzduirea funcțiilor noastre:

$ 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

Apoi, puteți accesa mașina virtuală prin ssh și instala serverul Fn:

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

Apoi, instalăm Docker și serverul Fn la fel cum am făcut deja pe mașina locală, pornim serverul:

$ 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 este pregătit să primească funcții! Pentru a transmite funcții către serverul de la distanță, vom folosi comanda deploy de pe computerul local, omítând flag-ul --local.

În plus, Fn necesită specificarea locației serverului Fn și a registrului Docker. Aceste opțiuni pot fi setate prin variabilele de mediu FN_API_URL și FN_REGISTRY în consecință, dar există și o modalitate mai convenabilă pentru gestionarea ușoară a creării și gestionării configurațiilor pentru desfășurare.

În termenii Fn, configurația pentru desfășurare se numește context. Comanda următoare va crea un context:

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

Puteți vizualiza contexte disponibile astfel:

$ fn list contexts

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

Și pentru a comuta la contextul care tocmai a fost creat, astfel:

 $ fn use context exoscale

 Acum utilizăm contextul: exoscale

Începând de aici, livrarea funcțiilor Fn va încărca imagini Docker, folosind contul ales de pe DockerHub (în cazul meu — nfrankel), după care va notifica serverul îndepărtat (în acest exemplu — http://185.19.30.175:8080) despre locația și versiunea celei mai recente imagini, care conține funcția dumneavoastră.

$ fn deploy --app fnexo .   # se rulează pe mașina locală din directorul hellonode

Se desfășoară funcția la: \/.
Se desfășoară hellonode la aplicația: fnexo
S-a urcat la versiunea 0.0.5
Construind imaginea nfrankel\/hellonode:0.0.5 .

În cele din urmă:

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

{"message":"Hello World"}

Construim propriul serverless pe baza Fn
Ciclul de viață al funcției în calculul serverless bazat pe Fn

Avantajele calculului serverless pe propriile resurse

Calculul serverless este o soluție convenabilă pentru implementarea rapidă a părților independente ale aplicației, care interacționează cu aplicații sau microservicii mai complexe.

Adesea, acest lucru este asociat cu costuri ascunse legate de furnizorul ales, ceea ce, în funcție de cazul de utilizare specific și de volum, poate duce la costuri mai mari și la o flexibiltate scăzută în viitor.

Arhitecturile multi-cloud și hibride suferă de asemenea în astfel de cazuri, deoarece se poate ajunge cu ușurință în situația în care s-ar dori utilizarea calculului serverless, dar din cauza politicii de corporație acest lucru poate fi imposibil.

Fn este suficient de simplu de utilizat, poate oferi aproape aceeași interfață FaaS, cu costuri reduse. Acesta elimină orice legături cu furnizorul, poate fi instalat local sau la orice furnizor de soluții cloud ales de dumneavoastră. De asemenea, există libertatea de a alege limbajul de programare.

Articolul prezintă doar elementele de bază ale Fn, dar crearea propriului mediu de execuție este destul de simplă, iar arhitectura generală poate fi extinsă folosind un echilibrator de încărcare Fn sau situând Fn în spatele unui proxy pentru protecție.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster