Budujemy własny serverless oparty na Fn

Budujemy własny serverless oparty na Fn

Obliczenia bezserwerowe — jedna z najbardziej zauważalnych tendencji w chmurze obliczeniowej. Główną zasadą działania jest to, że infrastruktura jest troską nie DevOpsów, a dostawcy usług. Skalowanie zasobów automatycznie dostosowuje się do obciążenia i charakteryzuje się dużą szybkością zmiany.

Inną wspólną cechą jest tendencja do minimalizacji i skupienia kodu, dlatego obliczenia bezserwerowe czasami nazywa się „funkcją jako usługą” (FaaS).

Historycznie pierwszym dostawcą usług w chmurze, który zaoferował FaaS z AWS Lambda, był Amazon, skąd pochodzi ta nazwa. Inni dostawcy usług w chmurze również oferują analogi:

  • Cloud Functions od Google
  • Azure Functions od Microsoftu

Wszystkie te firmy oferują obliczenia bezserwerowe, automatyczne skalowanie i płatność tylko za faktycznie wykorzystane zasoby, jednak przywiązują klientów do swojego własnego produktu. Niemniej jednak istnieją darmowe alternatywy z otwartym źródłem do organizowania obliczeń bezserwerowych. Warto zauważyć:

  • Platformę Apache OpenWhisk, opracowywaną w inkubatorze przez IBM,
  • Spring Cloud Functions, jako część dość bogatego ekosystemu Spring Framework, który może być również używany jako fasada AWS Lambda, Azure Functions i OpenWhisk,
  • Projekt Fn, wspierany przez Oracle.

Wszystkie te rozwiązania są całkowicie niezależne od chmur, to znaczy mogą być instalowane w dowolnej chmurze, w tym w chmurze prywatnej, publicznej lub oczywiście w Exoscale.

Jak działa projekt Fn

Fn jest w pełni oparty na Dockerze, składa się z dwóch głównych komponentów:

  • CLI programu, przeznaczonego do zarządzania wszystkimi aspektami infrastruktury Fn i interakcjonującego z serwerem Fn,
  • Sama serwer Fn, zwykła aplikacja zapakowana w kontener dla Docker.

Funkcje uruchamiane w Fn są również wykonywane w oddzielnych kontenerach, co pozwala na obsługę wielu języków programowania, na przykład… Clojure!

Argumenty funkcji są przekazywane do standardowego wejścia (STDIN), a wyniki są zapisywane na standardowym wyjściu (STDOUT). Jeśli argumenty lub zwracane wartości nie są prostymi wartościami (na przykład obiekt JSON) – mogą być przetwarzane za pomocą warstwy abstrakcji, którą sam Fn udostępnia w postaci zestawu do tworzenia funkcji (FDK).

Dla wygody oferowane są wbudowane zestawy szablonów, które ułatwiają wdrażanie FaaS w szerokim wachlarzu różnych języków i ich wersji (Go, różne wersje Java, Python itd.).

Stworzenie FaaS jest proste, postępując według tego schematu:

  • Wdrażamy funkcję za pomocą CLI Fn: tworzony jest plik konfiguracyjny aplikacji dla Fn, oparty na wybranym szablonie.
  • Wypuszczamy naszą funkcję, znów za pomocą CLI Fn: obraz kontenera umieszczany jest w pewnym repozytorium, a następnie serwer jest informowany o istnieniu i lokalizacji tego obrazu.

Budujemy własny serverless oparty na Fn
Zasada dostarczania funkcji w Fn

Lokalna instalacja i testowanie bezserwerowych funkcji

Zaczynamy od instalacji Fn na lokalnej maszynie. Najpierw instalujemy Docker, jak wymaga Fn. Zakładamy, że jesteśmy na Debianie/Ubuntu:

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

Lub skorzystaj z menedżera pakietów / kompilacji Dockera zgodnie z twoim systemem. Następnie można przejść bezpośrednio do instalacji Fn CLI. Na przykład, używając curl:

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

Jeśli pracujesz na OSX i masz zainstalowanego Homebrew, można pójść inną drogą:

$ brew install fn

==> Pobieranie https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Pobieranie z https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Wylewając fn-0.5.8.high_sierra.bottle.tar.gz
  /usr/local/Cellar/fn/0.5.8: 5 plików, 16.7MB

