Práticas recomendadas para conectar serviços do Amazon ECS em uma VPC
Usando tarefas do Amazon ECS em uma VPC, é possível dividir aplicações monolíticas em partes separadas que podem ser implantadas e escaladas de forma independente em um ambiente seguro. Essa arquitetura é chamada de arquitetura orientada a serviços (SOA) ou microsserviços. No entanto, pode ser difícil garantir que todas essas partes, dentro e fora de uma VPC, possam se comunicar umas com as outras. Há várias abordagens para facilitar a comunicação, todas com vantagens e desvantagens diferentes.
Usar o Service Connect
Recomendamos o Service Connect, que fornece a configuração do Amazon ECS para descoberta de serviços, conectividade e monitoramento de tráfego. Com o Service Connect, as aplicações podem usar nomes curtos e portas padrão para se conectar a serviços no mesmo cluster e em outros clusters, inclusive entre VPCs na mesma região. Para obter mais informações, consulte Amazon ECS Service Connect.
Ao usar o Service Connect, o Amazon ECS gerencia todas as partes da descoberta de serviços: criar os nomes que podem ser descobertos, gerenciar dinamicamente as entradas de cada tarefa à medida que as tarefas começam e são interrompidas, executar um agente em cada tarefa configurada para descobrir os nomes. Sua aplicação pode pesquisar os nomes usando a funcionalidade padrão para nomes do DNS e fazendo conexões. Caso a aplicação já faça isso, não será necessário modificá-la para usar o Service Connect.
As mudanças só acontecem durante as implantações
Você fornece a configuração completa dentro de cada serviço e definição de tarefa. O Amazon ECS gerencia as alterações nessa configuração em cada implantação de serviço, para garantir que todas as tarefas em uma implantação se comportem da mesma maneira. Por exemplo, um problema comum do DNS como descoberta de serviços é controlar uma migração. Se você alterar um nome do DNS de modo a direcionar para os novos endereços IP substitutos, poderá levar o tempo máximo de TTL antes que todos os clientes comecem a usar o novo serviço. Com o Service Connect, a implantação do cliente atualiza a configuração substituindo as tarefas do cliente. Você pode configurar o disjuntor de implantação e outras configurações de implantação para afetar as alterações do Service Connect da mesma forma que qualquer outra implantação.
Usar descoberta de serviços
Outra abordagem para a comunicação entre serviços é a comunicação direta por meio da descoberta de serviços. Nessa abordagem, você pode usar a integração da descoberta de serviços do AWS Cloud Map com o Amazon ECS. Usando a descoberta de serviços, o Amazon ECS sincroniza a lista de tarefas executadas com o AWS Cloud Map, que mantém um nome de host do DNS que resolve os endereços IP internos de uma ou mais tarefas desse serviço específico. Outros serviços na Amazon VPC podem usar esse nome de host do DNS para enviar tráfego diretamente a outro contêiner usando o endereço IP interno. Para obter mais informações, consulte Descoberta de serviços.
No diagrama anterior, há três serviços. service-a-local
tem um contêiner e se comunica com service-b-local
, que tem dois contêineres. service-b-local
também deve se comunicar com service-c-local
, que tem um contêiner. Cada contêiner em todos esses três serviços pode usar os nomes DNS internos de AWS Cloud Map para encontrar os endereços IP internos de um contêiner do serviço downstream com o qual ele precisa se comunicar.
Essa abordagem de comunicação entre serviços fornece baixa latência. À primeira vista, também é simples, pois não há componentes extras entre os contêineres. O tráfego viaja diretamente de um contêiner para o outro.
Essa abordagem é adequada ao usar o modo de rede awsvpc
, em que cada tarefa tem seu próprio endereço IP exclusivo. A maioria dos softwares é compatível apenas com o uso de registros A
do DNS, que resolvem diretamente os endereços IP. Ao usar o modo de rede awsvpc
, o endereço IP de cada tarefa é um registro A
. No entanto, se você estiver usando o modo de rede bridge
, vários contêineres podem estar compartilhando o mesmo endereço IP. Além disso, os mapeamentos dinâmicos de portas fazem com que os contêineres recebam números de porta aleatoriamente nesse único endereço IP. A essa altura, um registro A
não é mais suficiente para a descoberta de serviços. Você também deve usar um registro SRV
. Esse tipo de registro pode rastrear endereços IP e números de porta, mas exige que você configure as aplicações adequadamente. Algumas aplicações pré-criadas que você usa podem não oferecer suporte a registros SRV
.
Outra vantagem do modo de rede awsvpc
é ter um grupo de segurança exclusivo para cada serviço. Você pode configurar esse grupo de segurança para permitir conexões de entrada somente dos serviços upstream específicos que precisam se comunicar com esse serviço.
A principal desvantagem da comunicação direta entre serviços usando a descoberta de serviços é que você deve implementar uma lógica extra para ter repetições e lidar com falhas de conexão. Os registros DNS têm um período de vida útil (TTL) que controla por quanto tempo são armazenados em cache. Leva algum tempo para que o registro DNS seja atualizado e o cache expire para que as aplicações possam obter a versão mais recente do registro DNS. Portanto, sua aplicação pode acabar resolvendo o registro DNS de modo a direcionar para outro contêiner que não está mais lá. A aplicação precisa processar repetições e ter uma lógica para ignorar backends problemáticos.
Usar um balanceador de carga interno
Outra abordagem à comunicação entre serviços é usar um balanceador de carga interno. Um balanceador de carga interno existe inteiramente dentro da sua VPC e só pode ser acessado por serviços dentro dela.
O balanceador de carga mantém a alta disponibilidade implantando recursos redundantes em cada sub-rede. Quando um contêiner de serviceA
precisa se comunicar com um contêiner de serviceB
, ele abre uma conexão para o balanceador de carga. O balanceador de carga então abre uma conexão para um contêiner a partir de service B
. O balanceador de carga serve como um local centralizado para gerenciar todas as conexões entre cada serviço.
Se um contêiner de serviceB
parar, o balanceador de carga poderá remover esse contêiner do grupo. O balanceador de carga também faz verificações de integridade em cada alvo downstream em seu grupo e pode remover automaticamente os alvos ruins do grupo até que eles se tornem saudáveis novamente. As aplicações não precisam mais saber quantos contêineres downstream existem. Elas simplesmente abrem suas conexões para o balanceador de carga.
Essa abordagem é vantajosa para todos os modos de rede. O balanceador de carga pode acompanhar os endereços IP da tarefa ao usar o modo de rede awsvpc
, bem como combinações mais avançadas de endereços IP e portas ao usar o modo de rede bridge
. Ele distribui uniformemente o tráfego em todas as combinações de endereços IP e portas, mesmo que vários contêineres estejam realmente hospedados na mesma instância do Amazon EC2, mas apenas em portas diferentes.
A única desvantagem dessa abordagem é o custo. Para manter a alta disponibilidade, o balanceador de carga precisa ter recursos em cada zona de disponibilidade. Isso adiciona um custo extra devido à sobrecarga representada por pagar pelo balanceador de carga e pela quantidade de tráfego que passa pelo balanceador de carga.
No entanto, é possível reduzir os custos indiretos fazendo com que vários serviços compartilhem um balanceador de carga. Isso é particularmente adequado para serviços REST que usam um Application Load Balancer. É possível criar regras de roteamento baseadas em caminho que roteiam o tráfego para diferentes serviços. Por exemplo, /api/user/*
pode rotear para um contêiner que faz parte do serviço user
, enquanto /api/order/*
pode rotear para o serviço order
associado. Com essa abordagem, você paga apenas por um Application Load Balancer e tem um URL consistente para sua API. No entanto, é possível dividir o tráfego em vários microsserviços no backend.