Um estudo de caso de conteinerização com o Docker

10 min de leitura
Patrocinado
Imagem de: Um estudo de caso de conteinerização com o Docker
Avatar do autor

Equipe TecMundo

Software como serviço (SaaS) é um modelo de entrega de software em que o software e os dados associados são hospedados na nuvem. Nesse modelo, a funcionalidade da aplicação é entregue por meio de uma assinatura online; mas as soluções SaaS estão em constante evolução.

Os times de pesquisa e desenvolvimento de produtos estão sempre adicionando camadas, recursos, ferramentas e plug-ins. O SaaS é barato, inteligente, atraente e constantemente no limite. Todos esses pontos tornam a solução SaaS uma opção relevante para administração de um negócio. De acordo com um estudo realizado pela North Bridge Venture Partners, “45% das empresas afirmam que já administram, ou planejam administrar, sua empresa a partir da nuvem — mostrando como a nuvem é essencial para os negócios”.

A evolução de produtos tradicionais em direção ao SaaS pode ser abordada de diferentes maneiras. (Usamos o termo “tradicional” para identificar produtos que não são cloud-native). A abordagem mais simples é portar o produto na nuvem, o que pode ser um passo à frente considerável se você não quiser se arriscar na migração para um produto cloud-native, mas ainda anseia por uma de suas vantagens (por exemplo, delegação de TI, eliminação de custos de infraestrutura e manutenção e maior segurança). Esse processo de “cloudificação” é basicamente uma migração chamada “lift-and-shift”: o produto é portado “no estado em que se encontra” em um provedor de nuvem de infraestrutura como serviço (IaaS).

Mas e se você quiser ser um provedor e oferecer um negócio de SaaS para seus clientes? É possível refatorar toda a arquitetura de produto e tentar reproduzir a força de um produto SaaS interessante e cloud-native? A alta disponibilidade, a escalabilidade, os microsserviços e as atualizações em tempo real são reproduzíveis para uma oferta SaaS baseada em tecnologia existente e essa abordagem pode ser competitiva? Em curto prazo, as aplicações existentes serão atendidas por SaaS?

O objetivo principal deste artigo é mostrar a evolução adicional do processo básico de cloudificação: impulsionar a conteinerização para abordar as questões descritas anteriormente e obter os benefícios de um puro e cloud-native. Especificamente, esse artigo discute um exemplo da abordagem que nossa equipe usou para mover o produto IBM Control Desk para um padrão de microsserviços usando a tecnologia de container Docker, sem a necessidade de redesenhar o produto ou tocar no código.

A aplicação foi dividida em seus componentes básicos e implementada em diferentes containers do WebSphere Liberty para obter um padrão de fornecimento mais gerenciável — tanto no tempo para lançamento no mercado quanto nas atividades gerais de operações de TI.

Nosso exemplo: a solução para o IBM Control Desk

O IBM Control Desk fornece gerenciamento de serviços de TI para simplificar o suporte de usuários e infraestruturas. Foi construído no componente Tivoli Product Automation Engine já incorporado no produto IBM Maximo Asset Management.

A arquitetura padrão consiste nas seguintes partes:

  • Uma aplicação Java Enterprise (UI e back-end)

  • Um banco de dados

  • Uma aplicação Node.js (um portal UI)

  • Um servidor web (load balancer)

Como um Java Runtime Environment, o WebSphere Application Server para Network Deployment era a escolha típica, pois o gerenciador do banco de dados suporta Oracle, DB2 e Microsoft SQL Server. A opção mais comum do servidor da web foi o IBM HTTP Server, especialmente para trabalhar com o WebSphere Application Server para Network Deployment, conforme mostrado na seguinte figura:

O guia de implementação do Maximo Asset Management, que também incluiu as práticas recomendadas, explicou como dividir a aplicação multifuncional em quatro aplicações diferentes: a Interface de Usuário (UI) do Maximo; Maximo Cron; Maximo Report e o Integration Framework. O custo em termos de esforço para atingir isso foi todo da equipe local de TI, sem nenhum procedimento padrão para auxiliar os engenheiros de tecnologia de informação. O Maximo Asset Management 7.6.1 incluiu o chamado “suporte Liberty”, dividindo ainda mais as aplicações e fornecendo um conjunto de scripts de construção que cria e agrupa apenas os módulos necessários para a função da aplicação.

O IBM Control Desk 7.6.1 foi desenvolvido sobre o Maximo Asset Management 7.6.1 e herdou o suporte Liberty usado para obter a decomposição do microsserviço.

Nosso caminho de implementação para conteinerizar a aplicação

O caminho de implementação que nosso time usou ilustra como tornar uma aplicação um SaaS.

O processo da nossa equipe incluiu as seguintes tarefas:

  • Instalar IBM Control Desk 7.6.1 no nó da workstation administrativa

  • Implementar o banco de dados IBM Control Desk em um nó DB2

  • Criar uma imagem Docker para o IBM Control Desk and Service Portal

  • Criar uma imagem Docker para o servidor JMS

  • Criar uma rede para permitir comunicação direta entre os containers

  • Rodar um container para cada imagem Docker que criamos

  • Configurar um servidor IBM HTTP para roteamento correto do tráfego para os containers

Nosso primeiro passo: instalando e implementando o IBM Control Desk 7.6.1

Para fins deste artigo, decidimos usar o mesmo nó como workstation administrativa e DB2. Usamos uma máquina virtual baseada no Red Hat Enterprise Linux Server 7 com duas CPUs de 4 GB de RAM, instalada com o produto IBM Control Desk e implementada no banco de dados MAXDB76.

O diretório de instalação do IBM Control Desk (que contém o código da aplicação) e o diretório de instalação do Service Portal são compartilhados através do sistema de arquivos de rede (NFS) com o Docker. Portanto, as aplicações ficam disponíveis para desenvolvimento nas duas estações.

Nosso segundo passo: criando as imagens Docker

Nós decidimos seguir todas as etapas descritas na documentação do Maximo Asset Management, então produzimos cinco diferentes aplicações:

  • UI

  • Cron

  • Maximo Enterprise Adapter (MEA)

  • API

  • Report (Business Intelligence and Reporting Tools — BIRT — Report Only Server ou “BROS”)

Depois, adicionamos duas aplicações para o service portal e o servidor JMS, que recebe, armazena e envia mensagens em qualquer lugar que o protocolo JMS seja utilizado.

  • Service Portal (SP)

  • JMS Server (JMS)

A ilustração a seguir mostra uma representação da arquitetura:

Nós construímos as aplicações seguindo as instruções do Maximo Asset Management 7.6.1 WebSphere Liberty Support, que produz uma série de arquivos web archive (war).

Por exemplo, para a aplicação UI, usamos o seguinte comando na workstation administrativa:

cd /opt/IBM/SMP/maximo/deployment/was-liberty-default

./buildmaximoui-war.sh && ./buildmaximo-xwar.sh

O subdiretório deployment/máximo-ui/máximo-ui-server/apps tinha a seguinte estrutura:

deployment/maximo-ui/maximo-ui-server/

+-- apps

¦   +-- maximoui.war

¦   +-- maximo-x.war

+-- Dockerfile

+-- jvm.options

+-- server.xml

O arquivo server.xml era o descritor do servidor; jvm.options continha as propriedades do sistema para definir o nível de inicialização da JVM; Dockerfile era o arquivo usado para construir a imagem e as aplicações continham os artefatos do desenvolvimento:

-rw-r--r-- 1 root root 1157149383 Mar 20 09:57 maximoui.war

-rw-r--r-- 1 root root   70932873 Mar 20 10:01 maximo-x.war

As outras aplicações tinham estrutura semelhante. (Você pode ver o Dockerfile na seção de procedimentos técnicos).

Do endereço para o Dockerfile na workstation, nós construímos uma imagem Docker rodando o seguinte comando:

docker build . -t icd/ui:7.6.1.0

Fizemos o mesmo com as outras aplicações Liberty, então obtivemos as seguintes imagens:

icd/ui:7.6.1.0

icd/cron:7.6.1.0

icd/mea:7.6.1.0

icd/bros:7.6.1.0

icd/api:7.6.1.0

O servidor JMS não veio por padrão com suporte Maximo Liberty. Precisávamos criá-lo do zero. Nosso procedimento foi baseado na documentação do WebSphere Application Server Liberty. (Você pode ver o arquivo server.xml de exemplo na seção de procedimentos técnicos).

Criamos a imagem Docker do Service Portal a partir da imagem Node.js. Para a aplicação Service Portal, copiamos a árvore completa, o certificado e a chave privada exportada pelo servidor da web para permitir a comunicação entre os dois componentes. (O Dockerfile for Service Portal está incluído na seção de procedimentos técnicos.)

Posteriormente, obtivemos as seguintes imagens:

icd/ui:7.6.1.0

icd/cron:7.6.1.0

icd/mea:7.6.1.0

icd/bros:7.6.1.0

icd/api:7.6.1.0

icd/jms:1.0.0.0

icd/sp:7.6.1.0

Nosso terceiro passo: implementar os containers

