O que é Cloud Native?

Gorjeta

Este conteúdo é um excerto do eBook, Architecting Cloud Native .NET Applications for Azure, disponível no .NET Docs ou como um PDF transferível gratuito que pode ser lido offline.

Miniatura da capa dos aplicativos .NET nativos da nuvem para eBook do Azure.

Pare o que está a fazer e peça aos seus colegas que definam o termo "Cloud Native". Há uma boa chance de você obter várias respostas diferentes.

Vamos começar com uma definição simples:

A arquitetura e as tecnologias nativas da nuvem são uma abordagem para projetar, construir e operar cargas de trabalho que são construídas na nuvem e aproveitam ao máximo o modelo de computação em nuvem.

A Cloud Native Computing Foundation fornece a definição oficial:

As tecnologias nativas da nuvem permitem que as organizações criem e executem aplicativos escaláveis em ambientes modernos e dinâmicos, como nuvens públicas, privadas e híbridas. Contêineres, malhas de serviço, microsserviços, infraestrutura imutável e APIs declarativas exemplificam essa abordagem.

Essas técnicas permitem sistemas de acoplamento flexível que são resilientes, gerenciáveis e observáveis. Combinadas com automação robusta, elas permitem que os engenheiros façam mudanças de alto impacto com frequência e de forma previsível com o mínimo de trabalho.

Cloud native é sobre velocidade e agilidade. Os sistemas de negócios estão evoluindo de capacitar capacidades de negócios para armas de transformação estratégica que aceleram a velocidade e o crescimento dos negócios. É imperativo colocar novas ideias no mercado imediatamente.

Ao mesmo tempo, os sistemas empresariais também se tornaram cada vez mais complexos, com os utilizadores a exigirem mais. Eles esperam resposta rápida, recursos inovadores e zero tempo de inatividade. Problemas de desempenho, erros recorrentes e a incapacidade de se mover rapidamente não são mais aceitáveis. Seus usuários visitarão seu concorrente. Os sistemas nativos da nuvem são projetados para abraçar mudanças rápidas, grande escala e resiliência.

Aqui estão algumas empresas que implementaram técnicas nativas da nuvem. Pense na velocidade, agilidade e escalabilidade que eles alcançaram.

Empresa Experiência
Netflix Tem 600+ serviços em produção. Implanta 100 vezes por dia.
Uber Tem 1.000+ serviços em produção. Implanta milhares de vezes por semana.
WeChat Tem 3.000+ serviços em produção. Implanta 1.000 vezes por dia.

Como você pode ver, Netflix, Uber e WeChat expõem sistemas nativos da nuvem que consistem em muitos serviços independentes. Este estilo arquitetónico permite-lhes responder rapidamente às condições do mercado. Eles atualizam instantaneamente pequenas áreas de um aplicativo dinâmico e complexo, sem uma reimplantação completa. Eles escalam individualmente os serviços conforme necessário.

Os pilares da nuvem nativa

A velocidade e a agilidade da nuvem nativa derivam de muitos fatores. O principal é a infraestrutura em nuvem. Mas há mais: cinco outros pilares fundamentais mostrados na Figura 1-3 também fornecem a base para sistemas nativos da nuvem.

Pilares fundamentais nativos da nuvem

Figura 1-3. Pilares fundamentais nativos da nuvem

Vamos dedicar algum tempo para entender melhor o significado de cada pilar.

Cloud

Os sistemas nativos da nuvem tiram o máximo partido do modelo de serviço na nuvem.

Projetados para prosperar em um ambiente de nuvem dinâmico e virtualizado, esses sistemas fazem uso extensivo da infraestrutura de computação e serviços gerenciados da Plataforma como Serviço (PaaS ). Eles tratam a infraestrutura subjacente como descartável - provisionada em minutos e redimensionada, dimensionada ou destruída sob demanda - por meio da automação.

Considere a diferença entre a forma como tratamos os animais de estimação e as mercadorias. Em um data center tradicional, os servidores são tratados como animais de estimação: uma máquina física, que recebe um nome significativo e é cuidada. Você dimensiona adicionando mais recursos à mesma máquina (escalonamento). Se o servidor ficar doente, você cuida dele de volta à saúde. Se o servidor ficar indisponível, todos percebem.

