Compartilhar via


Conteinerizando aplicações monolíticas

Dica

Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

miniatura da capa do eBook sobre arquitetura de microsserviços do .NET para aplicativos .NET em contêineres.

Talvez você queira criar um único aplicativo Web ou serviço implantado monolicamente e implantá-lo como um contêiner. O aplicativo em si pode não ser monolítico internamente, mas estruturado como várias bibliotecas, componentes ou até mesmo camadas (camada de aplicativo, camada de domínio, camada de acesso a dados etc.). Externamente, no entanto, é um único contêiner: um único processo, um único aplicativo Web ou um único serviço.

Para gerenciar esse modelo, você implanta um único contêiner para representar o aplicativo. Para aumentar a capacidade, escale horizontalmente, ou seja, basta adicionar mais cópias com um balanceador de carga na frente. A simplicidade vem do gerenciamento de uma única implantação em um único contêiner ou VM.

Diagrama mostrando os componentes de um aplicativo em contêiner monolítico.

Figura 4-1. Exemplo da arquitetura de um aplicativo monolítico em contêineres

Você pode incluir vários componentes, bibliotecas ou camadas internas em cada contêiner, conforme ilustrado na Figura 4-1. Um aplicativo em contêiner monolítico tem a maior parte de sua funcionalidade em um único contêiner, com camadas ou bibliotecas internas, e é dimensionado clonando o contêiner em vários servidores/VMs. No entanto, esse padrão monolítico pode entrar em conflito com o princípio do contêiner "um contêiner faz uma coisa e faz isso em um único processo", mas pode ser ok para alguns casos.

A desvantagem dessa abordagem fica evidente se o aplicativo cresce, exigindo que ele seja dimensionado. Se todo o aplicativo puder ser dimensionado, não será realmente um problema. No entanto, na maioria dos casos, apenas algumas partes do aplicativo são os pontos de estrangulamento que exigem dimensionamento, enquanto outros componentes são menos usados.

Por exemplo, em um aplicativo de comércio eletrônico típico, você provavelmente precisa dimensionar o subsistema de informações do produto, pois muito mais clientes navegam em produtos do que os compram. Mais clientes usam sua cesta do que usam o sistema de pagamento. Menos clientes adicionam comentários ou veem seu histórico de compras. E você pode ter apenas um punhado de funcionários que precisam gerenciar o conteúdo e as campanhas de marketing. Se você dimensionar o design monolítico, todo o código para essas tarefas diferentes será implantado várias vezes e dimensionado na mesma classe.

Há várias maneiras de dimensionar uma duplicação horizontal do aplicativo, dividindo diferentes áreas do aplicativo e particionando dados ou conceitos de negócios semelhantes. Porém, além do problema de dimensionamento de todos os componentes, as alterações em um único componente exigem o reteste completo de todo o aplicativo e uma reimplantação completa de todas as instâncias.

No entanto, a abordagem monolítica é comum, pois o desenvolvimento do aplicativo é inicialmente mais fácil do que para abordagens de microsserviços. Assim, muitas organizações se desenvolvem usando essa abordagem arquitetônica. Embora algumas organizações tenham tido resultados suficientes, outras estão atingindo limites. Muitas organizações projetaram seus aplicativos usando esse modelo porque as ferramentas e a infraestrutura tornaram muito difícil a construção de arquiteturas orientadas a serviço (SOA) alguns anos atrás, e não viram a necessidade até que o aplicativo se expandisse.

Do ponto de vista da infraestrutura, cada servidor pode executar muitos aplicativos no mesmo host e ter uma taxa aceitável de eficiência no uso de recursos, conforme mostrado na Figura 4-2.

Diagrama mostrando um host executando muitos aplicativos em contêineres.

Figura 4-2. Abordagem monolítica: host executando vários aplicativos, cada aplicativo em execução como um contêiner

Aplicativos monolíticos no Microsoft Azure podem ser implantados usando VMs dedicadas para cada instância. Além disso, usando conjuntos de dimensionamento de máquinas virtuais do Azure, você pode dimensionar facilmente as VMs. O Serviço de Aplicativo do Azure também pode executar aplicativos monolíticos e dimensionar facilmente instâncias sem exigir que você gerencie as VMs. Desde 2016, os Serviços de Aplicativo do Azure também podem executar instâncias individuais de contêineres do Docker, simplificando a implantação.