Teraz wszystko jest gotowe do początkowego wdrożenia naszej funkcji z użyciem CLI. Dla uproszczenia będziemy używać wbudowanego środowiska uruchomieniowego, na przykład Node:

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

Tworzenie funkcji w: /hellonode
Wygenerowano szablon funkcji.
func.yaml utworzono.

Zostanie utworzony nowy katalog hellonode do dalszego rozwoju naszej funkcji Fn z kilkoma podstawowymi plikami konfiguracyjnymi. Wewnątrz nowo utworzonego katalogu możesz stworzyć swoją aplikację, przestrzegając standardów wybranego przez siebie języka lub środowiska uruchomieniowego:

# Каталог с 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 tworzy początkową strukturę projektu, tworzy plik func.yaml, zawierający niezbędne konfiguracje dla Fn oraz ustalający szablon dla kodu w wybranym języku.

W przypadku środowiska wykonawczego Node oznacza to:

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

Teraz szybko przetestujemy naszą funkcję lokalnie, aby zobaczyć, jak to wszystko działa.

Na początek uruchomimy serwer Fn. Jak już wspomniano, serwer Fn jest kontenerem Docker, więc po uruchomieniu pobierze obraz z rejestru Docker.

$ fn start -d                    # uruchamiamy lokalny serwer w tle

Nie można znaleźć obrazu 'fnproject/fnserver:latest' lokalnie
latest: Pobieranie z fnproject/fnserver
ff3a5c916c92: Pobieranie zakończone
1a649ea86bca: Pobieranie zakończone
ce35f4d5f86a: Pobieranie zakończone

...

Stan: Pobrano nowszy obraz dla fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

Aby uruchomić naszą funkcję, musimy ją "wypuścić". W tym celu wymagana jest nazwa aplikacji: w Fn wszystkie aplikacje muszą być zdefiniowane jako przestrzenie nazw dla powiązanych funkcji.

Fn CLI będzie szukać pliku func.yaml w bieżącym katalogu, który będzie używany do konfiguracji funkcji. Więc najpierw musimy przejść do naszego katalogu hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # wypuszczamy funkcję lokalnie, nazwa aplikacji - fnexo.
                                 # parametr local nie przesyła obrazu do zdalnego rejestru,
                                 # uruchamiając go bezpośrednio

Wdrażanie hellonode do aplikacji: fnexo
Zwiększono do wersji 0.0.2
Budowanie obrazu nfrankel/hellonode:0.0.3 .
Aktualizowanie funkcji hellonode przy użyciu obrazu nfrankel/hellonode:0.0.3...
Pomyślnie utworzono aplikację:  fnexo
Pomyślnie utworzono funkcję: hellonode z nfrankel/hellonode:0.0.3
Pomyślnie utworzono wyzwalacz: hellonode-trigger

Jak widać z wyjścia polecenia, tworzony jest nowy obraz kontenera dla Docker, zawierający naszą funkcję. Funkcja jest gotowa do wywołania, a mamy dwa sposoby, aby to zrobić:

  • korzystając z polecenia Fn invoke
  • wywołując bezpośrednio przez http

Wywołanie invoke Fn emuluje połączenie HTTP do testów, co jest wygodne do szybkiej weryfikacji:

$ fn invoke fnexo hellonode      # wywołujemy funkcję hellonode aplikacji fnexo

{"message":"Hello World"}

Aby wywołać funkcję bezpośrednio, musisz znać pełny URL:

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

{"message":"Hello World"}