Escolhemos para o Docker uma máquina Ubuntu 18.04 com quatro CPUs de 32 GB de RAM, um tamanho típico para a arquitetura SaaS padrão.

Depois que obtivemos nossas imagens, começamos a implementar containers a partir delas. Primeiro implementamos com um container por imagem. Em seguida, fizemos um teste de escalabilidade com dois containers da interface de usuário, conforme discutido na seção de resultados.

Criamos uma rede Docker chamada ICDNet e lá adicionamos cada container em execução, o que permitiu comunicação fácil entre todos os containers.

No final, nosso comando docker ps formatado ficou como o seguinte exemplo:

NAME    SP

IMAGE   icd/sp:7.6.1.0

PORTS   0.0.0.0:3000->3000/tcp

 

NAME    CRON

IMAGE   icd/cron:7.6.1.0

PORTS   9080/tcp, 9443/tcp

 

NAME    UI

IMAGE   icd/ui:7.6.1.0

PORTS   0.0.0.0:9080->9080/tcp, 0.0.0.0:9443->9443/tcp

 

NAME    API

IMAGE   icd/api:7.6.1.0

PORTS   0.0.0.0:9081->9080/tcp, 0.0.0.0:9444->9443/tcp

 

NAME    MEA

IMAGE   icd/mea:7.6.1.0

PORTS   0.0.0.0:9084->9080/tcp, 0.0.0.0:9447->9443/tcp

 

NAME    JMS

IMAGE   icd/jms:1.0.0.0

PORTS   9080/tcp, 0.0.0.0:9011->9011/tcp, 9443/tcp

 

NAME    BROS

IMAGE   icd/bros:7.6.1.0

PORTS   0.0.0.0:9085->9080/tcp, 0.0.0.0:9448->9443/tcp

Todos os recursos — container, rede e volumes — são criados usando a ferramenta de composição do Docker (o arquivo docker-compose.yml está incluído na seção de procedimentos técnicos). O arquivo YAML inclui parâmetros no comando de execução para cada container; por exemplo, o db host e algumas variáveis de ambiente para configurar corretamente os containers.

Nosso procedimento técnico

O exemplo a seguir mostra o Dockerfile para a imagem baseada no Liberty:

FROM websphere-liberty

USER root

 

# Copy the applications

COPY --chown=default:root apps /opt/ibm/wlp/usr/servers/defaultServer/apps

 

# Copy the server.xml and JVM options

COPY server.xml /opt/ibm/wlp/usr/servers/defaultServer/

COPY jvm.options /opt/ibm/wlp/usr/servers/defaultServer/

 

# install the additional utilities listed in the server.xml

RUN ["/opt/ibm/wlp/bin/installUtility","install","defaultServer"]

server.xml file for the JMS docker image

servlet-3.1

wasJmsClient-2.0

wasJmsServer-1.0

jmsMdb-3.2



  wasJmsPort="9011" wasJmsSSLPort="9100"/>

 

  receiveAllowed="true" maintainStrictOrder="false"/>

 

  sendAllowed="true"

  receiveAllowed="true"maintainStrictOrder="false"/>

 

  receiveAllowed="true" maintainStrictOrder="false"/>

 

  receiveAllowed="true" maintainStrictOrder="false"/>

 

  sendAllowed="true" receiveAllowed="true"

  maintainStrictOrder="false"/>

 

O seguinte exemplo mostra o Dockerfile para a imagem do servidor JMS:

FROM websphere-liberty

 

COPY files/server.xml /opt/ibm/wlp/usr/servers/defaultServer/

 

RUN ["/opt/ibm/wlp/bin/installUtility","install","defaultServer"]

O próximo exemplo mostra o Dockerfile para a imagem do Service Portal:

FROM aricenteam/aricentrepo:nodejs

USER root

 

# copy the serviceportal tree in the /opt/ibm/ng directory

RUN mkdir -p /opt/ibm/ng

COPY ng /opt/ibm/ng/

 

# copy certificate and key files

COPY server.crt /opt/ibm/ng

COPY server.key /opt/ibm/ng

 

EXPOSE 3000

WORKDIR /opt/ibm/ng

CMD ["node", "app.js"]

docker-compose.yml file

version: '3.7'

 

