
Nota. transl.: 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 .
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 createdO 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 , 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:
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.c7071b22.css
/static/js/main.059f8e9c.js
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.f87cd8c9.css
/static/js/main.f7659dbb.js 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 ():
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1 1 - xerarase hash en función do contido da cabeceira HTTP version.
Aplique a configuración co seguinte comando:
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created Agora executa o seguinte comando e asegúrate de obter os ficheiros correctos cando especifiques a cabeceira version:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep mainNota: Para engadir diferentes valores na cabeceira e probar os resultados directamente no navegador, pode usar a Chrome (Ou para Firefox - aprox. trad.).
En xeral, DestinationRules ten máis capacidades na área do equilibrio de carga. Comprobe os detalles en .
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:
$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions “sa-frontend-green” deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io “sa-frontend” deletedMirroring: servizos virtuais na práctica
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:
$ kubectl get pods -l app=sa-logic --show-labels
NAME READY LABELS
sa-logic-568498cb4d-2sjwj 2/2 app=sa-logic,version=v1
sa-logic-568498cb4d-p4f8c 2/2 app=sa-logic,version=v1
sa-logic-buggy-76dff55847-2fl66 2/2 app=sa-logic,version=v2
sa-logic-buggy-76dff55847-kx8zz 2/2 app=sa-logic,version=v2 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.
Definición de subconxuntos nas regras de destino
Subconxuntos (subconxuntos) están determinadas pola seguinte configuración ():
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-logic
spec:
host: sa-logic # 1
subsets:
- name: v1 # 2
labels:
version: v1 # 3
- name: v2
labels:
version: v2- Anfitrión (
host) define que esta regra só se aplica aos casos en que a ruta vai cara ao servizosa-logic; - Títulos (
name) os subconxuntos utilízanse cando se encamiñan a instancias de subconxuntos; - Etiqueta (
label) define os pares clave-valor que as instancias deben coincidir para formar parte do subconxunto.
Aplique a configuración co seguinte comando:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic createdAgora que os subconxuntos están definidos, podemos avanzar e configurar o VirtualService para aplicar regras ás solicitudes a sa-logic para que:
- Dirixido a un subconxunto
v1, - Espello nun subconxunto
v2.
O seguinte manifesto permíteche conseguir os teus plans ():
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
mirror:
host: sa-logic
subset: v2Non 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 createdEngadimos 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 ():
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 80 # 1
- destination:
host: sa-logic
subset: v2
weight: 20 # 1 1 é o peso (weight), que especifica a porcentaxe de solicitudes que se dirixirán a un destinatario ou a un subconxunto do destinatario.
Actualicemos a configuración anterior de VirtualService para sa-logic co seguinte comando:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured... 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: 500Os 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 ""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,
- ténteo de novo se a solicitude falla.
Para a implementación, utilizaremos a seguinte definición de recurso ():
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 50
- destination:
host: sa-logic
subset: v2
weight: 50
timeout: 8s # 1
retries:
attempts: 3 # 2
perTryTimeout: 3s # 3- 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:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configuredE 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:
$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” deletedPatróns de interruptores e mamparos
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, .)
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, .)
Omitirei os detalles de implementación destes patróns porque son fáciles de atopar , e tamén quero mostrar autenticación e autorización, que se comentarán na seguinte parte do artigo.
PS do tradutor
Lea tamén no noso blog:
- "Volver aos microservizos con Istio": , ;
- «»;
- «».
Fonte: www.habr.com
