Budowanie własnego serwera bezserwerowego w oparciu o Fn

Budowanie własnego serwera bezserwerowego w oparciu o Fn

Przetwarzanie bezserwerowe to jeden z najważniejszych trendów w chmurze obliczeniowej. Podstawowa zasada działania jest taka, że ​​infrastruktura nie jest przedmiotem zainteresowania DevOps, ale dostawcy usług. Skalowanie zasobów automatycznie dostosowuje się do obciążenia i charakteryzuje się dużą szybkością zmian.

Inną wspólną cechą jest tendencja do minimalizowania i skupiania kodu, dlatego też przetwarzanie bezserwerowe jest czasami nazywane funkcją jako usługą (FaaS).

Historycznie rzecz biorąc, pierwszym dostawcą chmury oferującym FaaS z AWS Lambda był Amazon, stąd nazwa. Inni dostawcy usług w chmurze również oferują podobne:

  • Funkcje chmury od Google
  • Azure Functions od Microsoftu

Wszystkie te firmy zapewniają przetwarzanie bezserwerowe, automatyczne skalowanie i płacą tylko za to, z czego faktycznie korzystasz, ale blokują klientów w swoim zastrzeżonym produkcie. Istnieją jednak bezpłatne i otwarte alternatywy dla przetwarzania bezserwerowego. To jest nic nie warte:

  • platforma Apache OpenWhisk, opracowany w inkubatorze IBM,
  • Funkcje chmury wiosennej, w ramach dość bogatego ekosystemu Spring Framework, który może służyć również jako fasada dla AWS Lambda, Azure Functions i OpenWhisk,
  • Projekt Fn, wspierany przez Oracle.

Wszystkie są całkowicie niezależne od chmur, czyli można je zainstalować w dowolnej chmurze, także tej własnej, publicznej czy prywatnej i oczywiście w Exoscale.

Jak działa projekt Fn

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

  • Program CLI przeznaczony do zarządzania wszystkimi aspektami infrastruktury Fn i współdziałający z serwerem Fn,
  • Sam serwer Fn to zwykła aplikacja spakowana w kontenerze Docker.

Funkcje zaimplementowane 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 przekazywane są na standardowe wejście (STDIN), wyniki zapisywane są na standardowe wyjście (STDOUT). Jeśli argumenty lub zwracane wartości nie są wartościami prostymi (jak np. obiekt JSON), można je skonwertować za pomocą warstwy abstrakcji dostarczonej przez samo Fn w postaci zestawu Function Development Kit (FDK).

Dla wygody oferowane są wbudowane zestawy szablonów ułatwiające wdrożenie FaaS w obszernej liście różnych języków i ich wersji (Go, różne wersje Java, Python itp.).

Tworzenie FaaS jest łatwe, jeśli zastosujesz się do poniższego diagramu:

  • Wdrażanie funkcji za pomocą Fn CLI: na podstawie wybranego szablonu tworzony jest plik konfiguracyjny aplikacji dla Fn.
  • Wdrażamy własną funkcję, ponownie wykorzystując CLI Fn: obraz kontenera jest umieszczany w określonym repozytorium, po czym serwer jest powiadamiany o istnieniu i umieszczeniu tego obrazu.

Budowanie własnego serwera bezserwerowego w oparciu o Fn
Zasada dostarczania funkcji do Fn

Lokalna instalacja i testowanie funkcji bezserwerowych

Zacznijmy instalować Fn na komputerze lokalnym. Najpierw instalowany jest Docker, zgodnie z wymaganiami Fn. Zakładając, że korzystamy z Debiana/Ubuntu:

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

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

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

Jeśli korzystasz z systemu OSX z zainstalowanym Homebrew, możesz przejść w drugą stronę:

$ 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

Jesteśmy teraz gotowi do wstępnego wdrożenia naszej funkcji za pomocą interfejsu CLI. Dla uproszczenia użyjemy wbudowanego środowiska startowego, takiego jak Node:

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

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

Zostanie utworzony nowy katalog hellonode aby dalej rozwijać naszą funkcję Fn za pomocą kilku podstawowych plików konfiguracyjnych. W nowo utworzonym katalogu możesz stworzyć swoją aplikację zgodnie ze standardami wybranego języka lub środowiska wykonawczego:

# Каталог с 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 ustawienia dla Fn i ustawia szablon kodu w wybranym przez Ciebie języku.

W przypadku środowiska uruchomieniowego 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 wszystko działa.

Najpierw uruchomimy serwer Fn. Jak już wspomniano, serwer Fn jest kontenerem Dockera, dlatego po uruchomieniu pójdzie i pobierze obraz z rejestru Dockera.

$ 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

Aby nasza funkcja mogła działać, należy ją „wdrożyć”. To wymaga имя приложения: W Fn wszystkie aplikacje muszą być określone jako przestrzenie nazw dla powiązanych funkcji.

