Marcio Cunha

Como balancear carga em containers Docker com Nginx

Aprenda a configurar um proxy reverso com Nginx e balanceamento round-robin para distribuir o tráfego entre múltiplos containers Docker de forma simples.

Marcio Cunha•5 min
Também disponível em:EnglishEspañol
Resumo
  • O balanceamento de carga distribui requisições de rede entre várias instâncias para evitar sobrecarga em um único servidor.
  • O Nginx atua como proxy reverso, recebendo conexões externas e repassando para os containers de forma transparente.
  • A estratégia round-robin envia cada nova requisição para o próximo container da lista em um ciclo contínuo.
  • O Docker Compose simplifica a orquestração e a comunicação interna entre o Nginx e as aplicações na mesma rede.
  • Monitorar o uso de recursos dos containers garante que gargalotes de hardware não comprometam o serviço.

O desafio de distribuir tráfego em ambientes Docker

Quando uma aplicação web cresce e passa a receber milhares de acessos simultâneos, rodar tudo em um único container Docker deixa de ser viável. O gargalo de processamento e memória logo aparece, causando lentidão ou até quedas repentinas no serviço. Para resolver esse problema, a arquitetura moderna recorre à replicação, executando várias cópias idênticas da mesma aplicação isoladas em seus próprios containers. Na prática, isso significa que precisamos de um maestro para decidir qual cópia vai atender cada pessoa que acessa o site.

É exatamente aí que entra o conceito de proxy reverso e balanceador de carga. Um proxy reverso é um servidor que fica na linha de frente da rede, recebendo todas as solicitações dos usuários antes que elas cheguem aos servidores da aplicação. Em vez de expor diretamente as portas internas de cada container, o operador expõe apenas o Nginx para a internet. O Nginx absorve o impacto inicial do tráfego e decide para qual endereço interno a requisição deve ser encaminhada, garantindo segurança e organização à infraestrutura. Caso precise otimizar o consumo geral do ambiente, vale a pena conferir estratégias como limitar a memória de containers com Cgroups v2 para evitar que um único serviço roube recursos dos demais.

Como funciona o algoritmo de distribuição round-robin

Existem várias formas de dividir o trabalho entre os servidores disponíveis, mas a mais tradicional e simples é chamada de round-robin. Imagine uma fila indiana em que o atendente entrega a primeira senha para o caixa um, a segunda senha para o caixa dois, a terceira para o caixa três, e depois recomeça o ciclo no caixa um. O Nginx faz exatamente isso com as requisições HTTP que chegam à sua porta principal, alternando os destinos de forma sequencial e previsível entre todos os containers cadastrados no grupo de servidores.

Essa abordagem é altamente eficaz quando todos os containers possuem capacidades hardware equivalentes e executam tarefas de complexidade semelhante. Como o sistema não precisa calcular o peso ou a ocupação atual de cada nó em tempo real, o custo de processamento para tomar essa decisão é praticamente zero. Para manter esse ecossistema limpo e evitar que arquivos temporários loteem o disco do servidor hospedeiro, é recomendável manter uma rotina de manutenção, como limpar o cache do Docker no Linux e liberar espaço periodicamente.

Estruturando o ambiente com Docker Compose

Para colocar essa arquitetura em funcionamento sem dor de cabeça, o Docker Compose surge como a ferramenta ideal. Ele permite definir múltiplos containers, suas redes internas e volumes de dados em um único arquivo de configuração em formato YAML. Abaixo, temos um exemplo prático de um arquivo que inicializa três instâncias de uma aplicação web simples e um container do Nginx para gerenciar o tráfego de entrada.

version: '3.8'&#nservices:&#n  web_app:&#n    image: nginx:alpine&#n    deploy:&#n      replicas: 3&#n    networks:&#n      - app-net&#n&#n  load_balancer:&#n    image: nginx:alpine&#n    ports:&#n      - "80:80"&#n    volumes:&#n      - ./nginx.conf:/etc/nginx/nginx.conf:ro&#n    networks:&#n      - app-net&#n    depends_on:&#n      - web_app&#n&#nnetworks:&#n  app-net:&#n    driver: bridge

Neste exemplo, o parâmetro de réplicas cria automaticamente três instâncias do container web, enquanto a rede interna chamada app-net permite que o Nginx enxergue esses containers pelo nome do serviço. Essa comunicação interna dispensa o uso de endereços IP fixos, que costumam mudar toda vez que reiniciamos os containers. Além disso, garantir a segurança e a integridade dos dados gerados por esses serviços é fundamental, e você pode automatizar rotinas de salvamento seguindo o guia sobre como fazer backup de volumes Docker com scripts shell e cron.

Configurando o arquivo de regras do Nginx

Com os containers rodando e conectados na mesma rede, o próximo passo é escrever o arquivo de configuração do Nginx para ativar o balanceamento round-robin. Este arquivo define o bloco upstream, que agrupa os endereços internos dos containers, e o bloco server, que escuta as portas externas e redireciona o tráfego usando a diretiva proxy_pass.

events { worker_connections 1024; }&#n&#nhttp {&#n    upstream backend_cluster {&#n        server web_app_1:80;&#n        server web_app_2:80;&#n        server web_app_3:80;&#n    }&#n&#n    server {&#n        listen 80;&#n&#n        location / {&#n            proxy_pass http://backend_cluster;&#n            proxy_set_header Host $host;&#n            proxy_set_header X-Real-IP $remote_addr;&#n        }&#n    }&#n}

Ao salvar este conteúdo em um arquivo chamado nginx.conf e mapeá-lo para dentro do container do Nginx, o servidor web inteligente começa a alternar as respostas entre as três instâncias configuradas. As diretivas de cabeçalho adicionais garantem que a aplicação final receba o endereço IP real do cliente original, em vez do IP interno do próprio proxy reverso. Essa visibilidade é crucial para registros de auditoria e regras de segurança na camada de aplicação.

Testando e validando o balanceamento em produção

Depois de aplicar as configurações e subir os containers com o comando de inicialização do Docker Compose, vale a pena validar se a distribuição do tráfego está funcionando conforme o esperado. Uma maneira simples de fazer isso é enviar diversas requisições HTTP seguidas para o endereço do servidor usando ferramentas de linha de comando como o curl. Se cada resposta retornar o identificador de um container diferente, significa que o round-robin está ativo e operando perfeitamente.

Caso ocorram falhas de conexão ou erros de gateway no navegador, o primeiro passo é verificar os logs de erro do Nginx e garantir que os nomes dos serviços no arquivo de configuração correspondam exatamente aos nomes definidos no ecossistema Docker. Manter uma infraestrutura robusta exige testes constantes de resiliência e validação dos componentes de rede, assegurando que o sistema continue respondendo mesmo quando uma das instâncias de container sofrer interrupções inesperadas.

Considerações finais sobre alta disponibilidade

Implementar o balanceamento de carga com Nginx e Docker é um divisor de águas para qualquer projeto que precise escalar sem complicações financeiras ou arquiteturais excessivas. A combinação de um proxy leve com a portabilidade dos containers entrega um ambiente previsível, fácil de manter e preparado para absorver picos de acesso. Com os conceitos de round-robin e proxy reverso dominados, sua infraestrutura ganha a elasticidade necessária para crescer de forma sustentável e segura.