Desenvolva aplicativos Internet of Things rapidamente com os contêineres de Docker

Visão geral de contêineres

A Internet of Things, a rede altamente conectada de dispositivos inteligentes, como sensores ambientais, trackers médicos, eletrodomésticos e equipamentos industriais, está crescendo rapidamente. Em 2020, é previsto que haverá 20 bilhões de dispositivos conectados, o que é mais do que duas vezes o número de PCs, smartphones e tablets combinados. Os desenvolvedores estão começando rapidamente a criar aplicativos para a IoT e usando contêiner que pode ajudá-los de diferentes maneiras.

Contêineres são uma abordagem leve para a virtualização que os desenvolvedores podem aplicar para desenvolver, testar, implementar e atualizar rapidamente os aplicativos da IoT em escala. Muitos desenvolvedores de aplicativos da web e móveis fazem uso de hypervisors, como VirtualBox, para executar máquinas virtuais (VMs) que virtualizam hardware físico como parte de um desenvolvimento multi-plataforma, testes e implementação de fluxo de trabalho.

Virtualização baseada em contêiner (às vezes chamada de virtualização de nível de sistema operacional) é muito mais leve. Cada contêiner é executado como uma instância isolada de espaço do usuário de um kernel de sistema operacional de hospedagem compartilhada. Embora o sistema operacional seja compartilhado, contêineres individuais têm interfaces de rede virtuais independentes, espaços de processo independentes e sistemas de arquivos separados. Estes contêineres podem ser alocados com os recursos do sistema, como memória RAM, usando grupos de controle que implementam isolamento de recursos. Comparado à virtualização baseada em hipervisor, onde cada VM é executada em seu próprio sistema operacional, que só aumenta a sua utilização de recursos do sistema, os contêineres usam muito menos recursos de disco e memória.

Docker é uma plataforma aberta para virtualização baseada em contêiner no Linux. Docker torna rápido e fácil construir contêineres e implementá-los rápido e em qualquer lugar: em uma nuvem pública ou privada, dentro de uma VM local ou em um hardware físico, incluindo dispositivos da IoT. Os Contêineres IBM são um recurso beta do IBM Cloud baseado em Docker para entrega e implementação de aplicativos de contêiner na plataforma IBM Cloud.

Trabalhando com contêineres, imagens e registros

Cada contêiner do Docker contém um ou mais processos em execução. O contêiner do Docker é ativado a partir de uma imagem que especifica esses elementos:

  • As informações de configuração de um aplicativo a ser executado dentro do contêiner
  • Suas dependências, por exemplo, bibliotecas e arquivos binários compartilhados

O Docker usa um sistema de arquivos em união para armazenar imagens como uma série de camadas. As camadas são armazenadas em cache durante o processo de criação, o que torna a construção de imagens derivativas rápida e eficiente.

Esta abordagem em camadas também significa que as imagens do Docker são pequenas e portáteis, o que as torna fácil de compartilhar, publicando-as em registro público ou privado. O Hub do Docker é o maior registro de repositórios de imagens do Docker; ele lista mais de 100.000 repositórios e hospeda inúmeros repositórios privados. Se você estiver usando a plataforma de nuvem do IBM Cloud, ela suporta puxar imagens públicas do Hub do Docker e também fornece repositórios de imagens privadas hospedados que permitem compartilhar imagens privadas dentro da sua organização.

Se você estiver usando uma estrutura ou serviço popular de software livre, é provável que será capaz de localizar uma imagem pública pré-construída no Hub do Docker, com muitas das imagens mantidas pelas comunidades de software livre que são associadas a esses projetos. A interface da web do Hub do Docker oferece uma pequena lista de repositórios oficiais, que é uma lista curada de repositórios que incluem imagens que são testadas pela equipe do Docker em busca de vulnerabilidades de segurança conhecidas.