O modelo de serviço de commodities é diferente. Você provisiona cada instância como uma máquina virtual ou contêiner. Eles são idênticos e recebem um identificador de sistema, como Service-01, Service-02 e assim por diante. Você dimensiona criando mais instâncias (dimensionamento). Ninguém percebe quando uma instância fica indisponível.

O modelo de commodities abraça a infraestrutura imutável. Os servidores não são reparados ou modificados. Se um falhar ou precisar de atualização, ele é destruído e um novo é provisionado – tudo feito por meio de automação.

Os sistemas nativos da nuvem adotam o modelo de serviços de commodities. Eles continuam a funcionar à medida que a infraestrutura entra ou sai, sem levar em conta as máquinas nas quais eles estão sendo executados.

A plataforma de nuvem do Azure dá suporte a esse tipo de infraestrutura altamente elástica com recursos automáticos de dimensionamento, autorrecuperação e monitoramento.

Design moderno

Como você projetaria um aplicativo nativo da nuvem? Como seria a sua arquitetura? A que princípios, padrões e melhores práticas você aderiria? Que preocupações operacionais e de infraestruturas seriam importantes?

A Aplicação dos Doze Fatores

Uma metodologia amplamente aceita para a construção de aplicativos baseados em nuvem é o aplicativo de doze fatores. Ele descreve um conjunto de princípios e práticas que os desenvolvedores seguem para construir aplicativos otimizados para ambientes de nuvem modernos. É dada especial atenção à portabilidade entre ambientes e à automatização declarativa.

Embora aplicável a qualquer aplicativo baseado na Web, muitos profissionais consideram o Twelve-Factor uma base sólida para a criação de aplicativos nativos da nuvem. Os sistemas baseados nesses princípios podem ser implantados e dimensionados rapidamente e adicionar recursos para reagir rapidamente às mudanças do mercado.

A tabela a seguir destaca a metodologia dos doze fatores:

Fator Explicação
1 - Base de Código Uma única base de código para cada microsserviço, armazenada em seu próprio repositório. Rastreado com controle de versão, ele pode ser implantado em vários ambientes (QA, Preparo, Produção).
2 - Dependências Cada microsserviço isola e empacota suas próprias dependências, abraçando mudanças sem afetar todo o sistema.
3 - Configurações As informações de configuração são movidas para fora do microsserviço e externalizadas por meio de uma ferramenta de gerenciamento de configuração fora do código. A mesma implantação pode se propagar entre ambientes com a configuração correta aplicada.
4 - Serviços de Apoio Recursos auxiliares (armazenamentos de dados, caches, agentes de mensagens) devem ser expostos por meio de uma URL endereçável. Isso separa o recurso do aplicativo, permitindo que ele seja intercambiável.
5 - Construir, Liberar, Executar Cada versão deve impor uma separação rigorosa entre os estágios de compilação, liberação e execução. Cada um deve ser marcado com um ID exclusivo e suportar a capacidade de reverter. Os modernos sistemas de CI/CD ajudam a cumprir este princípio.
6 - Processos Cada microsserviço deve ser executado em seu próprio processo, isolado de outros serviços em execução. Externalize o estado necessário para um serviço de backup, como um cache distribuído ou armazenamento de dados.
7 - Encadernação de portas Cada microsserviço deve ser independente, com suas interfaces e funcionalidades expostas em sua própria porta. Isso proporciona isolamento de outros microsserviços.
8 - Simultaneidade Quando a capacidade precisar aumentar, dimensione os serviços horizontalmente em vários processos idênticos (cópias), em vez de expandir uma única instância grande na máquina mais poderosa disponível. Desenvolva o aplicativo para ser simultâneo, tornando o escalonamento em ambientes de nuvem perfeito.
9 - Descartabilidade As instâncias de serviço devem ser descartáveis. Favoreça a inicialização rápida para aumentar as oportunidades de escalabilidade e desligamentos graciosos para deixar o sistema em um estado correto. Os contêineres do Docker, juntamente com um orquestrador, satisfazem inerentemente esse requisito.
10 - Paridade Dev/Prod Mantenha os ambientes em todo o ciclo de vida do aplicativo o mais semelhantes possível, evitando atalhos caros. Aqui, a adoção de containers pode contribuir muito, promovendo o mesmo ambiente de execução.
11 - Exploração madeireira Trate os logs gerados por microsserviços como fluxos de eventos. Processe-os com um agregador de eventos. Propagar dados de log para ferramentas de gerenciamento de dados/mineração de logs, como o Azure Monitor ou o Splunk e, eventualmente, para arquivamento de longo prazo.
12 - Processos Administrativos Execute tarefas administrativas/de gerenciamento, como limpeza de dados ou análise de computação, como processos únicos. Use ferramentas independentes para invocar essas tarefas do ambiente de produção, mas separadamente do aplicativo.