Como um ambiente de QA ou um ambiente de produção limitado, você pode implantar várias VMs de host do Docker e equilibrá-las usando o Azure Load Balancer, conforme mostrado na Figura 4-3. Isso permite que você gerencie o dimensionamento com uma abordagem de alto nível, pois todo o aplicativo opera em um único contêiner.

Diagrama mostrando vários hosts executando os contêineres de aplicativo monolítico.

Figura 4-3. Exemplo de vários hosts dimensionando um único aplicativo de contêiner

A implantação para os vários hosts pode ser gerenciada com técnicas de implantação tradicionais. Os hosts do Docker podem ser gerenciados com comandos como docker run ou docker-compose executados manualmente ou por meio de automação, como pipelines de CD (entrega contínua).

Implantando um aplicativo monolítico como um contêiner

Há benefícios em usar contêineres para gerenciar implantações de aplicativos monolíticos. Dimensionar instâncias de contêiner é muito mais rápido e fácil do que implantar VMs adicionais. Mesmo que você use conjuntos de dimensionamento de máquinas virtuais, as VMs levam tempo para serem iniciadas. Quando implantada como instâncias de aplicativo tradicionais em vez de contêineres, a configuração do aplicativo é gerenciada como parte da VM, o que não é o ideal.

Implantar atualizações como imagens do Docker é muito mais rápido e eficiente para a rede. Normalmente, as imagens do Docker começam em segundos, o que acelera as distribuições. Derrubar uma instância de imagem do Docker é tão fácil quanto emitir um docker stop comando e normalmente é concluído em menos de um segundo.

Como os contêineres são imutáveis por design, você nunca precisa se preocupar com VMs corrompidas. Por outro lado, os scripts de atualização de uma VM podem se esquecer de considerar alguma configuração ou arquivo específico deixado em disco.

Embora aplicativos monolíticos possam se beneficiar do Docker, estamos tocando apenas nos benefícios. Benefícios adicionais do gerenciamento de contêineres vêm da implantação com orquestradores de contêineres, que gerenciam as várias instâncias e o ciclo de vida de cada instância de contêiner. Dividir o aplicativo monolítico em subsistemas que podem ser dimensionados, desenvolvidos e implantados individualmente é o ponto de entrada no reino dos microsserviços.

Publicando um aplicativo baseado em contêiner único no Serviço de Aplicativo do Azure

Se você deseja obter a validação de um contêiner implantado no Azure ou quando um aplicativo é simplesmente um aplicativo de contêiner único, o Serviço de Aplicativo do Azure fornece uma ótima maneira de fornecer serviços escalonáveis baseados em contêiner único. Usar o Serviço de Aplicativo do Azure é simples. Ele fornece uma ótima integração com o Git para facilitar a captura do código, compilá-lo no Visual Studio e implantá-lo diretamente no Azure.

Captura de tela da caixa de diálogo Criar Serviço de Aplicativo mostrando um Registro de Contêiner.

Figura 4-4. Publicando um aplicativo de contêiner único no Serviço de Aplicativo do Azure a partir do Visual Studio 2022

Sem o Docker, se você precisasse de outras funcionalidades, estruturas ou dependências que não têm suporte no Serviço de Aplicativo do Azure, será necessário aguardar até que a equipe do Azure atualize essas dependências no Serviço de Aplicativo. Ou você teve que mudar para outros serviços, como serviços de nuvem do Azure ou VMs, em que você tinha mais controle e poderia instalar um componente ou estrutura necessário para seu aplicativo.

O suporte a contêineres no Visual Studio 2017 e posterior oferece a capacidade de incluir o que quiser em seu ambiente de aplicativo, conforme mostrado na Figura 4-4. Como você está executando-o em um contêiner, se você adicionar uma dependência ao seu aplicativo, poderá incluir a dependência em sua imagem do Dockerfile ou do Docker.

Como também mostrado na Figura 4-4, o fluxo de publicação envia uma imagem através de um registry de contêineres. Pode ser o Registro de Contêiner do Azure (um registro próximo às suas implantações no Azure e protegido por grupos e contas do Azure Active Directory) ou qualquer outro registro do Docker, como o Hub do Docker ou um registro local.