Você é um engenheiro moderno de Platform Ops ou DevOps. Você usa uma biblioteca 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, preparação e produção. Você comprou as arquiteturas e conceitos de microsserviços e, na maior parte, funciona muito bem. No entanto, você encontrou alguns obstáculos ao longo desta jornada.
Por exemplo, ao criar e implementar novos clusters, serviços e aplicativos, como você integra ou migra facilmente esses novos recursos para a produção sem perder tráfego? Os dispositivos de rede tradicionais exigem recargas ou reinicializações ao implementar alterações de configuração em registros DNS, balanceadores de carga, firewalls e proxies. Esses ajustes não são reconfiguráveis sem causar tempo de inatividade porque uma “interrupção do serviço” ou “janela de manutenção” é necessária para atualizar as regras de DNS, balanceador de carga e firewall. Na maioria das vezes, você precisa enviar um temido tíquete de serviço e esperar que outra equipe aprove e faça as alterações.
As janelas de manutenção podem levar sua equipe a um beco sem saída, paralisar a entrega de aplicativos e fazer você declarar: "Deve haver uma maneira melhor de gerenciar o tráfego!" Então, vamos explorar uma solução que o coloque de volta na via rápida.
Se você tiver vários clusters do Kubernetes, o ideal é rotear 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 azul-verde e enviar uma pequena porcentagem do seu tráfego como teste. Para fazer isso, você pode usar o NGINX Plus com ngx_http_split_clients_module
.
O módulo HTTP Split Clients foi escrito pela NGINX Open Source e permite que a proporção de solicitações seja distribuída com base em uma chave. Neste caso de uso, os clusters são os “upstreams” do NGINX. Então, conforme as solicitações do cliente chegam, o tráfego é dividido entre dois clusters. A chave usada para determinar a solicitação do cliente é qualquer $variable
do cliente NGINX disponível. Dito isso, para controlar isso para 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 taxas de divisão, determine quais porcentagens você gostaria de aplicar em cada cluster. Neste exemplo, usamos o K8s Cluster1 como um “grande cluster” para produção e o Cluster2 como um “pequeno cluster” para testes de pré-produção. Se você tivesse um pequeno cluster para preparação, poderia usar uma proporção de 90:10 e testar 10% do seu tráfego no cluster pequeno para garantir que tudo esteja funcionando antes de implementar novas alterações no cluster grande. Se isso parecer muito arriscado, você pode alterar a proporção para 95:5. Na verdade, você pode escolher qualquer proporção que desejar, de 0 a 100%.
Para a maioria do tráfego de produção em tempo real, você provavelmente deseja uma proporção de 50:50, na qual seus dois clusters tenham o mesmo tamanho. Mas você pode facilmente fornecer outras proporções, com base no tamanho do cluster ou outros detalhes. Você pode facilmente definir a proporção para 0:100 (ou 100:0) e atualizar, corrigir, reparar ou até mesmo substituir um cluster inteiro sem tempo de inatividade. Deixe que o NGINX split_clients
encaminhe as solicitações para o cluster ativo enquanto você resolve os problemas no outro.
# Balanceamento de carga de vários clusters do Nginx
# Configuração de clientes divididos HTTP para proporções Cluster1:Cluster2
# Forneça proporções de 100, 99, 50, 1, 0% (adicione/altere conforme necessário)
# Com base em
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – Jan 2024
#
split_clients $request_id $split100 {
* cluster1-cafe; # Todo o tráfego para 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% para cluster1, 99% para cluster2
* cluster2-cafe;
}
split_clients $request_id $split0 {
* cluster2-cafe; # Todo o tráfego para cluster2
}
# Escolha qual cluster upstream com base na proporção
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 tem um módulo Split Clients
para conexões TCP no contexto de fluxo, que pode ser usado para tráfego não HTTP. Isso divide o tráfego com base em novas conexões TCP, em vez de solicitações HTTP.
O próximo recurso que você pode usar é o armazenamento de chave-valor do NGINX Plus. Este é um objeto chave-valor em uma zona de memória compartilhada do NGINX que pode ser usado para muitos casos de uso de armazenamento de dados diferentes. Aqui, usamos isso para armazenar o valor da taxa de divisão mencionado na seção acima. O NGINX Plus permite que você altere qualquer registro de valor-chave sem recarregar o NGINX. Isso permite que você altere esse valor de divisão com 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 diz:
A chave é o nome do host “cafe.example.com”
O valor é “90” para a taxa de divisão
Em vez de codificar a taxa 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 no NGINX.
Neste exemplo, o NGINX está configurado para usar 90:10 para a taxa de divisão, com o grande Cluster1 para os 90% e o pequeno Cluster2 para os 10% restantes. Como este é um registro de chave-valor, você pode alterar essa proporção usando a API do NGINX Plus dinamicamente , sem recarregar a configuração! O módulo Split Clients usará esse novo valor de proporção assim que você alterá-lo, na próxima solicitação.
Crie o registro KV, comece com uma proporção de 50/50:
Adicione um novo registro ao armazenamento KeyValue enviando um comando de API para o NGINX Plus:
curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split
Alterar o registro KV, alterar para a proporção 90/10:
Altere a taxa de divisão de KeyVal para 90, usando um 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 do aplicativo está pronto, você o implanta no grande Cluster1 e altera a proporção para 100%. Isso envia imediatamente todo o tráfego para o Cluster1 e seu novo aplicativo fica "ativo" sem nenhuma interrupção no tráfego, sem interrupções de serviço, sem janelas de manutenção, reinicializações, recarregamentos ou muitos tickets. Basta uma chamada de API para alterar essa taxa de divisão no momento que você escolher.
Claro, sendo tão fácil passar de 90% para 100%, você tem uma maneira fácil de alterar a proporção de 100:0 para 50:50 (ou até 0:100). Assim, você pode ter um cluster de backup ativo ou dimensionar seus clusters horizontalmente com novos recursos. Com aceleração máxima, você pode até mesmo construir completamente um novo cluster com o software, hardware e patches de software mais recentes, implantando o aplicativo e migrando o tráfego ao longo de um período de tempo sem perder uma única conexão!
Usar o módulo HTTP Split Clients com o armazenamento dinâmico de chave-valor pode fornecer os seguintes casos de uso:
Aqui está um exemplo da configuração de chave-valor:
# Defina o armazenamento de valor de chave, arquivo de estado de backup, tempo limite e habilite a sincronização
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:
# Defina blocos de servidor e localização para cafe.example.com, com 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; # tráfego dividido em blocos upstream } # Defina 2 blocos upstream – um para cada cluster # Servidores gerenciados dinamicamente por NLK, backup de arquivo de estado # Cluster1 faz upstream upstream cluster1-cafe { zone cluster1-cafe 256k; least_time last_byte; keepalive 16; #servidores gerenciados pelo estado do controlador NLK /var/lib/nginx/state/cluster1-cafe.state; } # Cluster2 upstreams upstream cluster2-cafe { zona cluster2-cafe 256k; least_time last_byte; keepalive 16; #servidores gerenciados pelo estado do controlador NLK /var/lib/nginx/state/cluster2-cafe.state; }
O IP:portas do servidor upstream são gerenciados pelo NGINX Loadbalancer for Kubernetes , um novo controlador que também usa a API do NGINX Plus para configurar o NGINX Plus dinamicamente. Os detalhes estão na próxima seção .
Vamos dar uma olhada no tráfego HTTP dividido ao longo do tempo com o Grafana , uma ferramenta popular de monitoramento e visualização. Use o NGINX Prometheus Exporter (baseado em njs ) para exportar todas as suas métricas do NGINX Plus, que são então coletadas e representadas graficamente pelo Grafana. Detalhes para configurar o Prometheus e o Grafana podem ser encontrados aqui .
Há quatro servidores upstream no gráfico: Dois para Cluster1 e dois para 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, você pode ver que a proporção de divisão é 50:50 no início do gráfico.
Então, a proporção muda para 10:90 em 12:56:30.
Depois muda para 90:10 às 13:00:00.
Você pode encontrar configurações funcionais do Prometheus e do Grafana no repositório GitHub do NGINX Loadbalancer for Kubernetes .
Você pode alterar a configuração estática do NGINX Upstream para upstreams de cluster dinâmicos usando a API NGINX Plus e o controlador NGINX Loadbalancer for Kubernetes . Este projeto gratuito é um controlador Kubernetes que monitora o NGINX Ingress Controller e atualiza automaticamente uma instância externa do NGINX Plus configurada para balanceamento de carga TCP/HTTP. É muito simples em design e fácil de instalar e operar. Com esta solução em vigor, você pode implementar o balanceamento de carga TCP/HTTP em ambientes Kubernetes, garantindo que novos aplicativos e serviços sejam imediatamente detectados e disponibilizados para tráfego, sem necessidade de recarga.
O NGINX Loadbalancer para Kubernetes fica dentro de um cluster do Kubernetes. Ele é registrado no Kubernetes para monitorar o serviço NGINX Ingress Controller ( nginx-ingress
). Quando há uma alteração nos controladores de entrada, o NGINX Loadbalancer para Kubernetes coleta os Worker Ips e os números de porta TCP NodePort e, em seguida, envia os IPs:portas para o NGINX Plus por meio da API do NGINX Plus .
Os servidores upstream do NGINX são atualizados sem necessidade de recarga, e o NGINX Plus balanceia a carga do tráfego para os servidores upstream corretos e os NodePorts do Kubernetes. Instâncias adicionais do NGINX Plus podem ser adicionadas para atingir alta disponibilidade .
Na captura de tela abaixo, há duas janelas que demonstram o NGINX Loadbalancer for Kubernetes implantado e fazendo seu trabalho:
LoadBalancer
para nginx-ingress
Observação : Neste exemplo, os nós de trabalho do Kubernetes são 10.1.1.8 e 10.1.1.10
À medida que mais e mais aplicativos executados no Kubernetes são expostos à internet aberta, a segurança se torna necessária. Felizmente, o NGINX Plus tem recursos de segurança de nível empresarial que podem ser usados para criar uma arquitetura em camadas e de defesa em profundidade.
Com o NGINX Plus na 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 benéficos? Aqui estão alguns dos recursos do NGINX Plus que podem ser usados para aumentar a segurança, com links e referências a outras documentações que podem ser usadas para configurá-los, testá-los e implantá-los.
Se você está frustrado com os desafios de rede na borda do seu cluster Kubernetes, considere experimentar esta solução multicluster NGINX. Faça um teste no software NGINX Loadbalancer for Kubernetes e diga-nos o que você achou. O código-fonte é de código aberto (sob a licença Apache 2.0) e todas as instruções de instalação estão disponíveis no GitHub .
Para fornecer feedback, deixe um comentário no repositório ou envie uma mensagem para nós no Slack da Comunidade NGINX .
"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."