Table of Contents
*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 the cloud provider 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 the cloud provider com sua conexão configurada como o
kubectlpadrã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 okubectlsão mostradas no passo Conexão com seu cluster, quando você criar seu cluster. Para criar um cluster do Kubernetes no the cloud provider, 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
stabledo 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 the cloud provider 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 the cloud provider", 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:
[secondary_label 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:
[secondary_label Output]
"openfaas" has been added to your repositories
Recarregue o cache do chart do Helm:
helm repo update
Você verá o seguinte resultado:
[secondary_label 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:
[label 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:
[secondary_label 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:
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:
[label 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:
[secondary_label 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:
[secondary_label 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:
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:
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.
Selecione-a. Na parte central da tela, você verá informações básicas sobre a 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.
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.
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:
[label ~/.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:
[secondary_label 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:
[secondary_label 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:
[secondary_label 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:
[secondary_label 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:
[secondary_label Output]
Deleting: nodeinfo.
Removing old function.
Execute faas list novamente para ver que o nodeinfo foi removido:
[secondary_label 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:
[secondary_label 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:
[label 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:
[label 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:
[label 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:
[label 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:
[secondary_label 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:
[secondary_label 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 the cloud provider 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.