Tutorial

Como executar funções sem servidor usando o OpenFaaS no Kubernetes da DigitalOcean

Open SourceKubernetesDigitalOcean Managed Kubernetes

O autor selecionou o Free and Open Source Fund para receber uma doação como parte do programa Write for DOnations.

Introdução

Normalmente, a hospedagem de um aplicativo de software na Internet exige gerenciamento, planejamento e monitoramento de infraestrutura para um sistema monolítico. Ao contrário desta abordagem tradicional, a arquitetura sem servidor (também conhecida como função como um serviço, ou FaaS) divide seu aplicativo em funções. Estas funções são entidades sem estado, independentes, acionadas por evento e completamente funcionais, que se comunicam através das APIs que você gerencia, como alternativa ao provisionamento do hardware subjacente e da infraestrutura explícita. As funções são escalonáveis por padrão, portáteis, possuem configuração mais rápida e são mais fáceis de testar do que os aplicativos comuns. Para que a arquitetura sem servidor funcione em princípio, ela exige um método de empacotamento e orquestração de funções independente da plataforma.

O OpenFaaS é um framework de código aberto criado para implementar a arquitetura sem servidor no Kubernetes, usando contêineres do Docker para armazenar e executar funções. Ele permite que qualquer programa seja empacotado como um contêiner e gerenciado como uma função, por meio da linha de comando ou da IU da Web integrada. O OpenFaaS tem um excelente suporte para métricas e fornece um redimensionamento automático de funções quando a demanda aumenta.

Neste tutorial, você implantará o OpenFaaS ao cluster do Kubernetes da DigitalOcean em seu domínio e o protegerá usando certificados gratuitos do Let’s Encrypt. Você também explorará a IU da Web e implantará funções existentes e novas usando a faas-cli, a ferramenta oficial de linha de comando. No final, você terá um sistema flexível para a implantação de funções sem servidor em funcionamento.

Pré-requisitos

  • Um cluster do Kubernetes da DigitalOcean com sua conexão configurada como o kubectl padrão. O cluster deve ter pelo menos 8GB de RAM e 4 núcleos de CPU disponíveis para o OpenFaaS (em caso de uso intenso, serão necessários mais núcleos). As instruções sobre como configurar o kubectl são mostradas no passo Conexão com seu cluster, quando você criar seu cluster. Para criar um cluster do Kubernetes no DigitalOcean, consulte o tópico sobre Início rápido do Kubernetes.
  • O Docker instalado em sua máquina local. Siga os passos 1 e 2 para sua distribuição (consulte Como instalar o Docker).
  • Uma conta do Docker Hub para armazenar as imagens do Docker que você criará neste tutorial.
  • O faas-cli, a ferramenta oficial de CLI para o gerenciamento do OpenFaaS, instalada em sua máquina local. Para maiores instruções para multiplataformas, visite os documentos oficiais.
  • O gerenciador de pacotes Helm instalado em sua máquina local. Para fazer isso, termine o Passo 1 e adicione o repositório stable do Passo 2 do tutorial Como instalar softwares nos clusters do Kubernetes com o gerenciador de pacotes Helm 3.
  • O Nginx Ingress Controller e o Cert-Manager instalados em seu cluster usando o Helm para expor o OpenFaaS utilizando os recursos do Ingress. Caso precise de orientações, siga o tutorial Como configurar um Nginx Ingress no Kubernetes da DigitalOcean usando o Helm.
  • Um nome de domínio totalmente registrado para hospedar o OpenFaaS apontado para o balanceador de carga utilizado pelo Nginx Ingress. Este tutorial utilizará o openfaas.your_domain durante todo o processo. Você pode comprar um nome de domínio em Namecheap, obter um gratuitamente em Freenom ou usar o registrador de domínios de sua escolha.

Nota: o nome de domínio que você vai usar aqui deve ser diferente do nome de domínio usado no tutorial “Como configurar um Nginx Ingress no Kubernetes da DigitalOcean”, que é um pré-requisito deste tutorial.

Passo 1 — Instalando o OpenFaaS usando o Helm

Neste passo, você instalará o OpenFaaS em seu cluster do Kubernetes usando o Helm e o exporá em seu domínio.

Como parte dos pré-requisitos do Nginx Ingress Controller, você criou exemplos de serviços e um Ingress. Você não precisará deles neste tutorial. Assim, você pode excluí-los executando os comandos a seguir:

  • kubectl delete -f hello-kubernetes-first.yaml
  • kubectl delete -f hello-kubernetes-second.yaml
  • kubectl delete -f hello-kubernetes-ingress.yaml

Como você implantará funções como objetos do Kubernetes, será útil armazenar tanto as funções quanto o próprio OpenFaaS em namespaces separados em seu cluster. O namespace do OpenFaaS será chamado de openfaas, e o namespace das funções será openfaas-fn. Crie-os em seu cluster executando o seguinte comando:

  • kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

Você verá o seguinte resultado:

Output
namespace/openfaas created namespace/openfaas-fn created

Em seguida, adicione o repositório Helm do OpenFaaS. Ele que hospedará o chart do OpenFaaS. Para fazer isso, execute o seguinte comando:

  • helm repo add openfaas https://openfaas.github.io/faas-netes/

O Helm exibirá o seguinte resultado:

Output
"openfaas" has been added to your repositories

Recarregue o cache do chart do Helm:

  • helm repo update

Você verá o seguinte resultado:

Output
Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "openfaas" chart repository ...Successfully got an update from the "jetstack" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈

Antes de instalar o OpenFaaS, será necessário personalizar alguns parâmetros do chart. Você os armazenará em sua máquina local, em um arquivo chamado values.yaml. Crie e abra o arquivo com seu editor de texto:

  • nano values.yaml

Adicione as linhas a seguir:

values.yaml
functionNamespace: openfaas-fn
generateBasicAuth: true

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "nginx"
  hosts:
    - host: openfaas.your_domain
      serviceName: gateway
      servicePort: 8080
      path: /

Primeiro, especifique o namespace onde as funções serão armazenadas atribuindo openfaas-fn à variável functionNamespace. Ao configurar o generateBasicAuth para true, você ordena que o Helm configure a autenticação obrigatória ao acessar a IU da Web do OpenFaaS, e gere uma combinação de nome de usuário e senha do administrador para você.

Em seguida, habilite a criação do Ingress e configure-o para utilizar o Nginx Ingress Controller e auxiliar o serviço do gateway OpenFaaS em seu domínio.

Lembre-se de substituir o openfaas.your_domain pelo seu domínio desejado nos pré-requisitos. Quando terminar, salve e feche o arquivo.

Por fim, instale o OpenFaaS no namespace openfaas com os valores personalizados:

  • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

Você verá o seguinte resultado:

Output
Release "openfaas" does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

A saída mostra que a instalação foi bem-sucedida. Execute o comando a seguir para revelar a senha para a conta admin:

  • echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode) | tee openfaas-password.txt

A senha decodificada é registrada simultaneamente na saída e em um arquivo chamado openfaas-password.txt, usando o tee. Anote a senha encontrada na saída. Está é a senha do OpenFaaS para a conta admin.

Você pode observar o processo de disponibilização dos contêineres do OpenFaaS executando o seguinte comando:

  • kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"

Quando todas as implantações listadas estiverem ready, pressione CTRL + C para sair.

Acesse o domínio especificado em seu navegador Web. Quando solicitado, insira o nome de usuário admin e sua respectiva senha. Você verá a IU da Web do OpenFaaS:

OpenFaaS - Painel de controle vazio

Você instalou o OpenFaaS e expôs seu painel de controle em seu domínio com êxito. Em seguida, você o protegerá usando certificados TLS gratuitos do Let’s Encrypt.

Passo 2 — Habilitando o TLS para seu domínio

Neste passo você protegerá seu domínio exposto usando certificados do Let’s Encrypt, fornecidos pelo gerenciador de certificados.

Para fazer isso, será necessário editar a configuração do Ingress em values.yaml. Abra o Caddyfile​​​ para edição:

  • nano values.yaml

Adicione as linhas destacadas a seguir:

values.yaml
generateBasicAuth: true

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: letsencrypt-prod
  tls:
    - hosts:
        - openfaas.your_domain
      secretName: openfaas-crt
  hosts:
    - host: openfaas.your_domain
      serviceName: gateway
      servicePort: 8080
      path: /

O bloco tls define em qual segredo os certificados para seus sites (listados em hosts) serão armazenados após sua emissão pelo ClusterIssuer do letsencrypt-prod. Geralmente, o segredo especificado deve ser diferente para cada Ingress em seu cluster.

