Nota. transl.: Primeira parte Esta serie dedicouse a presentar as capacidades de Istio e demostralas en acción. Agora falaremos de aspectos máis complexos da configuración e do uso desta malla de servizo e, en particular, do enrutamento finamente axustado e da xestión do tráfico de rede.
Lembrámosche tamén que o artigo usa configuracións (manifestos para Kubernetes e Istio) do repositorio istio-dominio.
xestión do tráfico
Con Istio, aparecen novas capacidades no clúster para proporcionar:
Enrutamento dinámico de solicitudes: lanzamentos canarios, probas A/B;
Equilibrio de carga: sinxelo e consistente, baseado en hash;
Recuperación tras caídas: tempo de espera, reintentos, interruptores;
Inserción de fallos: atrasos, solicitudes abandonadas, etc.
A medida que o artigo continúa, estas capacidades ilustraranse usando a aplicación seleccionada como exemplo e introduciranse novos conceptos ao longo do camiño. O primeiro concepto deste tipo será DestinationRules(é dicir, regras sobre o destinatario do tráfico/solicitudes - aprox. traduc.), coa axuda do cal activamos as probas A/B.
Probas A/B: DestinationRules na práctica
As probas A/B úsanse nos casos en que hai dúas versións dunha aplicación (normalmente son visualmente diferentes) e non estamos seguros ao 100% de cal mellorará a experiencia do usuario. Polo tanto, executamos as dúas versións á vez e recollemos métricas.
Para implementar a segunda versión do frontend, necesaria para demostrar as probas A/B, execute o seguinte comando:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
O manifesto de despregamento para a versión verde difire en dous lugares:
A imaxe está baseada nunha etiqueta diferente - istio-green,
As vainas teñen unha etiqueta version: green.
Xa que ambos despregamentos teñen unha etiqueta app: sa-frontend, solicitudes encamiñadas polo servizo virtual sa-external-services para o servizo sa-frontend, será redirixido a todas as súas instancias e a carga distribuirase a través algoritmo round-robin, o que dará lugar á seguinte situación:
Non se atoparon os ficheiros solicitados
Estes ficheiros non se atoparon porque reciben un nome diferente nas diferentes versións da aplicación. Asegurémonos disto:
Significa iso index.html, solicitando unha versión de ficheiros estáticos, pode ser enviado polo equilibrador de carga a pods que teñan unha versión diferente, onde, por razóns obvias, tales ficheiros non existen. Polo tanto, para que a aplicación funcione, necesitamos establecer unha restrición: "a mesma versión da aplicación que serviu index.html debería atender solicitudes posteriores».
Chegaremos aí cun balance de carga consistente baseado en hash (Balanceamento de carga Hash consistente)... Neste caso as solicitudes do mesmo cliente envíanse á mesma instancia de backend, para o que se usa unha propiedade predefinida, por exemplo, unha cabeceira HTTP. Implementado usando DestinationRules.
Regras de destino
Despois Servizo Virtual enviou unha solicitude ao servizo desexado, mediante DestinationRules podemos definir políticas que se aplicarán ao tráfico destinado a instancias deste servizo:
Xestión do tráfico con recursos de Istio
Nota: O impacto dos recursos de Istio no tráfico da rede preséntase aquí dun xeito doado de entender. Para ser precisos, a decisión sobre a que instancia enviar a solicitude tómaa o Envoy no Ingress Gateway configurado no CRD.
Coas regras de destino, podemos configurar o equilibrio de carga para utilizar hash coherentes e garantir que a mesma instancia de servizo responde ao mesmo usuario. A seguinte configuración permítelle conseguir isto (destinationrule-sa-frontend.yaml):
Nota: Para engadir diferentes valores na cabeceira e probar os resultados directamente no navegador, pode usar esta extensión a Chrome (Ou con este para Firefox - aprox. trad.).
En xeral, DestinationRules ten máis capacidades na área do equilibrio de carga. Comprobe os detalles en documentación oficial.
Antes de estudar máis adiante VirtualService, eliminemos a "versión verde" da aplicación e a correspondente regra de dirección de tráfico executando os seguintes comandos:
Sombreado ("blindaxe") ou Espello ("reflejo") utilízase nos casos nos que queremos probar un cambio na produción sen afectar aos usuarios finais: para iso, duplicamos as solicitudes ("espello") a unha segunda instancia onde se realizaron os cambios desexados e observamos as consecuencias. En pocas palabras, é cando o teu colega escolle o problema máis crítico e fai unha solicitude de extracción en forma de gran cantidade de lixo que ninguén pode revisalo.
Para probar este escenario en acción, creemos unha segunda instancia de SA-Logic con erros (buggy) executando o seguinte comando:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
E agora imos executar o comando para asegurarnos de que todas as instancias con app=sa-logic Tamén teñen etiquetas coas versións correspondentes:
Servizo sa-logic apunta a vainas cunha etiqueta app=sa-logic, polo que todas as solicitudes repartiranse entre todas as instancias:
... pero queremos que as solicitudes se envíen a instancias v1 e que se reflejen en instancias v2:
Conseguirémolo mediante VirtualService en combinación con DestinationRule, onde as regras determinarán os subconxuntos e rutas do VirtualService a un subconxunto específico.
Non se necesita explicación aquí, así que vémolo en acción:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
Engadimos a carga chamando ao seguinte comando:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done
Vexamos os resultados en Grafana, onde podes ver que a versión con erros (buggy) produce fallos para ~60 % das solicitudes, pero ningún destes fallos afecta aos usuarios finais xa que son respondidos por un servizo en execución.
Respostas exitosas de diferentes versións do servizo sa-logic
Aquí vimos por primeira vez como se aplica VirtualService aos enviados dos nosos servizos: cando sa-web-app fai unha solicitude a sa-logic, pasa polo sidecar Envoy, que -a través de VirtualService- está configurado para dirixir a solicitude ao subconxunto v1 e reflectir a solicitude ao subconxunto v2 do servizo. sa-logic.
Seino, xa podes pensar que os servizos virtuais son sinxelos. Na seguinte sección, ampliaremos isto dicindo que tamén son realmente xeniais.
Lanzamentos de Canarias
Canary Deployment é o proceso de lanzar unha nova versión dunha aplicación a un pequeno número de usuarios. Úsase para asegurarse de que non hai problemas no lanzamento e só despois diso, xa confiando na súa calidade (de lanzamento), distribúelo a outros usuarios.оaudiencia maior.
Para demostrar os lanzamentos de canarias, seguiremos traballando cun subconxunto buggy у sa-logic.
Non perdamos o tempo en bagatelas e enviemos inmediatamente o 20% dos usuarios á versión con erros (isto representará o noso lanzamento canario) e o 80% restante ao servizo normal. Para iso, use o seguinte VirtualService (subconxuntos sa-logic-canary-vs.yaml):
... e veremos inmediatamente que algunhas solicitudes dan lugar a fallos:
$ while true; do
curl -i http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}'
--silent -w "Time: %{time_total}s t Status: %{http_code}n"
-o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500
Os servizos virtuais permiten lanzamentos canarios: neste caso, reducimos o impacto potencial dos problemas ao 20% da base de usuarios. Marabilloso! Agora, en todos os casos cando non esteamos seguros do noso código (noutras palabras, sempre...), podemos usar a creación de réplicas e os lanzamentos canarios.
Tempos mortos e reintentos
Pero os erros non sempre acaban no código. Na lista de "8 Conceptos erróneos sobre a computación distribuída"En primeiro lugar está a crenza errónea de que "a rede é fiable". En realidade a rede non fiable, e por iso necesitamos tempo morto (tempos mortos) e reintentos (reintentos).
Para a demostración seguiremos usando a mesma versión do problema sa-logic (buggy), e simularemos a falta de fiabilidade da rede con fallos aleatorios.
Permite que o noso servizo con erros teña 1/3 de posibilidades de tardar demasiado en responder, 1/3 de posibilidades de rematar cun erro interno do servidor e 1/3 de posibilidades de devolver a páxina con éxito.
Para mitigar o impacto deste tipo de problemas e mellorar a vida dos usuarios, podemos:
engade un tempo de espera se o servizo tarda máis de 8 segundos en responder,
O tempo de espera para a solicitude establécese en 8 segundos;
As solicitudes reinténtanse 3 veces;
E cada intento considérase infructuoso se o tempo de resposta supera os 3 segundos.
Trátase dunha optimización porque o usuario non terá que esperar máis de 8 segundos e faremos tres novos intentos para obter resposta en caso de fallos, aumentando as posibilidades de resposta satisfactoria.
Aplique a configuración actualizada co seguinte comando:
E comproba nos gráficos de Grafana que o número de respostas exitosas aumentou arriba:
Melloras nas estatísticas de resposta exitosa despois de engadir tempo de espera e reintentos
Antes de pasar á seguinte sección (ou mellor dito, á seguinte parte do artigo, porque neste xa non haberá máis experimentos prácticos - aprox. trad.), borrar sa-logic-buggy e VirtualService executando os seguintes comandos:
Estamos a falar de dous patróns importantes na arquitectura de microservizos que che permiten lograr a autorecuperación (autocuración) Servizos.
Circuíto break("interruptor") úsase para finalizar as solicitudes que chegan a unha instancia dun servizo que se considera insalubre e restauralas mentres as solicitudes dos clientes son redirixidas a instancias saudables dese servizo (o que aumenta a porcentaxe de respostas exitosas). (Nota: pódese atopar unha descrición máis detallada do patrón, por exemplo, aquí.)
Mampara("partición") illa os fallos do servizo de afectar a todo o sistema. Por exemplo, o servizo B está roto e outro servizo (o cliente do servizo B) fai unha solicitude ao servizo B, o que fai que esgote o seu grupo de fíos e non poida atender outras solicitudes (aínda que non sexan do servizo B). (Nota: pódese atopar unha descrición máis detallada do patrón, por exemplo, aquí.)
Omitirei os detalles de implementación destes patróns porque son fáciles de atopar documentación oficial, e tamén quero mostrar autenticación e autorización, que se comentarán na seguinte parte do artigo.