Brincando com Erlang nodes: embedded
- 5 minutes read - 903 wordsEste post faz parte de uma série de outros posts relacionados a como usar Erlang distribution protocol.
Na primeira parte, Brincando com Erlang nodes: eclero criamos uma aplicação básica. O próximo passo é continuar com o desenvolvimento dos requisitos. Relembrando e incrementando os requisitos, temos:
Cada nó necessita detectar e ser notificado de qualquer falha dos outros nós- O cluster de nós Erlang deve ser configurado utilizando algum tipo de configuração vinda do ambiente
- O ambiente de execução é Linux embarcado rodando em qualquer plataforma
- Desejável poder rodar em um ambiente embarcado com o mínimo de recursos necessários
- Mínimo de 3 nós para a solução funcionar
Agora vamos abordar alguns assuntos que não são propriamente relacionados com Erlang e Elixir mas fazem parte do contexto dos requisitos.
O objetivo é responder algumas pergunta:
- Como criar uma solução embarcada utilizando Erlang?
- É possível rodar Erlang em um ambiente embarcado?
- Definir um possível caminho para uma implementação
- Verificar se é possível rodar o ’eclero’ em um ambiente virtualizado gerando imagens com o Yocto Project e meta-erlang
Erlang embarcado não é uma ideia nova e muito menos revolucionária. De fato Erlang/OTP é usado em diversos tipos de ambientes (Linux, Solaris, Windows), inclusive existe uma documentação oficial sobre o assunto Embedded Users Guide.
Creio que atualmente existem diversas formas de fazer. Este post explora uma delas.
Yocto Project
É um projeto opensource, com mais de 10 anos de vida, com o objetivo de facilitar e criar um ecosistema para aplicações embarcadas com Linux.
Utilizando o projeto podemos criar uma distribuição linux, totalmente dimensionada para os requisitos de um produto ou solução. Aqui vou deixar referências pois não é o escopo abordar Yocto Project neste blog.
Entretanto a nossa solução vai utilizar Yocto Project para gerar as imagens embarcadas com todo o ferramental necessário. Então, como usuário vamo apenas executar os comandos:
- bitbake, para gerar imagens
- runquemu, para testar a imagem
Apenas isso.
meta-erlang
O Yocto Project possui uma maneira de extender novas funcionalidades e aplicações, sem a necessidade de alterar o projeto. Adicionando layers podemos trazer outros elementos para as imagens. Não há um limite para as layers e atualmente existe vários tipos para as mais variadas necessidades. Veja OpenEmbedded Layer Index para mais detalhes.
No post , abordamos sobre o assunto. Aqui vamos utilizar os conhecimentos e colocar em prática.
Receita da aplicação eclero
Como de usual, quando estamos brincando com Yocto Project, vamos criar uma receita para encapsular a aplicação.
https://github.com/joaohf/meta-axon/blob/master/recipes-extended/eclero/eclero_git.bb 1SUMMARY = "Simple erlang application to answer cluster health checks"
2DESCRIPTION = ""
3LICENSE = "MIT"
4LIC_FILES_CHKSUM = "file://LICENSE;md5=62612d1c0b9e46d8296dd0097c07db91"
5
6S = "${WORKDIR}/git"
7SRCREV = "0512ba7f71d09a88db5cb38f0ff726dfbf4f20ab"
8PV = "0.1.0-git${SRCPV}"
9PR = "r0"
10
11SRC_URI = "\
12 git://github.com/joaohf/eclero;branch=master;protocol=https \
13 "
14
15inherit rebar3
16
17REBAR3_PROFILE = "prod"
Para compilar a receita usamos o comando:
bitbake eclero
Receita da imagem embarcada eclero
O próximo passo é escrever uma receita que vai criar uma imagem linux bem pequena e a aplicação eclero.
A receita é bem simples e vai instalar todos os componentes necessários. Basicamente vamos instalar na imagem final:
- base-files, layout de arquivos e diretórios básicos
- erlinit, é um substituto do programa /sbin/init no qual executa uma release Erlang/OTP. erlinit é como se fosse um systemd ou initscripts mas usando uma abordagem minimalista.
- eclero
Estes componentes são o suficiente para criarmos uma imagem no qual vai executar o kernel Linux e a aplicação eclero.
https://github.com/joaohf/meta-axon/blob/master/recipes-extended/image/eclero-embedded-image-minimal.bb 1SUMMARY = "A small image just capable of allowing a device to boot with eclero."
2
3IMAGE_INSTALL = "\
4 packagegroup-erlang-embedded-initscripts \
5 eclero \
6 "
7
8IMAGE_LINGUAS = " "
9USE_NLS="no"
10
11LICENSE = "MIT"
12
13inherit core-image
14
15IMAGE_ROOTFS_SIZE ?= "8192"
Para construir a imagem executamos:
bitbake eclero-embedded-image-minimal
O resultado pode ser visto no diretório: tmp/deploy
QEMU
Precisamos testar a imagem e a aplicação e ver se tudo está funcionando. A maneira mais rápida de fazer isso é utilizando um emulador, no caso qemu.
O Yocto Project já disponibiliza as ferramentas necessárias, então executando
runqemu
vamos ver um o kernel Linux inicializando e o console da aplicação:
runqemu qemuarm axon-embedded-image-minimal
qemuparams="-serial stdio"
No asciinema acima podemos ver o kernel linux iniciando e já chamando o erlinit no qual se encarrega de chamar a aplicação eclero dentro de um VM Erlang.
Testando
A melhor forma de testar é executar duas operações:
Dentro do qemu (guest), usando o console Erlang, chamamos alguma API do eclero para verificar o estado do cluster:
Erlang/OTP 22 [erts-10.5.6] [source] [smp:1:1] [ds:1:1:10] [async-threads:30] Eshell V10.5.6 (abort with ^G) (eclero1@eclero)1> eclero_health:get(). {ok,[{eclero1@eclero,true}]}
No host Linux executamos o comando curl passando o endpoint que queremos acessar, recebemos como resposta 200 Ok:
curl -v 19w.168.7.2:8000/check - Trying 192.168.7.2... - TCP_NODELAY set - Connected to 192.168.7.2 (192.168.7.2) port 8000 (#0) > GET /check HTTP/1.1 Host: 192.168.7.2:8000 User-Agent: curl/7.58.0 Accept: > _/_ > > < HTTP/1.1 200 OK < content-length: 19 < content-type: text/plain < date: > Thu, 19 Dec 2019 21:28:16 GMT < server: Cowboy < - Connection #0 to host 192.168.7.2 left intact
Podemos ver que conseguimos obter resposta nos dois métodos testados.
Conclusão
Aparentemente tudo está funcionando. Mas o processo de desenvolvimento não foi tranquilo. Nos próximos posts vamos abordar os problemas. Por agora o importante é as referências dos links e códigos.
Agora já podemos executar a aplicação eclero em um ambiente embarcado.
Por enquanto é um nó apenas.