Serwer Fn udostępnia swoje funkcje przez port 8080, a URL funkcji odpowiada schematowi t/app/function, ale nie całkowicie. Przez HTTP funkcja nie jest wywoływana bezpośrednio, lecz przez tzw. wyzwalacz, który zgodnie ze swoją nazwą "uruchamia" wywołanie funkcji. Wyzwalacze są definiowane w `func.yml projekcie:

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 wyzwalacza

Możemy zmienić nazwę wyzwalacza, aby odpowiadała nazwie funkcji, co wszystko uprości:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # pasuje do nazwy funkcji

Następnie uruchamiamy wdrażanie funkcji jeszcze raz i wywołujemy ją z nowego wyzwalacza:

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

{"message":"Hello World"}

Wszystko działa! Czas przejść do rzeczywistych eksperymentów i opublikować nasze FaaS na serwerze!

Instalacja serwisów funkcji bezserwerowych na własnej infrastrukturze

Szybko zainstalujmy maszynę wirtualną korzystając z CLI Exoscale. Jeśli jeszcze jej nie skonfigurowałeś — możesz skorzystać z naszego przewodnika szybkiego uruchomienia. To świetne narzędzie, które jeszcze bardziej zwiększy Twoją produktywność. Nie zapomnij o skonfigurowaniu reguły otwierającej port 8080 w grupie bezpieczeństwa! Następujące polecenia uruchomią czystą maszynę wirtualną, gotową do hostowania naszych funkcji:

$ 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

Następnie można zalogować się przez ssh na maszynę wirtualną i zainstalować serwer 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)

Następnie instalujemy Dockera i serwer Fn tak jak to już było robione na lokalnej maszynie, uruchamiamy serwer:

$ 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 jest gotowy do odbioru funkcji! Do przesyłania funkcji na zdalny serwer użyjemy komendy deploy z lokalnego komputera, pomijając flagę --local.

Poza tym Fn wymaga podania adresu serwera Fn oraz rejestru Dockera. Te parametry mogą być ustawione przez zmienne środowiskowe FN_API_URL i FN_REGISTRY odpowiednio, ale zaproponowany jest też wygodniejszy sposób na proste zarządzanie tworzeniem i zarządzaniem konfiguracjami dla wdrożenia.

W terminologii Fn, konfiguracja dla wdrożenia nazywa się context. Następująca komenda stworzy kontekst:

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

Możesz wyświetlić dostępne konteksty w następujący sposób:

$ fn list contexts

AKTUALNA NAZWA      DOSTAWCA      URL API                      REJESTR
    default       default       http://localhost:8080/
    exoscale      default       http://185.19.30.175:8080    nfrankel

Aby przełączyć się na kontekst, który właśnie został utworzony, użyj następującej komendy:

 $ fn use context exoscale

 Teraz używany kontekst: exoscale

Od tego miejsca dostarczanie funkcji Fn zacznie ładować obrazy Docker, korzystając z wybranego konta na DockerHub (w moim przypadku — nfrankel), następnie powiadomi serwer zdalny (w tym przykładzie — http://185.19.30.175:8080) o lokalizacji i wersji ostatniego obrazu, zawierającego twoją funkcję.

$ fn deploy --app fnexo .   # wykonywane na lokalnej maszynie z katalogu hellonode

Wdrażanie funkcji z: /.
Wdrażanie hellonode do aplikacji: fnexo
Zaktualizowano do wersji 0.0.5
Budowanie obrazu nfrankel/hellonode:0.0.5 .

Na koniec:

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

{"message":"Hello World"}

Budujemy własny serverless oparty na Fn
Cykl życia funkcji w obliczeniach bezserwerowych opartych na Fn

Zalety obliczeń bezserwerowych na własnych zasobach

Obliczenia bezserwerowe to wygodne rozwiązanie do szybkiego wdrażania niezależnych części aplikacji, które współpracują z bardziej złożonymi aplikacjami lub mikroserwisami.

Często związane jest to z ukrytymi kosztami uzależnienia od wybranego dostawcy, co w zależności od konkretnego przypadku użycia i skali może prowadzić do wyższych wydatków i mniejszej elastyczności w przyszłości.

Architektury multi-cloud i hybrydowe również cierpią z tego powodu, ponieważ łatwo można znaleźć się w sytuacji, w której chciałoby się korzystać z obliczeń bezserwerowych, ale ze względu na politykę korporacyjną może to być niemożliwe.

Fn jest stosunkowo prosty w użyciu, może dać prawie taki sam interfejs FaaS przy minimalnych kosztach. Umożliwia uniknięcie jakichkolwiek uzależnień od dostawcy, można go zainstalować lokalnie lub u dowolnego wybranego dostawcy chmurowego. Istnieje również swoboda w wyborze języka programowania.

W artykule przedstawiono jedynie podstawy Fn, jednak stworzenie własnego środowiska wykonawczego jest wystarczająco proste, a ogólną architekturę można wdrożyć szerzej, korzystając z load balancera Fn lub umieszczając Fn za proxy w celu ochrony.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster