Изграждане на наш собствен сървър без сървър, базиран на Fn

Изграждане на наш собствен сървър без сървър, базиран на Fn

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

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

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

  • Облачни функции от Google
  • Azure Functions от Microsoft

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

  • Платформа Apache OpenWhisk, разработен в инкубатор от IBM,
  • Пролетни облачни функции, като част от доста богата екосистема на 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 е лесно, като следвате тази диаграма:

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

Изграждане на наш собствен сървър без сървър, базиран на 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

==> 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

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

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

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

Ще бъде създадена нова директория 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 runtime това означава:

$ 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                    # запускаем локальный сервер в фоне

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

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

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

Както можете да видите от изхода на командата, е създадено ново изображение на 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":"Hello World"}

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

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

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

$ 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

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)

След това инсталирайте 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

 Now using context: exoscale

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

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

Накрая:

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

{"message":"Hello World"}

Изграждане на наш собствен сървър без сървър, базиран на Fn
Жизнен цикъл на функцията в изчисления без сървър, базирани на Fn

Предимства на безсървърно изчисление с вашия собствен капацитет

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

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

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

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

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

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

Добавяне на нов коментар