No livro, Beyond the Twelve-Factor App, o autor Kevin Hoffman detalha cada um dos 12 fatores originais (escrito em 2011). Além disso, ele discute três fatores extras que refletem o design moderno de aplicativos em nuvem de hoje.

Novo fator Explicação
13 - API em primeiro lugar Faça de tudo um serviço. Suponha que seu código será consumido por um cliente front-end, gateway ou outro serviço.
14 - Telemetria Em uma estação de trabalho, você tem uma visibilidade profunda do seu aplicativo e seu comportamento. Na nuvem, não. Certifique-se de que seu design inclua a coleta de dados de monitoramento, específicos do domínio e de integridade/sistema.
15 - Autenticação/ Autorização Implemente a identidade desde o início. Considere os recursos RBAC (controle de acesso baseado em função) disponíveis em nuvens públicas.

Referir-nos-emos a muitos dos 12+ fatores neste capítulo e ao longo do livro.

Well-Architected Framework do Azure

Projetar e implantar cargas de trabalho baseadas em nuvem pode ser um desafio, especialmente ao implementar a arquitetura nativa da nuvem. A Microsoft fornece práticas recomendadas padrão do setor para ajudar você e sua equipe a fornecer soluções de nuvem robustas.

O Microsoft Well-Architected Framework fornece um conjunto de princípios orientadores que podem ser usados para melhorar a qualidade de uma carga de trabalho nativa da nuvem. O framework consiste em cinco pilares de excelência em arquitetura:

Princípios Description
Gestão de custos Concentre-se em gerar valor incremental antecipadamente. Aplique os princípios Build-Measure-Learn para acelerar o tempo de entrada no mercado e, ao mesmo tempo, evitar soluções intensivas em capital. Usando uma estratégia de pagamento conforme o uso, invista à medida que expande, em vez de entregar um grande investimento antecipadamente.
Excelência operacional Automatize o ambiente e as operações para aumentar a velocidade e reduzir o erro humano. Reverta as atualizações de problemas para trás ou para a frente rapidamente. Implemente monitoramento e diagnóstico desde o início.
Eficiência do desempenho Atenda com eficiência às demandas impostas às suas cargas de trabalho. Favoreça o dimensionamento horizontal (dimensionamento) e projete-o em seus sistemas. Realize continuamente testes de desempenho e carga para identificar possíveis gargalos.
Fiabilidade Crie cargas de trabalho resilientes e disponíveis. A resiliência permite que as cargas de trabalho se recuperem de falhas e continuem funcionando. A disponibilidade garante aos usuários acesso à sua carga de trabalho em todos os momentos. Projete aplicativos para esperar falhas e se recuperar delas.
Segurança Implemente a segurança em todo o ciclo de vida de um aplicativo, desde o projeto e a implementação até a implantação e as operações. Preste muita atenção ao gerenciamento de identidades, acesso à infraestrutura, segurança de aplicativos e soberania e criptografia de dados.

Para começar, a Microsoft fornece um conjunto de avaliações online para ajudá-lo a avaliar suas cargas de trabalho atuais na nuvem em relação aos cinco pilares bem arquitetados.

Microsserviços

Os sistemas nativos da nuvem adotam microsserviços, um estilo arquitetônico popular para a construção de aplicativos modernos.

Criados como um conjunto distribuído de serviços pequenos e independentes que interagem por meio de uma malha compartilhada, os microsserviços compartilham as seguintes características:

  • Cada um implementa um recurso de negócios específico dentro de um contexto de domínio maior.

  • Cada um é desenvolvido de forma autónoma e pode ser implementado de forma independente.

  • Cada um é autônomo encapsulando sua própria tecnologia de armazenamento de dados, dependências e plataforma de programação.

  • Cada um é executado em seu próprio processo e se comunica com outros usando protocolos de comunicação padrão, como HTTP/HTTPS, gRPC, WebSockets ou AMQP.

  • Eles compõem juntos para formar uma candidatura.

A Figura 1-4 contrasta uma abordagem de aplicativo monolítico com uma abordagem de microsserviços. Observe como o monólito é composto por uma arquitetura em camadas, que é executada em um único processo. Normalmente, consome um banco de dados relacional. A abordagem de microsserviço, no entanto, segrega a funcionalidade em serviços independentes, cada um com sua própria lógica, estado e dados. Cada microsserviço hospeda seu próprio armazenamento de dados.

Implantação monolítica versus microsserviços

Figura 1-4. Arquitetura monolítica versus arquitetura de microsserviços

Observe como os microsserviços promovem o princípio de Processos a partir do Aplicativo de Doze Fatores, discutido anteriormente no capítulo.

O fator #6 especifica "Cada microsserviço deve ser executado em seu próprio processo, isolado de outros serviços em execução."

Porquê microsserviços?

Os microsserviços proporcionam agilidade.

No início do capítulo, comparamos um aplicativo de comércio eletrônico construído como um monólito com o de microsserviços. No exemplo, vimos alguns benefícios claros:

  • Cada microsserviço tem um ciclo de vida autônomo e pode evoluir de forma independente e ser implantado com frequência. Você não precisa esperar por uma versão trimestral para implantar um novo recurso ou atualização. Você pode atualizar uma pequena área de um aplicativo ativo com menos risco de interromper todo o sistema. A atualização pode ser feita sem uma reimplantação completa do aplicativo.

  • Cada microsserviço pode ser dimensionado de forma independente. Em vez de dimensionar todo o aplicativo como uma única unidade, você dimensiona apenas os serviços que exigem mais poder de processamento para atender aos níveis de desempenho desejados e aos contratos de nível de serviço. O dimensionamento refinado proporciona maior controle do sistema e ajuda a reduzir os custos gerais à medida que você dimensiona partes do sistema, não tudo.

Um excelente guia de referência para entender os microsserviços é o .NET Microservices: Architecture for Containerized .NET Applications. O livro mergulha profundamente no design e arquitetura de microsserviços. É um complemento para uma arquitetura de referência de microsserviço full-stack disponível para download gratuito da Microsoft.

Desenvolvimento de microsserviços

Os microsserviços podem ser criados em qualquer plataforma de desenvolvimento moderna.

A plataforma Microsoft .NET é uma excelente escolha. Gratuito e de código aberto, tem muitos recursos integrados que simplificam o desenvolvimento de microsserviços. O .NET é multiplataforma. Os aplicativos podem ser criados e executados no Windows, macOS e na maioria dos tipos de Linux.

O .NET tem alto desempenho e obteve bons resultados em comparação com a Node.js e outras plataformas concorrentes. Curiosamente, o TechEmpower conduziu um extenso conjunto de benchmarks de desempenho em muitas plataformas e estruturas de aplicações web. O .NET pontuou no top 10 - bem acima da Node.js e de outras plataformas concorrentes.

O .NET é mantido pela Microsoft e pela comunidade .NET no GitHub.

Desafios do microsserviço

Embora os microsserviços distribuídos nativos da nuvem possam fornecer imensa agilidade e velocidade, eles apresentam muitos desafios:

Comunicação

Como os aplicativos cliente front-end se comunicarão com os microsserviços principais de backed-end? Vai permitir a comunicação direta? Ou você poderia abstrair os microsserviços de back-end com uma fachada de gateway que fornece flexibilidade, controle e segurança?

Como os microsserviços principais de back-end se comunicarão entre si? Você permitirá chamadas HTTP diretas que podem aumentar o acoplamento e afetar o desempenho e a agilidade? Ou você pode considerar mensagens dissociadas com tecnologias de fila e tópico?

A comunicação é abordada no capítulo Padrões de comunicação nativos da nuvem.

Resiliência

Uma arquitetura de microsserviços move seu sistema de comunicação de rede em processo para fora de processo. Em uma arquitetura distribuída, o que acontece quando o Serviço B não está respondendo a uma chamada de rede do Serviço A? Ou, o que acontece quando o Serviço C fica temporariamente indisponível e outros serviços que o chamam ficam bloqueados?

A resiliência é abordada no capítulo de resiliência nativa da nuvem.

Dados distribuídos

Por design, cada microsserviço encapsula seus próprios dados, expondo operações por meio de sua interface pública. Em caso afirmativo, como consultar dados ou implementar uma transação em vários serviços?

Os dados distribuídos são abordados no capítulo Padrões de dados nativos da nuvem.

Segredos

Como seus microsserviços armazenarão e gerenciarão segredos e dados de configuração confidenciais com segurança?

Os segredos são abordados em detalhes Segurança nativa da nuvem.

Gerencie a complexidade com o Dapr

Dapr é um tempo de execução de aplicativo distribuído e de código aberto. Através de uma arquitetura de componentes conectáveis, simplifica drasticamente o encanamento por trás de aplicativos distribuídos. Ele fornece uma cola dinâmica que vincula seu aplicativo com recursos de infraestrutura pré-criados e componentes do tempo de execução do Dapr. A Figura 1-5 mostra Dapr a partir de 20.000 pés.

Dapr a 20.000 pésFigura 1-5. Dapr a 20.000 pés.

Na linha superior da figura, observe como o Dapr fornece SDKs específicos de linguagem para plataformas de desenvolvimento populares. O Dapr v1 inclui suporte para .NET, Go, Node.js, Python, PHP, Java e JavaScript.

Enquanto SDKs específicos de idioma melhoram a experiência do desenvolvedor, o Dapr é independente da plataforma. Sob o capô, o modelo de programação do Dapr expõe recursos por meio de protocolos de comunicação HTTP/gRPC padrão. Qualquer plataforma de programação pode chamar Dapr por meio de suas APIs HTTP e gRPC nativas.

As caixas azuis no centro da figura representam os blocos de construção do Dapr. Cada um expõe o código de encanamento pré-criado para um recurso de aplicativo distribuído que seu aplicativo pode consumir.

A linha de componentes representa um grande conjunto de componentes de infraestrutura predefinidos que seu aplicativo pode consumir. Pense em componentes como código de infraestrutura que você não precisa escrever.

A linha inferior destaca a portabilidade do Dapr e os diversos ambientes nos quais ele pode ser executado.

Olhando para o futuro, o Dapr tem o potencial de ter um impacto profundo no desenvolvimento de aplicativos nativos da nuvem.

Contentores

É natural ouvir o termo container mencionado em qualquer conversa nativa da nuvem. No livro, Cloud Native Patterns, a autora Cornelia Davis observa que "os contêineres são um grande facilitador de software nativo da nuvem". A Cloud Native Computing Foundation coloca a conteinerização de microsserviços como o primeiro passo em seu Cloud Native Trail Map - orientação para empresas que estão começando sua jornada nativa da nuvem.

A contentorização de um microsserviço é simples e direta. O código, suas dependências e tempo de execução são empacotados em um binário chamado imagem de contêiner. As imagens são armazenadas em um registro de contêiner, que atua como um repositório ou biblioteca de imagens. Um registro pode ser localizado em seu computador de desenvolvimento, em seu data center ou em uma nuvem pública. O próprio Docker mantém um registro público via Docker Hub. A nuvem do Azure apresenta um registo de contentor privado para armazenar imagens de contentor perto das aplicações na nuvem que as irão executar.

Quando um aplicativo é iniciado ou dimensionado, você transforma a imagem do contêiner em uma instância de contêiner em execução. A instância é executada em qualquer computador que tenha um mecanismo de tempo de execução de contêiner instalado. Você pode ter quantas instâncias do serviço conteinerizado forem necessárias.

A Figura 1-6 mostra três microsserviços diferentes, cada um em seu próprio contêiner, todos executados em um único host.

Vários contêineres em execução em um host de contêiner

Figura 1-6. Vários contêineres em execução em um host de contêiner