Evite o uso de imagens mais antigas do Docker, mesmo a partir de origens confiáveis, pois muitas das imagens mais velhas são apenas fornecidas para propósitos de arquivamento e teste. As imagens mais antigas são marcadas como suportadas no Hub do Docker se ainda forem mantidas. A maioria das imagens no registro público são de comunidades contribuídas e não podem ser bem documentadas ou mantidas. Em caso de dúvida, crie a sua própria imagem usando uma das imagens oficiais como base.

É possível criar uma imagem concluindo essas etapas:

  1. Puxe uma imagem base do regsitro
  2. Execute uma série de comando interativamente
  3. Confirme o resultado como uma nova imagem

Por exemplo, a seguinte lista de comandos puxa a imagem da versão 14.04 do Ubuntu oficial do Hub do Docker, ativa um contêiner a partir da imagem para executar um comando que instala o Git no contêiner, em seguida, lista o ID do contêiner que foi criado.

Criando uma imagem
$ docker pull ubuntu:14.04
$ docker run ubuntu apt-get install -y git
$ docker ps -l

É possível salvar este contêiner (cb23e345fde0) como uma nova imagem (nomeada demo/git) emitindo o seguinte comando: $ docker commit cb23e345fde0 demo/git.

Para executar os comandos do Docker localmente usando a ferramenta IBM Container Extensions, altere o comando docker para ice --local. Por exemplo, use este comando: $ ice --local pull ubuntu:14.04

Se precisar executar mais de um ou dois comandos para configurar seu ambiente de aplicativo, você desejará criar um Dockerfile. Dockerfiles são arquivos de texto que especificam uma lista de instruções para construção de uma imagem. O Dockerfile na seguinte listagem de código cria uma imagem base para a execução de um servidor da web Nginx.

Dockerfile que cria uma imagem base para executar um servidor da web Nginx
FROM ubuntu:14.04
RUN apt-get -y update && apt-get install -y nginx
RUN mkdir -p /var/www/html
EXPOSE 80
EXPOSE 443
WORKDIR /etc/nginx
CMD ["nginx"]

A primeira instrução em cada Dockerfile é uma instrução FROM, que indica a imagem base. Cada instrução subsequente no Dockerfile é armazenada como uma camada: As instruções

  • RUN executam comandos do Linux, como os comandos apt-get. As instruções
  • ADD e COPY incluem os arquivos de aplicativo no contêiner. As instruções
  • EXPOSE abrem portas. As instruções
  • ENV configuram variáveis de ambiente.

Finalmente, cada Dockerfile contém instruções WORKDIR, ENTRYPOINT ou CMD para especificar como e onde executar o aplicativo quando o contêiner é ativado.

Executar contêineres do Docker requer bem poucos custos adicionais, assim, é possível dividir seu aplicativo em um conjunto de serviços que são executados em contêineres separados que podem ser vinculados pelo nome ao executá-los. Por exemplo, é possível dividir seu aplicativo em um contêiner que executa um aplicativo Node.js vinculado a outro contêiner que executa um armazenamento Redis de valor chave.

Mantendo um ambiente de desenvolvimento de IoT consistente usando contêineres

Aplicativos IoT direcionam uma grande variedade de plataformas de dispositivos. Durante a criação de protótipos e fases iniciais de desenvolvimento, os projetos de IoT são muitas vezes desenvolvidos utilizando placas de desenvolvimento baseadas em microcontroladores genéricos ou computadores de placa única (SBCS), como o Raspberry Pi. Os aplicativos integrados que são desenvolvidos para esses dispositivos podem ser posteriormente atualizados para serem executados em placas de desenvolvimento de protótipos customizados e, finalmente, em dispositivos de produção. É possível avaliar um leque de potenciais microcontroladores e dispositivos system-on-a-chip (SoC), com distintos e algumas vezes incompatíveis requisitos de driver de dispositivo. Cada dispositivo ou revisão de dispositivo também pode requerer diferentes versões e configurações dos kits de ferramentas de desenvolvimento que são usados para utilizar memória flash, monitorar e comunicar-se com o dispositivo.

Os contêineres podem ser utilizados para capturar um ambiente de desenvolvimento que é conhecido por trabalhar para cada revisão de dispositivo e para compartilhar esse ambiente entre uma equipe de desenvolvedores. Por exemplo, se a sua equipe estava trabalhando com vários tipos de placas de desenvolvimento compatíveis com Arduino, será possível criar uma imagem que contém o kit de ferramentas da linha de comando do Arduino e um programa de emulação de terminal dumb para comunicação de série como sua imagem de desenvolvimento de linha de base. Será possível, então, usar essa imagem base de desenvolvimento do Arduino para criar novas imagens variantes para cada uma das placas de desenvolvimento que requerem drivers customizados específicos.

O sistema de arquivos em camadas do Docker torna eficiente o uso do espaço nesta situação, uma vez que apenas as camadas exclusivas são armazenadas quando uma nova imagem é criada. O comando de histórico do docker exibe uma lista das várias camadas, formando uma imagem, incluindo a instrução que criou cada camada e o tamanho da camada, como:

IMAGE           CREATED         CREATED BY              SIZE
3ca43a9a4095    20 hours ago    apt-get install -y git  37.64 MB

As camadas são armazenadas em cache, de modo que é possível tentar rapidamente novas variações da imagem. Por exemplo, é possível que o Cliente queira aplicar as atualizações para os drivers ou ferramentas de desenvolvimento. As camadas também o tornam indolor para reverter a uma versão anterior da imagem e tentar uma abordagem diferente se algo der errado.

Se as mudanças em seu ambiente de desenvolvimento forem bem-sucedidas, a nova imagem poderá ser enviada por push para seu registro de equipe privado para propagar rapidamente as mudanças para o resto da equipe. Quando cada membro da equipe puxar a imagem atualizada, já terão a maioria das camadas armazenadas em cache, assim, obter a nova imagem instalada e funcionando normalmente leva apenas de poucos segundos a alguns minutos para o Docker percorrer as instruções a fim de criar as novas camadas. Comparado a realizar o push e pull em capturas instantâneos de imagens de VM ou construir imagens inteiras a partir do zero para cada variação, as camadas economizam espaço de armazenamento, mas também o mais importante, o tempo do seu desenvolvedor.

Implementando contêineres em dispositivos IoT

O apelo de um aplicativo com Docker é que depois de ter construído uma imagem, será possível enviar e executá-lo em praticamente qualquer lugar. Se o dispositivo IoT for executado no Linux, será possível implementar contêineres diretamente em seu dispositivo. Apesar dos recursos de sistema limitados que estão normalmente disponíveis em tais dispositivos IoT, é viável implementar contêineres do Docker porque os custos adicionais do seu tempo de execução são de quase zero. É possível até mesmo executar vários contêineres em seu dispositivo, por exemplo, se gostaria de executar diferentes versões do seu aplicativo lado a lado para comparação.

O Docker requer um kernel moderno do Linux com suporte para namespaces do kernel e grupos de controle, de modo que as imagens base adequadas podem ainda não estar disponíveis para o dispositivo IoT preferencial. É possível esperar ver mais dispositivos IoT com capacidade para o Linux serem desenvolvidos como o ponto de preço de SoCs adequados continuarem a cair (por exemplo, a placa de desnvolvimento C.H.I.P. de $ 9); em seguida, uma escolha mais ampla de distribuições do Linux direcionadas a estas plataformas se tornarão disponíveis.

O Hub do Docker contém uma série de imagens baseadas em ARM para SBCs de hobbyist populares, como o Raspberry Pi e BeagleBone Black. Se forem executados contêineres diretamente em seu dispositivo, será possível evitar ter que atualizar constantemente o seu dispositivo ou substituir todo o firmware. Em vez disso, é possível construir novas imagens, puxá-las e executá-las dentro do sistema operacional do host no dispositivo e rapidamente criar um protótipo e experimentar com bibliotecas e firmware mais avançados para aproveitar ao máximo o seu dispositivo IoT.

Desenvolvedores de IoT enfrentam o desafio de manter uma rede de dispositivos conectados atualizada e executando em conexões wireless potencialmente pouco confiáveis e de baixa largura de banda. Além disso, eles devem considerar a forma de manter a segurança de dados confidenciais e altamente pessoais que muitos destes dispositivos coletam. Os dispositivos IoT podem ser conectados apenas de forma esporádica, com alguns dispositivos definidos para hibernar em horários diferentes para economizar energia. Outros dispositivos IoT podem ser conectados usando uma topologia de rede de malha em que apenas partes da rede são acessíveis a qualquer momento. Atualizações baseadas em push tendem a falhar quando a conectividade de rede cai, e o perigo de aplicar atualizações incompletas ou potencialmente corrompidas é que os dispositivos podem entrar em um estado inconsistente ou ficarem inoperantes.

O Docker fornece uma possível solução para este problema de atualização. Um dispositivo que emite um pedido de pull para versão mais recente da imagem do seu aplicativo será enviado apenas para a imagem que executa diff por meio da Internet em vez de toda a imagem. As atualizações à base de diff serão concluídas muito mais rapidamente, o que reduz a quantidade de tempo que o dispositivo necessita para ser conectado e reduz a probabilidade de falha, colocando menos pressão sobre as redes de baixa largura de banda. Isso possibilita que as atualizações sejam aplicadas mais frequentemente.

Alguns dispositivos IoT permitem interação limitada com o usuário por meio de botões físicos ou pequenas telas sensíveis ao toque, no entanto, para muitos dispositivos IoT da geração atual, o principal meio de interação do usuário é com aplicativos móveis. Não deveria ser uma surpresa que os contêineres do Docker estão sendo cada vez mais adotados para acelerar testes automatizados, integração contínua e entrega de aplicativos móveis.

Integrando dispositivos IoT com a nuvem

Implementar aplicativos em dispositivos inteligentes e dispositivos móveis é apenas uma parte da história de desenvolvimento da Internet of Things. Muitos da geração atual de dispositivos IoT publicam dados e eventos nos serviços em nuvem.

Os contêineres são projetados para executar serviços em nuvem. No entanto, os contêiner são passageiros, então todos os dados gravados no sistema de arquivos dentro de um contêiner de banco de dados em execução devem ser considerados temporários; ou seja, os dados serão perdidos se o contêiner for encerrado. Em certo sentido, usar contêineres força o Cliente a estabelecer o bom hábito de desenvolver aplicativos de nuvem sem estado. Quaisquer dados que devam ser persistentes devem ser armazenados usando um volume de dados. Os volumes de dados persistem depois que um contêiner é encerrado, e podem ser compartilhados entre vários contêineres.

À medida que o número de dispositivos conectados aumenta, aplicativos baseados em nuvem para a IoT terão que dimensionar para lidar com o volume de dados a ser gerado. Felizmente, podemos aproveitar o crescente ecossistema de ferramentas de orquestração construído em torno do Docker para o desenvolvimento de aplicativos em nuvem escaláveis, incluindo as ferramentas recentemente anunciadas, Docker Machine, Swarm e Compose. Estas ferramentas são recomendadas apenas para os ambientes de desenvolvimento no presente, mas o Docker está trabalhando em torná-las prontas para a produção para uma série de plataformas de nuvem, incluindo o EC2 Container Services, Microsoft Azure e IBM Cloud. O IBM Cloud também suporta atualmente a execução de grupos de contêineres para balanceamento de carga e failover.

Conclusão

Para atender à demanda prevista para aplicativos para a Internet of Things, os desenvolvedores precisarão adotar ferramentas e práticas que permitam desenvolver rapidamente aplicativos e serviços IoT para executar em dispositivos inteligentes, dispositivos móveis e na nuvem. Com a capacidade de enviar e executar aplicativos em qualquer lugar, com custos adicionais mínimos de tempo de execução, e com um sistema de arquivos em camadas que resulta em imagens portáteis leves e rápida construção de imagens, os contêineres do Docker são uma ótima ferramenta para os desenvolvedores da IoT.

Aviso

O conteúdo aqui presente foi traduzido da página IBM Developer US. Caso haja qualquer divergência de texto e/ou versões, consulte o conteúdo original.