Fn CLI wyszuka plik func.yaml w bieżącym katalogu, który będzie używany do konfigurowania funkcji. Najpierw musisz przejść do naszego katalogu 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

Jak widać z wyniku polecenia, tworzony jest nowy obraz kontenera Docker zawierający naszą funkcję. Funkcja jest gotowa do wywołania i mamy na to dwa sposoby:

  • za pomocą polecenia Fn invoke
  • dzwoniąc bezpośrednio przez http

Zadzwoń invoke przez Fn po prostu emuluje pracę przez HTTP do testów, co jest wygodne do szybkiego testowania:

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

{"message":"Hello World"}

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

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

{"message":"Hello World"}

Serwer Fn udostępnia swoje funkcje na porcie 8080, a adres URL funkcji wydaje się pasować do wzorca t/app/function, ale nie całkowicie. Poprzez HTTP funkcja nie jest wywoływana bezpośrednio, lecz poprzez tzw. wyzwalacz, który zgodnie ze swoją nazwą „uruchamia” wywołanie funkcji. Wyzwalacze są zdefiniowane w `func.yml projekt:

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

Możemy zmienić nazwę wyzwalacza, aby pasowała do nazwy funkcji, to wszystko uprości:

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

Następnie ponownie uruchamiamy dostarczanie funkcji 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 eksperymentów na pełną skalę i opublikować nasz FaaS na serwerze!

Instalowanie usług funkcji bezserwerowych na własnej infrastrukturze

Zainstalujmy szybko maszynę wirtualną za pomocą interfejsu CLI Exoscale. Jeśli jeszcze tego nie skonfigurowałeś, możesz użyć nasz przewodnik szybkiego startu. To fajne narzędzie, które jeszcze bardziej zwiększy Twoją produktywność. Nie zapomnij, że musisz skonfigurować regułę otwierającą port 8080 w grupie zabezpieczeń! 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żesz połączyć się przez ssh z maszyną wirtualną i zainstalować zdalny 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 zainstaluj Dockera i serwer Fn w taki sam sposób, jak zostało to już zrobione na komputerze lokalnym, uruchom 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 ukierunkowanego przeniesienia funkcji na zdalny serwer użyjemy polecenia deploy z komputera lokalnego, pomijając flagę --local.

Ponadto Fn wymaga określenia lokalizacji serwera Fn i rejestru Docker. Opcje te można ustawić za pomocą zmiennych środowiskowych FN_API_URL и FN_REGISTRY odpowiednio, ale oferuje także wygodniejszy sposób łatwego zarządzania tworzeniem i zarządzaniem konfiguracjami do wdrożenia.

W terminologii Fn nazywana jest konfiguracja do wdrożenia context. Następujące polecenie utworzy kontekst:

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

Dostępne konteksty możesz przeglądać w następujący sposób:

$ fn list contexts

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

I przejdź do kontekstu, który właśnie został utworzony w ten sposób:

 $ fn use context exoscale

 Now using context: exoscale

Odtąd funkcja Fn będzie pobierać obrazy Dockera przy użyciu wybranego konta DockerHub (w moim przypadku - nfrankel), a następnie powiadom zdalny serwer (w tym przykładzie - http://185.19.30.175:8080) o lokalizacji i wersji najnowszego obrazu zawierającego Twoją funkcję.

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

Wreszcie:

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

{"message":"Hello World"}

Budowanie własnego serwera bezserwerowego w oparciu o Fn
Cykl życia funkcji w obliczeniach bezserwerowych opartych na technologii Fn

Zalety przetwarzania bezserwerowego we własnym zakresie

Przetwarzanie bezserwerowe to wygodne rozwiązanie umożliwiające szybkie wdrażanie niezależnych części aplikacji, które współdziałają z bardziej złożonymi aplikacjami lub mikrousługami.

Często wynika to z ukrytych kosztów związanych z wybranym dostawcą, co w zależności od konkretnego przypadku użycia i wolumenu może prowadzić do wyższych kosztów i mniejszej elastyczności w przyszłości.

Architektury multi-cloud i chmury hybrydowe również ucierpią na tym przypadku, ponieważ łatwo można znaleźć się w sytuacji, w której chciałbyś korzystać z przetwarzania bezserwerowego, ale ze względu na politykę korporacyjną może to nie być możliwe.

Fn jest dość łatwy w użyciu i może zapewnić prawie taki sam interfejs FaaS, przy niewielkim obciążeniu. Eliminuje zależność od dostawcy i można ją zainstalować lokalnie lub u dowolnego wybranego dostawcy rozwiązań chmurowych. Istnieje także dowolność w wyborze języka programowania.

W tym artykule omówiono tylko podstawy Fn, ale utworzenie własnego środowiska wykonawczego jest dość proste, a ogólną architekturę można wdrożyć szerzej za pomocą modułu równoważenia obciążenia Fn lub umieszczając Fn za serwerem proxy w celu ochrony.

Źródło: www.habr.com

Dodaj komentarz