Създаваме собствен serverless на базата на Fn

Създаваме собствен serverless на базата на Fn

Безсървърни изчисления — една от най-забележителните тенденции в облачните изчисления. Основният принцип на работа е, че инфраструктурата е грижа не на DevOps, а на доставчика на услуги. Масштабът на ресурсите автоматично се регулира според натоварването и предлага висока скорост на изменение.

Друга обща черта е тенденцията към минимизиране и фокусиране на кода, поради което безсървърните изчисления понякога се наричат „функция като услуга“ (FaaS).

Исторически първият доставчик на облачни услуги, предложил FaaS с AWS Lambda, е Amazon, откъдето произлиза и названието. Други облачни доставчици също предлагат аналози:

  • Cloud Functions на Google
  • Azure Functions на Microsoft

Всички тези компании предоставят безсървърни изчисления, автоматично мащабиране и заплащане само за действително използвани ресурси, но в същото време привързват клиентите към собствения си собствен продукт. Въпреки това, съществуват безплатни алтернативи с отворен код за организиране на безсървърни изчисления. Струва си да се отбележи:

  • Платформата Apache OpenWhisk, разработвана в инкубатор на IBM,
  • Spring Cloud Functions, като част от доста богатата екосистема на Spring Framework, която също може да се използва като фасада на AWS Lambda, Azure Functions и OpenWhisk,
  • Проект Fn, поддържан от Oracle.

Всички те са напълно независими от облаците, тоест се инсталират в всяко облако, включително вашето собствено, публично или частно, и разбира се в Exoscale.

Как е структуриран проект Fn

Fn е напълно базиран на Docker и се състои от два основни компонента:

  • CLI програма, предназначена за управление на всички аспекти на инфраструктурата Fn, и взаимодействието с сървъра Fn,
  • Собствено сървърът Fn, обикновено приложение, опаковано в контейнер за Docker.

Функциите, разгръщани в Fn, също се изпълняват в отделни контейнери, което позволява поддържането на много езици за програмиране, например… Clojure!

Аргументите на функциите се подават на стандартен вход (STDIN), а резултатите се записват на стандартен изход (STDOUT). Ако аргументите или върнатите стойности не са прости стойности (например, JSON обект) — те могат да бъдат преобразувани с помощта на слой абстракция, предоставен от самия Fn под формата на комплект за разработка на функции (FDK).

За удобство се предлагат вградени комплекти шаблони, които улесняват разгръщането на FaaS на обширен списък от различни езици и техните версии (Go, различни версии на Java, Python и т.н.).

Създаването на FaaS е просто, следвайки тази схема:

  • Разгръщаме функцията с помощта на CLI Fn: създава се конфигурационен файл на приложението за Fn, базиран на избрания шаблон.
  • Качваме собствената функция, отново с помощта на CLI Fn: контейнерният образ се поставя в някакво хранилище, след което сървърът се уведомява за съществуването и местоположението на този образ.

Създаваме собствен serverless на базата на Fn
Принцип на доставка на функции в Fn

Локална инсталация и тестване на безсървърни функции

Започваме с инсталирането на Fn на локалната машина. Първо се инсталира Docker, както изисква Fn. Предполага се, че работим на Debian/Ubuntu:

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

Или използвайте пакетния мениджър/инсталацията на Docker съобразно вашата система. След това можете директно да преминете към инсталирането на Fn CLI. Например, с помощта на curl:

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

Ако работите на OSX с инсталиран Homebrew, можете да следвате друг път:

$ brew install fn

==> Изтегляне на https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Изтегляне от https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Преливане на fn-0.5.8.high_sierra.bottle.tar.gz
  /usr/local/Cellar/fn/0.5.8: 5 файла, 16.7MB

Сега всичко е готово за първоначално разгръщане на нашата функция с използване на CLI. За улеснение ще използваме вградената среда за изпълнение, например Node:

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

Създаване на функция на: /hellonode
Създаден е шаблон за функция.
func.yaml е създаден.

Ще бъде създадена нова директория hellonode за по-нататъшно разработване на нашата функция Fn с някои основни конфигурационни файлове. Вътре в новосъздадената директория можете да създадете вашето приложение, следващо стандартите на избрания от вас език или среда за изпълнение:

# Каталог с 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 създава началната структура на проекта, създава файл func.yaml, съдържащ необходимите настройки за Fn, и установява шаблон за кода на избрания от вас език.

В случая на средата за изпълнение Node това означава:

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

Сега бързо ще проверим нашата функция локално, за да видим как всичко работи.

Първо ще стартираме сървъра Fn. Както вече беше споменато, сървърът Fn представлява Docker контейнер, следователно, след стартиране, той ще вземе образа от Docker регистъра.

$ fn start -d                    # стартираме локалния сървър на заден план

Не може да се намери образът 'fnproject/fnserver:latest' локално
latest: Изтегляне от fnproject/fnserver
ff3a5c916c92: Изтеглянето завършено
1a649ea86bca: Изтеглянето завършено
ce35f4d5f86a: Изтеглянето завършено

...

Статус: Изтеглен нов образ за fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

За да стартираме нашата функция, трябва да я 'разгърнем'. За това е необходимо името на приложението: в Fn всички приложения трябва да бъдат зададени под формата на пространство от имена за свързани функции.

Fn СLI ще търси файл func.yaml в текущата директория, който ще бъде използван за конфигуриране на функцията. Така че първо трябва да преминем в нашата директория hellonode.

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