Lembre-se de substituir o openfaas.your_domain pelo seu domínio desejado e, depois, salve e feche o arquivo.

Aplique as alterações no seu cluster executando o seguinte comando:

  • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

Você verá o seguinte resultado:

Output
Release "openfaas" has been upgraded. Happy Helming! NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 2 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

Espere alguns minutos para os servidores do Let’s Encrypt emitirem um certificado para seu domínio. Enquanto isso, você pode acompanhar o progresso inspecionando a saída do seguinte comando:

  • kubectl describe certificate openfaas-crt -n openfaas

O final da saída se parecerá com isso:

Output
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 24m cert-manager Generated a new private key Normal Requested 16m cert-manager Created new CertificateRequest resource "openfaas-crt-1017759607" Normal Issued 16m cert-manager Certificate issued successfully

Quando a última linha da saída disser Certificate issued successfully​​​, saia pressionando CTRL + C. Atualize seu domínio em no navegador para testá-lo. Você verá um cadeado ao lado esquerdo da barra de endereço no seu navegador, indicando que a conexão está segura.

Você protegeu seu domínio do OpenFaaS usando certificados TLS gratuitos do Let’s Encrypt. Agora você usará a IU da Web e gerenciará funções a partir dela.

Passo 3 — Implantando funções através da IU da Web

Nesta seção você explorará a IU da Web do OpenFaaS e implantará, gerenciará e invocará funções a partir dela.

A IU da Web do OpenFaaS tem duas partes principais: no lado esquerdo, uma coluna onde estão listadas as funções implantadas, e o painel central, onde você verá informações detalhadas sobre uma função selecionada e poderá interagir com ela.

Para implantar uma nova função, clique no botão Implantar nova função abaixo do logo do OpenFaaS, no canto superior esquerdo. Você verá uma diálogo pedindo que escolha uma função:

OpenFaaS - Diálogo Implantar uma nova função

A guia FROM STORE lista as funções pré-disponibilizadas da loja oficial de funções do OpenFaaS que você pode implantar imediatamente. Cada função é mostrada com uma breve descrição dela, e você pode selecionar o ícone do link à direita de uma função para dar uma olhada em seu código-fonte. Para implantar uma função da loja desta lista, selecione-a e clique no botão DEPLOY.

Você também pode fornecer suas próprias funções alternando para a guia CUSTOM:

OpenFaaS - Implantar uma função personalizada

Aqui, será necessário especificar uma imagem do Docker de sua função, que está configurada especificamente para o OpenFaaS e disponível em um registro do Docker (como o Docker Hub). Neste passo, você implantará um função pré-disponibilizada da loja do OpenFaaS. Em seguida, nos próximos passos, você criará e implantará funções personalizadas para o Docker Hub.

Você implantará a função NodeInfo, que retorna informações sobre a máquina em que ela está implantada, como a arquitetura da CPU, o número de núcleos, o total de memória RAM disponível e o tempo de atividade (em segundos).

Na lista de funções da loja, selecione NodeInfo e clique em DEPLOY. Em instantes, ela aparecerá na lista de funções implantadas.

OpenFaaS - NodeInfo implantada

Selecione-a. Na parte central da tela, você verá informações básicas sobre a função implantada.

OpenFaaS - Informações da função implantada

O status da função é atualizado em tempo real e deve rapidamente mudar para Ready. Se o status permanecer como Not Ready por tempo demais, é provável que seu cluster não possua os recursos necessários para aceitar um novo pod. Siga os passos de Como redimensionar os Droplets para obter maiores informações sobre como corrigir este problema.

Assim que tiver o status Ready, a função implantada estará acessível na URL exibida. Para testar a função, acesse-a por meio da URL em seu navegador, ou chame-a no painel Invoke function, localizada abaixo das informações da função.

OpenFaaS - Invocar função implantada

Selecione entre Texto, JSON e Download para indicar o tipo de resposta que você quer. Se quiser que a solicitação seja um POST em vez de GET, forneça os dados dela no campo Corpo da solicitação.

Para chamar a função nodeinfo, clique no botão INVOKE. O OpenFaaS desenvolverá e executará uma solicitação em HTTP de acordo com as opções selecionadas e preencherá os campos com os dados recebidos.

OpenFaaS - Resposta da função nodeinfo

O status da resposta é HTTP 200 OK, o que significa que a solicitação foi executada com sucesso. O corpo da resposta contém as informações do sistema que o NodeInfo reúne, o que significa que ele está devidamente acessível e funcionando corretamente.

Para excluir uma função, selecione-a da lista e clique no ícone de lixo no canto superior direito da página. Quando solicitado, clique em OK para confirmar. O status da função se tornará Not Ready (o que significa que ele está sendo removido do cluster) e a função desaparecerá em breve da IU.

Neste passo, você utilizou a IU da Web OpenFaaS, além de implantar e gerenciar funções a partir dela. Agora você verá como implantar e gerenciar funções OpenFaas usando a linha de comando.

Passo 4 — Gerenciando funções usando o faas-cli

Nesta seção, você configurará o faas-cli para trabalhar com seu cluster. Em seguida, você implantará e gerenciará suas funções existentes por meio da linha de comando.

Para não precisar especificar seu domínio OpenFaaS sempre que for executar o faas-cli, armazene-o em uma variável de ambiente chamada OPENFAAS_URL. O faas-cli pegará o valor dessa variável e o utilizará durante sua execução.

Abra o .bash_profile em seu diretório base para edição:

  • nano ~/.bash_profile

Adicione a linha a seguir:

~/.bash_profile
. . .
export OPENFAAS_URL=https://openfaas.your_domain

Lembre-se de substituir o openfaas.your_domain pelo seu domínio e, depois, salve e feche o arquivo.

Para evitar fazer o login novamente, avalie manualmente o arquivo:

  • . ~/.bash_profile

Agora, confira se o faas-cli está instalado em sua máquina local. Se ainda não o tiver instalado, faça isso seguindo as instruções descritas nos documentos oficiais.

Depois, defina suas credenciais de login executando o seguinte comando:

  • cat ~/openfaas-password.txt | faas-cli login --username admin --password-stdin

O resultado se parecerá com o seguinte:

Output
Calling the OpenFaaS server to validate the credentials... credentials saved for admin https://openfaas.your_domain

Para implantar uma função da loja, execute o seguinte comando:

  • faas store deploy function_name

Tente implantar o nodeinfo executando:

  • faas store deploy nodeinfo

Você verá uma saída como a seguinte:

Output
Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/nodeinfo

Para listar as funções implantadas, execute faas list:

  • faas list

Suas funções existentes serão exibidas:

Output
Function Invocations Replicas nodeinfo 0 1

Para obter informações detalhadas sobre uma função implantada, utilize faas describe:

  • faas describe nodeinfo

Sua saída será parecida com esta:

Name:                nodeinfo
Status:              Ready
Replicas:            1
Available replicas:  1
Invocations:         0
Image:               functions/nodeinfo-http:latest
Function process:
URL:                 https://openfaas.your_domain/function/nodeinfo
Async URL:           https://openfaas.your_domain/async-function/nodeinfo
Labels:              faas_function : nodeinfo
                     uid : 514253614
Annotations:         prometheus.io.scrape : false

Invoque uma função com o faas invoke:

  • faas invoke nodeinfo

Você receberá a seguinte mensagem:

Output
Reading from STDIN - hit (Control + D) to stop.

Em seguida, forneça um corpo de solicitação. Se fizer isso, o método será o POST em vez de GET. Quando terminar de inserir os dados, ou desejar que a solicitação seja GET, pressione CTRL + D. O faas-cli executará a solicitação inferida e retornará a resposta, da mesma maneira que a IU da Web.

Para excluir uma função, execute faas remove:

  • faas remove nodeinfo

Você receberá a seguinte saída:

Output
Deleting: nodeinfo. Removing old function.

Execute faas list novamente para ver que o nodeinfo foi removido:

Output
Function Invocations Replicas

Neste passo, você implantou, listou, invocou e removeu funções em seu cluster por meio da linha de comando usando o faas-cli. No próximo passo, você criará sua própria função e a implantará em seu cluster.

Passo 5 — Criando e implantando uma nova função

Agora você criará uma função de exemplo chamada Node.JS usando o faas-cli e a implantará em seu cluster.

A função que você criar será empacotada como um contêiner do Docker e publicada no Docker Hub. Para conseguir publicar contêineres, você precisará fazer login executando o seguinte comando:

  • docker login

Para finalizar o processo de login, digite seu nome de usuário e senha quando solicitado.

Você armazenará a função exemplo Node.JS em uma pasta chamada sample-js-function. Crie-a usando o seguinte comando:

  • mkdir sample-js-function

Navegue até ele:

  • cd sample-js-function

Preencha o diretório com o modelo de uma função JS executando o comando que segue:

  • faas new sample-js --lang node

O resultado ficará parecido com este:

Output
2020/03/24 17:06:08 No templates found in current directory. 2020/03/24 17:06:08 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/24 17:06:10 Fetched 19 template(s) : [csharp csharp-armhf dockerfile go go-armhf java11 java11-vert -x java8 node node-arm64 node-armhf node12 php7 python python-armhf python3 python3-armhf python3-debian ru by] from https://github.com/openfaas/templates.git Folder: sample-js created. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Function created in folder: sample-js Stack file written: sample-js.yml ...

Como escrito na saída, o código para a função em si está localizado na pasta sample-js, enquanto a configuração OpenFaaS para a função está no arquivo sample-js.yaml. No diretório sample-js (que se parece com um projeto Node.JS normal) há dois arquivos, o handler.js e o package.json.

O handler.js contém o código JS real que retornará uma resposta quando a função for chamada. O conteúdo do handler se parece com o seguinte:

sample-js-function/sample-js/handler.js
"use strict"

module.exports = async (context, callback) => {
    return {status: "done"}
}

Ele exporta uma função lambda com dois parâmetros, um context com dados de solicitação e um callback, que você pode usar para devolver os dados da resposta à função em vez de apenas retornar a resposta.

Abra este arquivo para edição:

  • nano sample-js/handler.js

Altere a linha destacada da seguinte forma:

sample-js-function/sample-js/handler.js
"use strict"

module.exports = async (context, callback) => {
    return {status: "<h1>Hello Sammy!</h1>"}
}

Quando terminar, salve e feche o arquivo. Quando chamada, esta função OpenFaaS escreverá Hello Sammy! como resposta.

Em seguida, abra o arquivo de configuração para edição:

  • nano sample-js.yml

Ele se parecerá com o seguinte:

sample-js-function/sample-js.yml
version: 1.0
provider:
  name: openfaas
  gateway: https://openfaas.your_domain
functions:
  sample-js:
    lang: node
    handler: ./sample-js
    image: sample-js:latest

Para o provider, ele especifica o openfaas e um gateway padrão. Depois, ele define a função sample-js, especifica a linguagem (node), o manipulador e o nome da imagem do Docker, que você precisará modificar para incluir seu nome de usuário da conta do Docker Hub, desta forma:

sample-js-function/sample-js.yml
version: 1.0
provider:
  name: openfaas
  gateway: http://127.0.0.1:8080
functions:
  sample-js:
    lang: node
    handler: ./sample-js
    image: your_docker_hub_username/sample-js:latest

Salve e feche o arquivo.

Em seguida, compile a imagem do Docker, envie-a para o Docker Hub e implante-a em seu cluster, simultaneamente, ao executar o seguinte comando:

  • faas up -f sample-js.yml

Você verá vários dados de saída (principalmente do Docker), que terminam da seguinte forma:

Output
. . . [0] < Pushing sample-js [your_docker_hub_username/sample-js:latest] done. [0] Worker done. Deploying: sample-js. Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/sample-js

Invoque sua função recém implantada para ter certeza de que ela está funcionando:

  • faas invoke sample-js

Pressione CTRL + D. Você verá a seguinte saída:

Output
<h1>Hello Sammy!</h1>

Isso significa que a função foi empacotada e implantada corretamente.

Você pode remover a função executando:

  • faas remove sample-js

Você criou e implantou com sucesso uma função Node.JS personalizada na instância OpenFaaS em seu cluster.

Conclusão

Você implantou o OpenFaaS em seu cluster do Kubernetes da DigitalOcean e está pronto para implantar e acessar funções pré-disponibilizadas e personalizadas. Agora você consegue implementar a função como uma arquitetura de serviço, que pode ampliar a utilização de recursos e trazer melhorias de desempenho para seus aplicativos.

Se quiser aprender mais sobre os recursos avançados do OpenFaaS, como o dimensionamento automático de suas funções implantadas e o monitoramento do desempenho delas, visite as documentações oficiais.

Creative Commons License