O tráfego entre zonas aumenta a latência e gera custos adicionais de transferência de dados. O roteamento com reconhecimento de zona mantém as requisições na mesma zona de disponibilidade sempre que há endpoints íntegros, o que reduz ambos os fatores. Quando os endpoints da mesma zona ficam indisponíveis, o tráfego passa automaticamente por failover para a zona mais próxima.
O Service Mesh (ASM) oferece suporte ao roteamento com reconhecimento de zona (também chamado de roteamento intra-zona) por meio do balanceamento de carga de localidade do Istio. Não é necessário alterar o código da aplicação. Este tópico demonstra como ativar o roteamento com reconhecimento de zona para um serviço de exemplo implantado em duas zonas. No exemplo a seguir, um gateway de entrada habilita o acesso a uma aplicação HTTPBin.
Como funciona
Quando um cliente inicia uma requisição para acessar um serviço, o sistema a roteia para o serviço no mesmo nó ou na mesma zona do cliente, com base nas informações de topologia da região e da zona onde o cliente reside. Cada endpoint herda a região, a zona e a subzona de seu nó. Ao ativar o balanceamento de carga de localidade por meio de uma DestinationRule, o proxy sidecar atribui níveis de prioridade aos endpoints:
|
Prioridade |
Significado |
|
0 |
Mesma zona do chamador (prioridade mais alta) |
|
1 |
Zona diferente, mesma região |
O tráfego é direcionado primeiro aos endpoints de prioridade 0. Se eles se tornarem não íntegros (detectados pela detecção de outliers), o proxy executa failover para o próximo nível de prioridade.
Pré-requisitos
Antes de começar, verifique se você tem:
Um cluster ACK adicionado à sua instância ASM. Para mais informações, consulte Adicionar um cluster a uma instância ASM
Nós de cluster distribuídos em pelo menos duas zonas de disponibilidade. Para verificar, confira a zona de cada instância do Elastic Compute Service (ECS) no Console de Gerenciamento do Container Service. Para mais informações, consulte Regiões e zonas
Etapa 1: Implantar aplicações de exemplo
Este tutorial utiliza duas aplicações:
sleep -- um cliente baseado em curl, implantado em
cn-hongkong-bhelloworld -- o serviço de destino, com v1 em
cn-hongkong-be v2 emcn-hongkong-c
Substitua cn-hongkong-b e cn-hongkong-c pelas zonas onde residem os nós do seu cluster.
Implantar o cliente sleep
-
Crie o arquivo
sleep.yaml: -
Aplique o manifesto:
kubectl apply -f sleep.yaml
Implantar o serviço helloworld
-
Crie o arquivo
helloworld.yaml: -
Aplique o manifesto:
kubectl apply -f helloworld.yaml
Verificar o registro de endpoints
Consulte as informações de cluster do Envoy no pod sleep para confirmar se ambos os endpoints helloworld estão registrados com metadados de zona:
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
-c sleep -- curl -s localhost:15000/clusters | grep helloworld
Na saída, procure pelos campos zone e priority. Antes de ativar o roteamento com reconhecimento de zona, ambos os endpoints compartilham a mesma prioridade (priority::0):
outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b
outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0
...
outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c
outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::0
Prioridades iguais indicam que o proxy distribui o tráfego entre ambos os endpoints sem preferência de zona.
Etapa 2: Ativar o roteamento com reconhecimento de zona com uma DestinationRule
Crie uma DestinationRule que ative o balanceamento de carga de localidade e configure a detecção de outliers para o serviço helloworld. A detecção de outliers é obrigatória para o failover; sem ela, o proxy não consegue detectar endpoints não íntegros nem redirecionar o tráfego para outra zona.
-
Crie o arquivo
helloworld-failover.yaml. Campos principais:Campo
Finalidade
localityLbSetting.enabledAtiva o roteamento com reconhecimento de zona
outlierDetectionDetecta endpoints não íntegros e aciona o failover para a próxima zona
consecutive5xxErrors: 1Remove um endpoint após um único erro 5xx (agressivo, apenas para demonstração)
baseEjectionTime: 1mMantém os endpoints removidos fora de serviço por 1 minuto
interval: 1sVerifica a integridade do endpoint a cada segundo
maxRequestsPerConnection: 1Força uma nova conexão por requisição (apenas para demonstração)
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld-failover namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 1 loadBalancer: localityLbSetting: enabled: true simple: ROUND_ROBIN outlierDetection: baseEjectionTime: 1m consecutive5xxErrors: 1 interval: 1s -
Aplique a DestinationRule:
kubectl apply -f helloworld-failover.yaml -
Verifique se as prioridades dos endpoints foram alteradas. O endpoint da mesma zona (
cn-hongkong-b) agora tempriority::0, e o endpoint entre zonas (cn-hongkong-c) tempriority::1. Prioridades diferentes confirmam que o roteamento com reconhecimento de zona está ativo. O proxy envia todo o tráfego primeiro para o endpoint de prioridade 0 (mesma zona).kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -c sleep -- curl -s localhost:15000/clusters | grep helloworldoutbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0 ... outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::1
Etapa 3: Verificar o comportamento de roteamento
Com o roteamento com reconhecimento de zona ativado, todas as requisições do pod sleep (cn-hongkong-b) são roteadas para o helloworld-v1 na mesma zona. As etapas a seguir confirmam esse comportamento e testam o failover quando o endpoint da mesma zona fica indisponível.
Confirme o roteamento na mesma zona
Execute o comando a seguir várias vezes:
kubectl exec -c sleep \
"$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \
-- curl -sSL helloworld:5000/hello
Saída esperada:
Hello version: v1, instance: helloworld-v1-6f88967849-sq2h2
Todas as respostas vêm da v1 (o endpoint da mesma zona em cn-hongkong-b).
Testar o failover entre zonas
-
Dimensione o helloworld-v1 para zero réplicas para simular uma interrupção em
cn-hongkong-b:kubectl scale deploy helloworld-v1 --replicas=0 -
Aguarde alguns segundos e envie requisições novamente. Saída esperada: O tráfego agora é roteado para a v2 em
cn-hongkong-c, o que confirma que o failover entre zonas funciona quando os endpoints da mesma zona estão indisponíveis.kubectl exec -c sleep \ "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- curl -sSL helloworld:5000/helloHello version: v2, instance: helloworld-v2-75db5f978d-s7v4k
Restaurar o endpoint da mesma zona
-
Dimensione o helloworld-v1 de volta para uma réplica:
kubectl scale deploy helloworld-v1 --replicas=1 -
Aguarde alguns segundos e verifique se o tráfego retorna para a v1. Saída esperada: O tráfego volta a ser roteado para o endpoint da mesma zona após a recuperação.
kubectl exec -c sleep \ "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- curl -sSL helloworld:5000/helloHello version: v1, instance: helloworld-v1-6f88967849-sq2h2