Construindo nosso próprio serverless baseado no Fn

Construindo nosso próprio serverless baseado no Fn

Computação sem servidor — é uma das tendências mais notáveis na computação em nuvem. O princípio básico é que a infraestrutura é responsabilidade do provedor de serviços, não dos DevOps. O dimensionamento dos recursos se ajusta automaticamente à carga e possui alta velocidade de alteração.

Outra característica comum é a tendência de minimizar e focar o código, pelo que a computação sem servidor é às vezes chamada de "função como serviço" (FaaS).

Historicamente, o primeiro provedor de serviços em nuvem a oferecer FaaS com o AWS Lambda foi a Amazon, de onde vem esse nome. Outros provedores de serviços em nuvem também oferecem análogos:

  • Cloud Functions da Google
  • Azure Functions da Microsoft

Todas essas empresas oferecem computação sem servidor, escalonamento automático e pagamento apenas pelos recursos realmente utilizados, mas, ao mesmo tempo, vinculam os clientes ao seu produto proprietário. No entanto, existem alternativas gratuitas de código aberto para organizar computação sem servidor. Vale a pena notar:

  • A plataforma Apache OpenWhisk, desenvolvida no incubador pela IBM,
  • Spring Cloud Functions, como parte de um ecossistema bastante rico do Spring Framework, que também pode ser usado como fachada para AWS Lambda, Azure Functions e OpenWhisk,
  • O projeto Fn, apoiado pela Oracle.

Todos eles são totalmente independentes de nuvens, ou seja, podem ser instalados em qualquer nuvem, incluindo a sua própria, pública ou privada, e claro, na Exoscale.

Como o projeto Fn é estruturado

O Fn é totalmente baseado em Docker, consistindo em dois componentes principais:

  • Uma interface de linha de comando (CLI) destinada a gerenciar todos os aspectos da infraestrutura do Fn e a interagir com o servidor Fn,
  • O próprio servidor Fn, um aplicativo comum empacotado em um contêiner Docker.

As funções implantadas no Fn também são executadas em contêineres separados, permitindo o suporte a muitas linguagens de programação, como… Clojure!

Os argumentos das funções são passados para a entrada padrão (STDIN), e os resultados são escritos na saída padrão (STDOUT). Se os argumentos ou valores retornados não forem valores simples (por exemplo, um objeto JSON), eles podem ser convertidos usando a camada de abstração fornecida pelo próprio Fn na forma de um kit de desenvolvimento de funções (FDK).

Para conveniência, são oferecidos conjuntos de templates incorporados que facilitam a implementação de FaaS em uma ampla lista de diferentes linguagens e suas versões (Go, diferentes versões do Java, Python, etc.).

Criar FaaS é simples, seguindo este esquema:

  • Implementamos a função usando o CLI Fn: um arquivo de configuração do aplicativo para o Fn é criado com base no template escolhido.
  • Implantamos nossa própria função, novamente usando o CLI Fn: a imagem do contêiner é colocada em um repositório, após o que o servidor é notificado sobre a existência e localização dessa imagem.

Construindo nosso próprio serverless baseado no Fn
Princípio de fornecimento de funções no Fn

Instalação e teste local de funções serverless

Vamos começar a instalar o Fn na máquina local. Primeiro, instalamos o Docker, como exigido pelo Fn. Assume-se que estamos no Debian/Ubuntu:

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

Ou use o gerenciador de pacotes/construção do Docker de acordo com seu sistema. Em seguida, podemos prosseguir diretamente para a instalação do Fn CLI. Por exemplo, usando curl:

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

Se você estiver no OSX com o Homebrew instalado, pode seguir por outro caminho:

$ 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

Agora tudo está pronto para a implantação inicial de nossa função usando o CLI. Para simplificar, usaremos um ambiente incorporado de execução, como o Node:

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

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

Um novo diretório será criado hellonode para o contínuo desenvolvimento de nossa função Fn com alguns arquivos de configuração básicos. Dentro do diretório recém-criado, você pode criar seu aplicativo, seguindo os padrões da linguagem ou ambiente de execução que você escolheu:

# Каталог с 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

O Fn cria a estrutura inicial do projeto, cria o arquivo func.yaml, contendo as configurações necessárias para o Fn, e estabelece o template para o código na linguagem que você escolheu.

No caso do ambiente de execução Node, isso significa:

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

Agora vamos rapidamente testar nossa função localmente para ver como tudo funciona.

Primeiro, vamos iniciar o servidor Fn. Como já mencionado, o servidor Fn é um container Docker, portanto, após o início, ele irá buscar a imagem no registro Docker.

$ fn start -d                    # iniciamos o servidor local em segundo plano

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

Para implantar nossa função, precisamos 'implantá-la'. Para isso, é necessário o nome do aplicativo: no Fn, todos os aplicativos devem ser especificados como namespaces para funções relacionadas.

O Fn CLI procurará um arquivo func.yaml no diretório atual, que será utilizado para configurar a função. Então, primeiro, precisamos navegar até nosso diretório hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # implantamos a função localmente, o nome do aplicativo é fnexo.
                                 # o parâmetro local não envia a imagem para o registro remoto,
                                 # rodando-a diretamente