services:

  ui:

    image: icd:ui

    ports:

      - "9443"

    environment:

      JVM_ARGS: "-Dmxe.name=MAXIMO_UI"

    networks:

      - icd_net

    volumes:

      - doclinks:/DOCLINKS

      - search:/SEARCH

  api:

    image: icd:api

    ports:

      - "9443"

    environment:

      JVM_ARGS: "-Dmxe.name=MAXIMO_API"

    networks:

      - icd_net

    volumes:

      - doclinks:/DOCLINKS

      - search:/SEARCH

  cron:

    image: icd:cron

    ports:

      - "9443"

    environment:

      JVM_ARGS: "-Dmxe.name=MAXIMO_CRON"

    networks:

      - icd_net

    volumes:

      - doclinks:/DOCLINKS

      - search:/SEARCH

  mea:

    image: icd:mea

    ports:

      - "9443"

    environment:

      JVM_ARGS: "-Dmxe.name=MAXIMO_MEA"

    networks:

      - icd_net

    volumes:

      - doclinks:/DOCLINKS

      - search:/SEARCH

  jms:

    image: icd:jms_server

    networks:

      - icd_net

 

networks:

  icd_net:

    driver: bridge

 

volumes:

  doclinks:

  search:

Nossos resultados

Depois de instalar nossa instância do Control Desk, fizemos algumas medições com a ferramenta Rational Performance Tester para comparar o desempenho de uma instância clássica e a baseada em container. Executamos dois testes diferentes com uma carga de trabalho de 20 e 50 usuários e monitoramos a CPU com script nmon e a memória das máquinas virtuais.

Conforme mostrado na imagem a seguir, observamos um maior consumo de memória pela instância clássica (implementada no WebSphere Application Server para Network Deployment), em virtude principalmente do número de processos Java em execução. Também incluiu o gerenciador de implementação e o agente do nó. No lado da CPU, os comportamentos se sobrepõem.

A tabela a seguir mostra os valores médios, mínimos e máximos do tempo de resposta da página (PRT). Parecia que o Docker teve um desempenho um pouco melhor, com uma resposta média de ~0,1 vez a verificada no caso clássico.

Para cenários de 50 usuários também realizamos um teste de escalabilidade adicionando outro container de interface do usuário à instância e verificando se a carga de trabalho está equilibrada. 

A captura de tela a seguir mostra o tempo de resposta da página (PRT) e as funções nos casos de um e dois containers da interface do usuário. Os resultados confirmaram o que era esperado: o desempenho de dois containers aumentou a um fator de 2. Então, concluímos que a instância é escalonada com uma tendência quase ideal.

Resumo

Esse artigo mostrou um estudo de caso usando a tecnologia de container para alavancar o suporte nativo para o WebSphere Liberty Profile com o produto IBM Control Desk.

O resultado mais interessante? Descobrimos que poderíamos mover um produto tradicional para containers a fim de evoluí-lo em direção a uma arquitetura “native-cloud” sem a necessidade de “tocar no código”. Não houve impactos no nível da aplicação.

Aplicações native-cloud geralmente são projetadas com um padrão de microsserviços que permite uma implementação natural em containers, mas esse não é o caso de produtos clássicos como Control Desk. Apesar desse desafio, um profundo conhecimento do produto em si torna possível o padrão de microsserviços na fase de implementação. Como fizemos, você pode identificar módulos independentes que “imitam” os diferentes microsserviços para garantir algum nível de dissociação em sua interação.

Você pode encontrar um desafio semelhante, no qual não possa tocar no código-fonte. Com base no estudo de caso descrito neste artigo, considere o procedimento geral a seguir para migrar um produto existente para uma arquitetura baseada em containers com um padrão semelhante ao de microsserviço:

  • Diagnóstico de produto: identifique módulos independentes na sua aplicação.

  • Analise seu conjunto de builds: você precisa reprojetar scripts da build, se não fornecidos, para produzir os módulos descritos na etapa 1 (um tipo de fatoração).

  • Implementação: implemente cada módulo em um único container (como as etapas de exemplo descritas anteriormente).

  • Configure o tráfego entre módulos: configure os diferentes containers para que eles possam se comunicar, garantindo os recursos gerais da aplicação.

  • Teste: verifique se a nova arquitetura de implementação não apresenta problemas inesperados na aplicação, concentrando-se especificamente no desempenho e na escala.

Desejamos o melhor para você ao mover seus aplicativos tradicionais para um ambiente de containers. Essas dicas e exemplos podem orientá-lo a tornar o processo o mais simples possível.

...

Quer ler mais conteúdo especializado de programação? Conheça a IBM Blue Profile e tenha acesso a matérias exclusivas, novas jornadas de conhecimento e testes personalizados. Confira agora mesmo, consiga as badges e dê um upgrade na sua carreira!

Você sabia que o TecMundo está no Facebook, Instagram, Telegram, TikTok, Twitter e no Whatsapp? Siga-nos por lá.