Observe como cada contêiner mantém seu próprio conjunto de dependências e tempo de execução, que podem ser diferentes entre si. Aqui, vemos diferentes versões do microsserviço do produto em execução no mesmo host. Cada contêiner compartilha uma fatia do sistema operacional do host subjacente, da memória e do processador, mas é isolado um do outro.

Observe como o modelo de contêiner adota o princípio de dependências do aplicativo de doze fatores.

O fator #2 especifica que "Cada microsserviço isola e empacota suas próprias dependências, abraçando alterações sem afetar todo o sistema."

Os contêineres suportam cargas de trabalho Linux e Windows. A nuvem do Azure abraça abertamente ambos. Curiosamente, é o Linux, não o Windows Server, que se tornou o sistema operacional mais popular no Azure.

Embora existam vários fornecedores de contêineres, o Docker conquistou a maior parte do mercado. A empresa tem impulsionado o movimento de contêineres de software. Tornou-se o padrão de facto para empacotar, implementar e executar aplicações nativas da nuvem.

Porquê contentores?

Os contêineres oferecem portabilidade e garantem consistência entre ambientes. Ao encapsular tudo em um único pacote, você isola o microsserviço e suas dependências da infraestrutura subjacente.

Você pode implantar o contêiner em qualquer ambiente que hospede o mecanismo de tempo de execução do Docker. As cargas de trabalho em contêineres também eliminam a despesa de pré-configuração de cada ambiente com estruturas, bibliotecas de software e mecanismos de tempo de execução.

Ao compartilhar o sistema operacional subjacente e os recursos do host, um contêiner tem um espaço muito menor do que uma máquina virtual completa. O tamanho menor aumenta a densidade, ou o número de microsserviços, que um determinado host pode executar ao mesmo tempo.

Orquestração de contentores

Embora ferramentas como o Docker criem imagens e executem contêineres, você também precisa de ferramentas para gerenciá-las. O gerenciamento de contêineres é feito com um programa de software especial chamado orquestrador de contêineres. Ao operar em escala com muitos contêineres independentes, a orquestração é essencial.

A Figura 1-7 mostra as tarefas de gerenciamento que os orquestradores de contêineres automatizam.

O que fazem os orquestradores de contentores

Figura 1-7. O que fazem os orquestradores de contentores

A tabela a seguir descreve tarefas comuns de orquestração.

Tarefas Explicação
A agendar Provisione automaticamente instâncias de contêiner.
Afinidade/anti-afinidade Provisione contêineres próximos ou distantes uns dos outros, ajudando na disponibilidade e no desempenho.
Monitorização do estado de funcionamento Detete e corrija falhas automaticamente.
Ativação pós-falha Reprovisione automaticamente uma instância com falha para uma máquina íntegra.
Dimensionamento Adicione ou remova automaticamente uma instância de contêiner para atender à demanda.
Rede Gerencie uma sobreposição de rede para comunicação de contêiner.
Deteção de Serviço Permita que os contêineres se localizem uns aos outros.
Atualizações contínuas Coordene atualizações incrementais com implantação sem tempo de inatividade. Reverter automaticamente alterações problemáticas.

Observe como os orquestradores de contêineres adotam os princípios de Descartabilidade e Simultaneidade do Aplicativo de Doze Fatores.

O fator #9 especifica que "as instâncias de serviço devem ser descartáveis, favorecendo startups rápidas para aumentar as oportunidades de escalabilidade e desligamentos graciosos para deixar o sistema em um estado correto." Os contêineres Docker, juntamente com um orquestrador, satisfazem inerentemente esse requisito."

O fator #8 especifica que "Os serviços são dimensionados em um grande número de pequenos processos idênticos (cópias), em vez de expandir uma única instância grande na máquina mais poderosa disponível."

Embora existam vários orquestradores de contêineres, o Kubernetes tornou-se o padrão de fato para o mundo nativo da nuvem. É uma plataforma portátil, extensível e de código aberto para gerenciar cargas de trabalho em contêineres.

Você poderia hospedar sua própria instância do Kubernetes, mas seria responsável pelo provisionamento e gerenciamento de seus recursos - o que pode ser complexo. A nuvem do Azure apresenta o Kubernetes como um serviço gerenciado. O Azure Kubernetes Service (AKS) e o Azure Red Hat OpenShift (ARO) permitem que você aproveite totalmente os recursos e o poder do Kubernetes como um serviço gerenciado, sem precisar instalá-lo e mantê-lo.

A orquestração de contêineres é abordada em detalhes em Scaling Cloud-Native Applications.

Serviços de apoio

Os sistemas nativos da nuvem dependem de muitos recursos auxiliares diferentes, como armazenamentos de dados, agentes de mensagens, monitoramento e serviços de identidade. Esses serviços são conhecidos como serviços de suporte.

A Figura 1-8 mostra muitos serviços de suporte comuns que os sistemas nativos da nuvem consomem.

Serviços de apoio comuns

Figura 1-8. Serviços de apoio comuns

Você poderia hospedar seus próprios serviços de suporte, mas seria responsável pelo licenciamento, provisionamento e gerenciamento desses recursos.

Os provedores de nuvem oferecem uma ampla variedade de serviços de suporte gerenciados. Em vez de possuir o serviço, você simplesmente o consome. O provedor de nuvem opera o recurso em escala e assume a responsabilidade pelo desempenho, segurança e manutenção. Monitoramento, redundância e disponibilidade são incorporados ao serviço. Os fornecedores garantem o desempenho do nível de serviço e suportam totalmente os seus serviços geridos - abra um ticket e corrige o seu problema.

Os sistemas nativos da nuvem favorecem os serviços de suporte gerenciado de fornecedores de nuvem. A economia de tempo e mão de obra pode ser significativa. O risco operacional de hospedar o seu próprio e ter problemas pode ficar caro rapidamente.

Uma prática recomendada é tratar um serviço de suporte como um recurso anexado, vinculado dinamicamente a um microsserviço com informações de configuração (uma URL e credenciais) armazenadas em uma configuração externa. Esta orientação é explicitada na Aplicação de Doze Fatores, discutida anteriormente no capítulo.

O fator #4 especifica que os serviços de suporte "devem ser expostos por meio de uma URL endereçável. Isso separa o recurso do aplicativo, permitindo que ele seja intercambiável."

O fator #3 especifica que "As informações de configuração são movidas para fora do microsserviço e externalizadas por meio de uma ferramenta de gerenciamento de configuração fora do código".

Com esse padrão, um serviço de suporte pode ser anexado e desanexado sem alterações de código. Você pode promover um microsserviço do controle de qualidade para um ambiente de preparação. Você atualiza a configuração do microsserviço para apontar para os serviços de backup em preparo e injeta as configurações em seu contêiner por meio de uma variável de ambiente.

Os fornecedores de nuvem fornecem APIs para você se comunicar com seus serviços de suporte proprietários. Essas bibliotecas encapsulam o encanamento proprietário e a complexidade. No entanto, a comunicação direta com essas APIs acoplará seu código a esse serviço de suporte específico. É uma prática amplamente aceita isolar os detalhes de implementação da API do fornecedor. Introduza uma camada de intermediação, ou API intermediária, expondo operações genéricas ao seu código de serviço e envolva o código do fornecedor dentro dele. Esse acoplamento flexível permite que você troque um serviço de suporte por outro ou mova seu código para um ambiente de nuvem diferente sem ter que fazer alterações no código do serviço principal. Dapr, discutido anteriormente, segue este modelo com seu conjunto de blocos de construção pré-construídos.

Em uma consideração final, os serviços de apoio também promovem o princípio da apatridia a partir da Aplicação de Doze Fatores, discutida anteriormente no capítulo.

O fator #6 especifica que, "Cada microsserviço deve ser executado em seu próprio processo, isolado de outros serviços em execução. Externalize o estado necessário para um serviço de backup, como um cache distribuído ou armazenamento de dados."

Os serviços de suporte são discutidos em padrões de dados nativos da nuvem e padrões de comunicação nativos da nuvem.

Automatização

Como você viu, os sistemas nativos da nuvem adotam microsserviços, contêineres e design de sistema moderno para alcançar velocidade e agilidade. Mas isso é apenas parte da história. Como você provisiona os ambientes de nuvem nos quais esses sistemas são executados? Como implantar rapidamente recursos e atualizações de aplicativos? Como se completa o quadro completo?

Entre na prática amplamente aceita de Infraestrutura como Código, ou IaC.

Com o IaC, você automatiza o provisionamento de plataforma e a implantação de aplicativos. Você essencialmente aplica práticas de engenharia de software, como testes e controle de versão, às suas práticas de DevOps. Sua infraestrutura e implantações são automatizadas, consistentes e repetíveis.

Automatizando a infraestrutura

Ferramentas como o Azure Resource Manager, o Azure Bicep, o Terraform da HashiCorp e a CLI do Azure permitem que você crie scripts declarativos da infraestrutura de nuvem necessária. Nomes de recursos, locais, capacidades e segredos são parametrizados e dinâmicos. O script é versionado e verificado no controle do código-fonte como um artefato do seu projeto. Você invoca o script para provisionar uma infraestrutura consistente e repetível em ambientes de sistema, como controle de qualidade, preparo e produção.

Sob o capô, o IaC é idempotente, o que significa que você pode executar o mesmo script repetidamente sem efeitos colaterais. Se a equipe precisar fazer uma alteração, editará e executará novamente o script. Apenas os recursos atualizados são afetados.

No artigo, What is Infrastructure as Code, o autor Sam Guckenheimer descreve como, "As equipes que implementam o IaC podem fornecer ambientes estáveis rapidamente e em escala. Eles evitam a configuração manual de ambientes e impõem consistência representando o estado desejado de seus ambientes via código. As implementações de infraestruturas com IaC são repetíveis e evitam problemas de runtime causados por desfasamento da configuração ou dependências em falta. As equipes de DevOps podem trabalhar em conjunto com um conjunto unificado de práticas e ferramentas para fornecer aplicativos e sua infraestrutura de suporte de forma rápida, confiável e em escala."

Automatizando implantações

O Aplicativo de Doze Fatores, discutido anteriormente, exige etapas separadas ao transformar o código concluído em um aplicativo em execução.

O fator #5 especifica que "Cada versão deve impor uma separação estrita entre os estágios de compilação, liberação e execução. Cada um deve ser marcado com um ID exclusivo e apoiar a capacidade de reverter."

Os modernos sistemas de CI/CD ajudam a cumprir este princípio. Eles fornecem etapas separadas de compilação e entrega que ajudam a garantir um código consistente e de qualidade prontamente disponível para os usuários.

A Figura 1-9 mostra a separação entre o processo de implantação.

Etapas de implantações no pipeline de CI/CD

Figura 1-9. Etapas de implantação em um pipeline de CI/CD

Na figura anterior, preste especial atenção à separação de tarefas:

  1. O desenvolvedor constrói um recurso em seu ambiente de desenvolvimento, iterando através do que é chamado de "loop interno" de código, execução e depuração.
  2. Quando concluído, esse código é enviado por push para um repositório de código, como GitHub, Azure DevOps ou BitBucket.
  3. O push dispara um estágio de compilação que transforma o código em um artefato binário. O trabalho é implementado com um pipeline de Integração Contínua (CI ). Ele cria, testa e empacota automaticamente o aplicativo.
  4. O estágio de liberação pega o artefato binário, aplica informações de configuração de aplicativo e ambiente externos e produz uma versão imutável. A versão é implantada em um ambiente especificado. O trabalho é implementado com um pipeline de Entrega Contínua (CD). Cada libertação deve ser identificável. Você pode dizer: "Esta implantação está executando a versão 2.1.1 do aplicativo."
  5. Finalmente, o recurso liberado é executado no ambiente de execução de destino. As versões são imutáveis, o que significa que qualquer alteração deve criar uma nova versão.

Aplicando essas práticas, as organizações evoluíram radicalmente na forma como enviam software. Muitos passaram de lançamentos trimestrais para atualizações sob demanda. O objetivo é detetar problemas no início do ciclo de desenvolvimento, quando eles são menos dispendiosos para corrigir. Quanto maior a duração entre as integrações, mais caro se torna a resolução dos problemas. Com consistência no processo de integração, as equipes podem confirmar alterações de código com mais frequência, levando a uma melhor colaboração e qualidade de software.

A infraestrutura como automação de código e implantação, juntamente com o GitHub e o Azure DevOps são discutidos em detalhes no DevOps.