Разгърнат hellonode за приложение: fnexo
Повишена до версия 0.0.2
Създаване на образ nfrankel/hellonode:0.0.3 .
Актуализиране на функция hellonode с използване на образ nfrankel/hellonode:0.0.3...
Успешно създадено приложение: fnexo
Успешно създадена функция: hellonode с nfrankel/hellonode:0.0.3
Успешно създаден тригер: hellonode-trigger

Както може да се види от изхода на командата, се създава нов образ на контейнер за Docker, съдържащ нашата функция. Функцията е готова за извикване и имаме два начина да я направим:

  • използвайки командата Fn invoke
  • извиквайки я директно през http

Извикване invoke през Fn просто еймулира работата по HTTP за тестове, което е удобно за бърза проверка:

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

{"message":"Hello World"}

За да извикате функцията директно, трябва да знаете пълния URL:

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

{"message":"Hello World"}

Сървърът Fn предоставя своите функции през порт 8080 и, както изглежда, URL на функцията отговаря на схемата t/app/function, но не напълно. Чрез HTTP функцията не се извиква директно, а чрез т.нар. тригер, който според името си 'стартира' извикването на функцията. Триггерите се определят в `func.yml проекта:

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

Можем да променим името на тригера, за да съответства на името на функцията, което ще опрости нещата:

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

След това стартираме отново доставката на функцията и я извикваме от новия тригер:

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

{"message":"Здравей, свят!"}

Всичко работи! Време е да преминем към практически експерименти и да публикуваме нашето FaaS на сървъра!

Инсталиране на услуги за безсървърни функции на собствената инфраструктура

Нека бързо инсталираме виртуална машина, използвайки CLI Exoscale. Ако все още не сте я настроили - можете да се възползвате от нашето ръководство за бързо стартиране. Това е страхотен инструмент, който ще увеличи вашата продуктивност. Не забравяйте да настроите правило за отваряне на порт 8080 в Security Group! Следващите команди ще стартират чиста виртуална машина, готова за разполагане на нашите функции:

$ 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

След това можете да се свържете по ssh с виртуалната машина и да инсталирате отдалечения сървър Fn:

$ exo ssh fn-server

Автентичността на хоста '185.19.30.175 (185.19.30.175)' не може да бъде установена.
ECDSA ключовият отпечатък е SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Сигурни ли сте, че искате да продължите с връзката (да/не)? да
Предупреждение: Стойността '185.19.30.175' (ECDSA) е добавена постоянно в списъка на известните хостове.
Добре дошли в Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

След това инсталираме Docker и сървъра Fn по същия начин, както го направихме на локалната машина, и стартираме сървъра:

$ 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 е готов да получава функции! За целенасочена доставка на функции на отдалечения сървър, ще използваме командата deploy от локалния компютър, пропускайки флага --local.

Освен това, Fn изисква да посочите местоположението на сървъра Fn и Docker регистъра. Тези параметри могат да бъдат зададени чрез променливи на средата FN_API_URL и FN_REGISTRY съответно, но се предлага и по-удобен начин за лесно управление на създаването и управлението на конфигурации за разгръщане.

В терминологията на Fn конфигурацията за разгръщане се нарича context. Следващата команда ще създаде контекст:

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

Можете да прегледате наличните контексти така:

$ fn list contexts

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

А за да превключите на контекста, който току-що беше създаден, така:

 $ fn use context exoscale

Сега използваме контекста: exoscale

Започвайки от това място, доставката на функции Fn ще зарежда Docker образи, използвайки избраната регистрация в DockerHub (в моя случай — nfrankel), след което ще уведомява отдалечения сървър (в този пример — http://185.19.30.175:8080) за местоположението и версията на последния образ, съдържащ вашата функция.

$ fn deploy --app fnexo .   # изпълнява се на локалната машина от директорията hellonode

Разполагане на функция на: \/.
Разполагане на hellonode на приложение: fnexo
Увеличена версия 0.0.5
Създаване на образ nfrankel\/hellonode:0.0.5 .

Накрая:

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

{"message":"Hello World"}

Създаваме собствен serverless на базата на Fn
Жизнен цикъл на функцията в безсървърни изчисления, базирани на Fn

Предимства на безсървърните изчисления на вашите ресурси

Безсървърни изчисления са удобен начин за бързо внедряване на независими части от приложението, които взаимодействат с по-сложни приложения или микросервизи.

Често това е свързано с невидими разходи, свързани с избрания доставчик, което, в зависимост от конкретния случай на употреба и обема, може да доведе до по-високи разходи и намалена гъвкавост в бъдеще.

Многооблачните и хибридни облачни архитектури също страдат в такъв случай, тъй като лесно може да се окажете в ситуация, в която искате да използвате безсървърни изчисления, но поради корпоративната политика това може да бъде невъзможно.

Fn е достатъчно лесен за работа, може да предостави почти същия интерфейс FaaS, с минимални разходи. Той освобождава от всякакви обвързаности с доставчика и можете да го инсталирате локално или при всеки удобен за вас облачен доставчик. Има също така свобода в избора на програмния език.

В статията са представени само основите на Fn, но създаването на собствена среда за изпълнение е достатъчно просто, а цялостната архитектура може да бъде разширена с помощта на балансировач на натоварването Fn или като разположите Fn зад прокси за защита.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster