Dois desfechos se escondem na frase de que a reserva funciona. Um novo pedido tem sucesso, e isso é recuperação. Uma transferência já em curso continua, e isso é continuidade. São promessas diferentes, e a maioria dos projetos de failover entrega a primeira enquanto a segunda expira em silêncio. Decida qual delas você precisa antes de escolher um mecanismo, e escreva o teste de modo que consiga distingui-las.

Dois resultados que parecem um só sucesso

Imagine um cliente em 10.90.0.42 com uma conexão para 198.51.100.20:443. A saída primária traduz isso para um endereço e uma porta públicos, e a saída de reserva traduz para outro. O endereço interno do cliente nunca muda, e é por isso que as pessoas esperam que a conexão sobreviva.

O servidor não vê um endereço interno. Vê o extremo traduzido, e esse extremo é diferente depois da troca.

Assim, o fluxo antigo expira enquanto uma conexão nova ao mesmo serviço funciona de imediato. As duas observações são verdadeiras ao mesmo tempo.

O que o servidor vê quando a saída muda

Uma conexão TCP é identificada pela sua quádrupla, e mudar o endereço ou a porta de origem cria uma conexão diferente do ponto de vista do host que recebe. Os pacotes que chegam de uma origem nova numa conexão que o servidor não conhece são descartados ou respondidos com um reset. Nada no endereço do cliente VPN preserva a associação ao longo dessa mudança.

O failover com estado existe exatamente para evitar isso, e funciona trocando estado de tradução e estado de conexão entre os dispositivos de encaminhamento. Isso é uma propriedade do par, não do túnel, e precisa ser projetado e testado em vez de presumido.

Verifique se o par realmente mantém estado antes de prometer continuidade a alguém. Os comandos abaixo mostram o estado atual dos dois lados.

conntrack -L -d 198.51.100.20 2>/dev/null | head
ss -tin dst 198.51.100.20
tcpdump -ni any host 198.51.100.20 -c 10

Por que o mesmo endereço público não basta

Manter um endereço público nos dois caminhos é um bom começo, porque o servidor passa a ver o mesmo extremo de origem. Sozinho, porém, não é suficiente. O dispositivo de encaminhamento ainda precisa do estado de tradução, do estado do firewall e de um caminho de retorno utilizável, e isso tem de existir no dispositivo que carrega o tráfego depois da troca.

A RFC 3022 descreve a tradução de endereços e trata a troca de estado entre dispositivos que traduzem como parte de um projeto de reserva. Um endereço flutuante ou um perfil copiado move a configuração sem mover o estado.

Por isso um teste que só faz ping pela reserva prova muito pouco. O ping não tem estado de conexão a perder.

Decida quão forte é o requisito

Se os utilizadores conseguem reconectar após uma falha, o projeto é de recuperação e o teste de aceitação é um pedido novo. Se uma transferência de ficheiro tem de sobreviver, o projeto precisa de sincronização de estado e de um teste muito mais cuidadoso. Se uma sessão remota tem de sobreviver, o requisito é ainda mais forte e pode exigir um mecanismo ao nível da aplicação em vez de ao nível da rede.

Escreva o requisito como uma frase com um resultado mensurável, por exemplo o carregamento termina sem reiniciar ou o operador reconecta dentro de um minuto. Depois escolha o mecanismo mais barato que o satisfaça, e muitas vezes é o projeto de recuperação.

Diga explicitamente o que acontece quando o primário volta, porque um retorno automático pode interromper uma conexão que acabara de recuperar na reserva. Esse caso pertence ao plano de testes, não a uma nota de rodapé.

Verifique o fluxo antigo e o pedido novo

Inicie uma transferência longa e inofensiva pelo primário, depois um pedido novo separado para o mesmo serviço. Registe o contexto da aplicação, o endereço de saída observado e a hora. Corte o primário de uma forma aprovada e continue a observar a transferência original enquanto envia o pedido novo pela reserva.

Relate três valores: se o fluxo antigo continuou, foi reiniciado ou expirou; quando a nova operação funcionou pela primeira vez; e se o retorno interrompeu algo. Essas três linhas são o registo de aceitação.

ss -tin dst 198.51.100.20
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' https://198.51.100.20/
tcpdump -ni any port 443 -c 20

Se a carga de trabalho escreve dados, não repita às cegas uma operação incerta após um tempo limite. A escrita pode ter chegado antes de a resposta se perder. Pergunte à aplicação pelo resultado, ou repita apenas onde a operação é idempotente. Depois escreva a declaração de aceitação em três partes: as operações novas recuperam segundo a política de saída, os fluxos existentes têm o comportamento de interrupção documentado, e a aplicação retoma em segurança. Essa declaração é verificável e é honesta quanto ao que o projeto não promete.

Artigos relacionados