Implantando hellonode no app: fnexo
Versão 0.0.2 aumentada
Construindo imagem nfrankel/hellonode:0.0.3 .
Atualizando a função hellonode usando a imagem nfrankel/hellonode:0.0.3...
Aplicativo criado com sucesso:  fnexo
Função criada com sucesso: hellonode com nfrankel/hellonode:0.0.3
Gatilho criado com sucesso: hellonode-trigger

Como pode ser visto na saída do comando, uma nova imagem de container para Docker está sendo criada, contendo nossa função. A função está pronta para ser chamada, e temos duas maneiras de fazer isso:

  • usando o comando Fn invoke
  • chamando diretamente através de http

Chamada invoke pelo Fn apenas emula a operação via HTTP para testes, o que é conveniente para uma verificação rápida:

$ fn invoke fnexo hellonode      # chamamos a função hellonode do aplicativo fnexo

{"message":"Hello World"}

Para chamar a função diretamente, é necessário conhecer a URL completa:

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

{"message":"Hello World"}

O servidor Fn oferece suas funções através da porta 8080, e, aparentemente, a URL da função corresponde ao esquema t/app/function, mas não completamente. A função é chamada não diretamente via HTTP, mas através do que é conhecido como trigger, que, conforme seu nome, 'dispara' a chamada da função. Os triggers são definidos em `func.yml do projeto:

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 do gatilho

Podemos mudar o nome do gatilho para que corresponda ao nome da função, isso irá simplificar tudo:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # corresponde ao nome da função

Em seguida, iniciamos a entrega da função novamente e a chamamos do novo gatilho:

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

{"message":"Olá Mundo"}

Tudo está funcionando! É hora de passar para experimentos reais e publicar nosso FaaS no servidor!

Instalação de serviços de funções sem servidor em infraestrutura própria

Vamos rapidamente instalar uma máquina virtual usando o CLI Exoscale. Se você ainda não a configurou, pode usar nosso guia para uma configuração rápida. É uma ferramenta incrível que aumentará ainda mais a sua produtividade. Não se esqueça de configurar uma regra para abrir a porta 8080 no Grupo de Segurança! Os seguintes comandos vão iniciar uma máquina virtual limpa, pronta para hospedar nossas funções:

$ 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

Em seguida, você pode acessar a máquina virtual via ssh e instalar o servidor remoto Fn:

$ exo ssh fn-server

A autenticidade do host '185.19.30.175 (185.19.30.175)' não pode ser estabelecida.
A impressão digital da chave ECDSA é SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Tem certeza de que deseja continuar conectando (sim/não)? sim
Aviso: Adicionado permanentemente '185.19.30.175' (ECDSA) à lista de hosts conhecidos.
Bem-vindo ao Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

Em seguida, instalamos o Docker e o servidor Fn da mesma forma que já foi feito na máquina local, iniciamos o servidor:

$ 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 está pronto para receber funções! Para o envio de funções para o servidor remoto, vamos usar o comando deploy do computador local, omitindo a flag --local.

Além disso, o Fn requer que você especifique o local do servidor Fn e do registro Docker. Esses parâmetros podem ser definidos através das variáveis de ambiente FN_API_URL e FN_REGISTRY respectivamente, mas também é oferecido um método mais conveniente para fácil gerenciamento de criação e gestão de configurações para implantação.

Em termos de Fn, a configuração para a implantação é chamada contexto. O seguinte comando criará um contexto:

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

Você pode visualizar os contextos disponíveis assim:

$ fn list contexts

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

E mudar para o contexto que foi criado recentemente assim:

 $ fn use context exoscale

 Agora usando o contexto: exoscale

A partir deste ponto, a entrega das funções Fn começará a carregar as imagens Docker usando a conta selecionada no DockerHub (no meu caso — nfrankel), e logo notificará o servidor remoto (neste exemplo — http://185.19.30.175:8080) sobre a localização e a versão da última imagem que contém sua função.

$ fn deploy --app fnexo .   # executado na máquina local a partir do diretório hellonode

Implantando função em: 
Implantando hellonode no aplicativo: fnexo
Atualizado para versão 0.0.5
Construindo imagem nfrankel/hellonode:0.0.5 .

Finalmente:

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

{"message":"Hello World"}

Construindo nosso próprio serverless baseado no Fn
Ciclo de vida da função em computação serverless baseadas em Fn

Vantagens da computação serverless em suas próprias instalações

A computação serverless é uma solução conveniente para a rápida implementação de partes independentes de um aplicativo que interagem com aplicativos mais complexos ou microserviços.

Isso muitas vezes está associado ao custo oculto de estar vinculado ao fornecedor escolhido, o que, dependendo do caso de uso específico e do volume, pode resultar em custos mais altos e menor flexibilidade no futuro.

Arquiteturas multicloud e híbridas também sofrem neste caso, pois é fácil se encontrar em uma situação onde se deseja usar computação serverless, mas devido à política corporativa isso pode ser impossível.

O Fn é bastante fácil de usar, pode fornecer quase a mesma interface FaaS, com poucos custos. Ele elimina quaisquer amarras ao fornecedor, podendo ser instalado localmente ou em qualquer fornecedor de soluções de nuvem de sua escolha. Também há liberdade na escolha da linguagem de programação.

Este artigo apresenta apenas os fundamentos do Fn, mas criar seu próprio ambiente de execução é bastante simples, e a arquitetura geral pode ser expandida mais usando um balanceador de carga Fn, ou colocando o Fn atrás de um proxy para proteção.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster