Você é um engenheiro moderno de Platform Ops ou DevOps. Você usa um conjunto de ferramentas de código aberto (e talvez algumas comerciais) para testar, implantar e gerenciar novos aplicativos e contêineres para sua equipe de desenvolvimento. Você escolheu o Kubernetes para executar esses contêineres e pods em ambientes de desenvolvimento, teste, homologação e produção. Você adotou as arquiteturas e os conceitos de microsserviços e, na maior parte do tempo, tudo funciona muito bem. No entanto, você encontrou alguns obstáculos ao longo dessa jornada.
Por exemplo, à medida que você cria e implanta novos clusters, serviços e aplicações, como integrar ou migrar facilmente esses novos recursos para o ambiente de produção sem interromper o tráfego? Os dispositivos de rede tradicionais precisam ser recarregados ou reiniciados quando são feitas alterações de configuração em registros DNS, balanceadores de carga, firewalls e proxies. Essas configurações não podem ser alteradas sem causar indisponibilidade, pois é necessária uma “interrupção do serviço” ou uma “janela de manutenção” para atualizar as regras de DNS, do balanceador de carga e do firewall. Na maioria das vezes, você precisa abrir um temido chamado de serviço e esperar que outra equipe aprove e faça as alterações.
As janelas de manutenção podem tirar sua equipe do rumo, atrasar a entrega de aplicações e fazer você exclamar: “Deve haver uma maneira melhor de gerenciar o tráfego!” Então, vamos explorar uma solução que coloque você de volta na pista rápida.
Balanceamento de carga ativo-ativo entre vários clusters
Se você tiver vários clusters do Kubernetes, o ideal é direcionar o tráfego para ambos os clusters ao mesmo tempo. Uma opção ainda melhor é realizar a divisão de tráfego A/B, canário ou blue-green e enviar uma pequena porcentagem do tráfego como teste. Para isso, você pode usar o NGINX Plus com o módulo ngx_http_split_clients_module.
O módulo HTTP Split Clients foi desenvolvido pelo NGINX Open Source e permite distribuir uma proporção das solicitações com base em uma chave. Neste caso de uso, os clusters são os “upstreams” do NGINX. Assim, à medida que as solicitações dos clientes chegam, o tráfego é dividido entre dois clusters. A chave usada para determinar a solicitação do cliente pode ser qualquer $variable de cliente do NGINX disponível. Dito isso, para controlar essa distribuição em cada solicitação, use a variável $request_id, que é um número exclusivo atribuído pelo NGINX a cada solicitação recebida.
Para configurar as proporções de divisão, determine qual porcentagem você deseja direcionar para cada cluster. Neste exemplo, usamos o K8s Cluster1 como um “cluster grande” para produção e o Cluster2 como um “cluster pequeno” para testes de pré-produção. Se você tivesse um cluster pequeno para staging, poderia usar uma proporção de 90:10 e testar 10% do tráfego no cluster pequeno para garantir que tudo esteja funcionando antes de implantar novas alterações no cluster grande. Se isso parecer arriscado demais, você pode alterar a proporção para 95:5. Na verdade, você pode escolher qualquer proporção entre 0 e 100%.
Para a maior parte do tráfego de produção em tempo real, provavelmente será melhor usar uma proporção de 50:50, com os dois clusters do mesmo tamanho. No entanto, você pode definir facilmente outras proporções com base no tamanho dos clusters ou em outros fatores. Também é possível definir a proporção como 0:100 (ou 100:0) e atualizar, aplicar patches, reparar ou até mesmo substituir um cluster inteiro sem nenhuma indisponibilidade. Deixe o NGINX split_clients encaminhar as solicitações para o cluster ativo enquanto você resolve os problemas no outro.
# Nginx Multi Cluster Load Balancing
# HTTP Split Clients Configuration for Cluster1:Cluster2 ratios
# Provide 100, 99, 50, 1, 0% ratios (add/change as needed)
# Based on
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – Jan 2024
#
split_clients $request_id $split100 {
* cluster1-cafe; # All traffic to cluster1
}
split_clients $request_id $split99 {
99% cluster1-cafe; # 99% cluster1, 1% cluster2
* cluster2-cafe;
}
split_clients $request_id $split50 {
50% cluster1-cafe; # 50% cluster1, 50% cluster2
* cluster2-cafe;
}
split_clients $request_id $split1 {
1.0% cluster1-cafe; # 1% to cluster1, 99% to cluster2
* cluster2-cafe;
}
split_clients $request_id $split0 {
* cluster2-cafe; # All traffic to cluster2
}
# Choose which cluster upstream based on the ratio
map $split_level $upstream {
100 $split100;
99 $split99;
50 $split50;
1.0 $split1;
0 $split0;
default $split50;
}Você pode adicionar ou editar a configuração acima para corresponder às proporções necessárias (por exemplo, 90:10, 80:20, 60:40 e assim por diante).
Observação: O NGINX também possui um módulo Split Clients para conexões TCP no contexto de stream, que pode ser usado para tráfego não HTTP. Esse módulo divide o tráfego com base em novas conexões TCP, em vez de solicitações HTTP.
Armazenamento de chave-valor do NGINX Plus
O próximo recurso que você pode usar é o armazenamento de chave-valor do NGINX Plus. Trata-se de um objeto de chave-valor em uma zona de memória compartilhada do NGINX que pode ser usado em diversos casos de uso de armazenamento de dados. Aqui, ele é usado para armazenar o valor da proporção de divisão mencionado na seção acima. O NGINX Plus permite alterar qualquer registro de chave-valor sem recarregar o NGINX. Assim, você pode alterar esse valor de divisão por meio de uma chamada de API, criando a função de divisão dinâmica.
Com base no nosso exemplo, fica assim:
{“cafe.example.com”:90}
Este registro KeyVal indica:
A chave é o nome do host “cafe.example.com”
O valor é “90” para a proporção da divisão
Em vez de codificar diretamente a proporção de divisão nos arquivos de configuração do NGINX, você pode usar a memória de chave-valor. Isso elimina a necessidade de recarregar o NGINX para alterar um valor de divisão estático.
Neste exemplo, o NGINX está configurado para usar uma proporção de divisão de 90:10, com o grande Cluster1 recebendo 90% e o pequeno Cluster2 recebendo os 10% restantes. Como esse é um registro de chave-valor, você pode alterar essa proporção usando a API do NGINX Plus dinamicamente, sem precisar recarregar a configuração! O módulo Split Clients usará o novo valor da proporção assim que você o alterar, já na solicitação seguinte.
Crie o registro de chave-valor, começando com uma proporção de 50/50:
Adicione um novo registro ao armazenamento KeyValue enviando um comando de API ao NGINX Plus:
curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split
Altere o registro de chave-valor (KV) para a proporção de 90/10:
Altere a proporção de divisão do KeyVal para 90 usando o método HTTP PATCH para atualizar o registro KeyVal na memória:
curl -iX PATCH -d '{"cafe.example.com":90}' http://nginxlb:9000/api/8/http/keyvals/split
Em seguida, a equipe de testes de pré-produção verifica se o novo código da aplicação está pronto, você o implanta no grande Cluster1 e altera a proporção para 100%. Isso direciona imediatamente todo o tráfego para o Cluster1 e sua nova aplicação entra “no ar” sem nenhuma interrupção no tráfego, indisponibilidade do serviço, janela de manutenção, reinicialização, recarregamento ou uma infinidade de chamados. Basta uma única chamada de API para alterar essa proporção de distribuição no momento que você escolher.
É claro que, se é tão fácil passar de 90% para 100%, também é fácil alterar a proporção de 100:0 para 50:50 (ou até mesmo 0:100). Assim, você pode ter um cluster de backup ativo ou escalar seus clusters horizontalmente com novos recursos. Indo ainda mais longe, você pode até criar um cluster totalmente novo com as versões mais recentes de software, hardware e patches de software, implantando a aplicação e migrando o tráfego gradualmente sem interromper uma única conexão!
Casos de uso
O uso do módulo HTTP Split Clients com o armazenamento de chave-valor dinâmico permite atender aos seguintes casos de uso:
- Balanceamento de carga ativo-ativo – Para balanceamento de carga entre vários clusters.
- Balanceamento de carga ativo-passivo – Para balanceamento de carga entre clusters e aplicações primários, de backup e de recuperação de desastres.
- Testes A/B, blue-green e canário – Usados com novas aplicações Kubernetes.
- Escalonamento horizontal do cluster – Adiciona mais recursos ao cluster e altera a proporção quando você estiver pronto.
- Atualizações de cluster sem interrupção – Possibilidade de usar um cluster enquanto você atualiza, aplica patches ou repara o outro cluster.
- Failover instantâneo – Se um dos clusters apresentar um problema grave, você poderá alterar a proporção para usar o outro cluster.
Exemplos de configuração
Veja um exemplo de configuração de chave-valor:
# Define Key Value store, backup state file, timeout, and enable sync
keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;
keyval $host $split_level zone=split;E este é um exemplo da configuração do aplicativo cafe.example.com:
# Define server and location blocks for cafe.example.com, with TLS
server {
listen 443 ssl;
server_name cafe.example.com;
status_zone https://cafe.example.com;
ssl_certificate /etc/ssl/nginx/cafe.example.com.crt;
ssl_certificate_key /etc/ssl/nginx/cafe.example.com.key;
location / {
status_zone /;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header "Connection" "";
proxy_pass https://$upstream; # traffic split to upstream blocks
}
# Define 2 upstream blocks – one for each cluster
# Servers managed dynamically by NLK, state file backup
# Cluster1 upstreams
upstream cluster1-cafe {
zone cluster1-cafe 256k;
least_time last_byte;
keepalive 16;
#servers managed by NLK Controller
state /var/lib/nginx/state/cluster1-cafe.state;
}
# Cluster2 upstreams
upstream cluster2-cafe {
zone cluster2-cafe 256k;
least_time last_byte;
keepalive 16;
#servers managed by NLK Controller
state /var/lib/nginx/state/cluster2-cafe.state;
}Os endereços IP e as portas dos servidores upstream são gerenciados pelo NGINX Loadbalancer for Kubernetes, um novo controlador que também usa a API do NGINX Plus para configurar dinamicamente o NGINX Plus. Mais detalhes estão na próxima seção.
Vamos analisar a divisão do tráfego HTTP ao longo do tempo com o Grafana, uma ferramenta popular de monitoramento e visualização. Você usa o NGINX Prometheus Exporter (baseado em njs) para exportar todas as suas métricas do NGINX Plus, que são então coletadas e exibidas em gráficos pelo Grafana. Os detalhes sobre como configurar o Prometheus e o Grafana podem ser encontrados aqui.
Há quatro servidores upstream no gráfico: dois para o Cluster1 e dois para o Cluster2. Usamos uma ferramenta de geração de carga HTTP para criar solicitações HTTP e enviá-las ao NGINX Plus.
Nos três gráficos abaixo, é possível observar que a proporção de divisão é de 50:50 no início do gráfico.

Em seguida, a proporção muda para 10:90 às 12:56:30.

Em seguida, a proporção muda para 90:10 às 13:00:00.

Você pode encontrar configurações funcionais do Prometheus e do Grafana no repositório do NGINX Loadbalancer for Kubernetes no GitHub.
Upstreams HTTP dinâmicos: NGINX Loadbalancer para Kubernetes
Você pode substituir a configuração estática de upstreams do NGINX por upstreams dinâmicos de cluster usando a API do NGINX Plus e o controlador NGINX Loadbalancer for Kubernetes. Esse projeto gratuito é um controlador do Kubernetes que monitora o NGINX Ingress Controller e atualiza automaticamente uma instância externa do NGINX Plus configurada para balanceamento de carga TCP/HTTP. Seu design é bastante simples, assim como sua instalação e operação. Com essa solução implementada, você pode realizar o balanceamento de carga TCP/HTTP em ambientes Kubernetes, garantindo que novos aplicativos e serviços sejam detectados imediatamente e estejam disponíveis para receber tráfego, sem necessidade de recarregamento.
Arquitetura e fluxo
O NGINX Loadbalancer for Kubernetes fica dentro de um cluster do Kubernetes. Ele é registrado no Kubernetes para monitorar o serviço do NGINX Ingress Controller (nginx-ingress). Quando ocorre uma alteração no(s) controlador(es) de Ingress, o NGINX Loadbalancer for Kubernetes coleta os IPs dos nós de trabalho e os números das portas TCP do NodePort e, em seguida, envia os IPs e as portas ao NGINX Plus por meio da API do NGINX Plus.
Os servidores upstream do NGINX são atualizados sem a necessidade de recarregamento, e o NGINX Plus distribui o tráfego entre os servidores upstream e os NodePorts do Kubernetes corretos. É possível adicionar outras instâncias do NGINX Plus para obter alta disponibilidade.
Uma visão geral do NGINX Loadbalancer para Kubernetes em ação
Na captura de tela abaixo, há duas janelas que mostram o NGINX Loadbalancer for Kubernetes implantado e em funcionamento:
- Tipo de serviço –
LoadBalancerparanginx-ingress - IP externo – Conecta-se aos servidores NGINX Plus
- Portas – O NodePort é mapeado para 443:30158 com servidores upstream do NGINX correspondentes (conforme mostrado no painel em tempo real do NGINX Plus)
- Logs – Indica que o NGINX Loadbalancer for Kubernetes está enviando dados com sucesso para o NGINX Plus

Observação: neste exemplo, os nós de trabalho do Kubernetes são 10.1.1.8 e 10.1.1.10
Adicionando recursos de segurança do NGINX Plus
À medida que cada vez mais aplicações executadas no Kubernetes são expostas à internet pública, a segurança se torna indispensável. Felizmente, o NGINX Plus conta com recursos de segurança de nível empresarial que podem ser usados para criar uma arquitetura em camadas, com defesa em profundidade.
Com o NGINX Plus à frente dos seus clusters e executando a função split_clients por que não aproveitar essa presença e adicionar alguns recursos de segurança úteis? Veja alguns dos recursos do NGINX Plus que podem ser usados para reforçar a segurança, com links e referências a outras documentações que podem ser usadas para configurá-los, testá-los e implantá-los.
- Listas de bloqueio/permissão de IP – Controlam o acesso com base no endereço IP de origem. Você pode encontrar um guia de configuração sobre como usar o armazenamento de chave-valor do NGINX Plus para listas dinâmicas de bloqueio/permissão de IP usando a API do Plus na página Bloqueio dinâmico de endereços IP da documentação do NGINX.
- Limitação de taxa – Controla o número de conexões TCP, solicitações HTTP e o uso de largura de banda para aplicativos, endpoints de API e downloads de mídia. Para saber mais sobre limitação de taxa com o NGINX, consulte Limitação de acesso a recursos HTTP com proxy na documentação do NGINX e as publicações do blog Limitação de taxa com NGINX e NGINX Plus e Limites dinâmicos de largura de banda usando o armazenamento de chave-valor do NGINX Plus.
- Módulo dinâmico GeoIP2 – Coleta metadados de localização com base no endereço IP de origem. Saiba mais sobre isso na página Restrição de acesso por localização geográfica da documentação do NGINX.
- Módulo JWT e OpenID Connect (OIDC) – Controla o acesso dos usuários por meio de protocolos padrão do setor. Mais informações podem ser encontradas na página Configuração da autenticação JWT da documentação do NGINX.
- NGINX App Protect – Um firewall de aplicações web leve e de baixa latência que protege contra ameaças existentes e emergentes.
Comece hoje mesmo
Se você está frustrado com os desafios de rede na borda do seu cluster Kubernetes, experimente esta solução multicluster do NGINX. Teste o software NGINX Loadbalancer for Kubernetes e conte-nos o que achou. O código-fonte é aberto (sob a licença Apache 2.0), e todas as instruções de instalação estão disponíveis no GitHub.
Para enviar seu feedback, deixe um comentário no repositório ou envie uma mensagem para nós no Slack da Comunidade NGINX.
Sobre o autor
Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.