Torna als microserveis amb Istio. Part 2

Torna als microserveis amb Istio. Part 2

Nota. transl.: Primera part Aquesta sèrie es va dedicar a presentar les capacitats d'Istio i demostrar-les en acció. Ara parlarem d'aspectes més complexos de la configuració i l'ús d'aquesta malla de servei, i en particular, sobre l'encaminament afinat i la gestió del trànsit de xarxa.

També us recordem que l'article utilitza configuracions (manifests per a Kubernetes i Istio) del repositori istio-mestratge.

gestió del trànsit

Amb Istio, apareixen noves capacitats al clúster per proporcionar:

  • Encaminament dinàmic de sol·licituds: llançaments canaris, proves A/B;
  • Equilibri de càrrega: simple i coherent, basat en hashes;
  • Recuperació després de les caigudes: temps d'espera, reintents, disjuntors;
  • Inserció de falles: retards, sol·licituds abandonades, etc.

A mesura que continua l'article, aquestes capacitats s'il·lustraran utilitzant l'aplicació seleccionada com a exemple i s'introduiran nous conceptes al llarg del camí. El primer concepte d'aquest tipus serà DestinationRules (és a dir, normes sobre el destinatari del trànsit/sol·licituds - traducció aprox.), amb l'ajuda del qual activem les proves A/B.

Prova A/B: Regles de destinació a la pràctica

Les proves A/B s'utilitzen en els casos en què hi ha dues versions d'una aplicació (normalment són visualment diferents) i no estem segurs al 100% de quina millorarà l'experiència de l'usuari. Per tant, executem les dues versions simultàniament i recollim mètriques.

Per implementar la segona versió de la interfície, necessària per demostrar les proves A/B, executeu l'ordre següent:

$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created

El manifest de desplegament de la versió verda difereix en dos llocs:

  1. La imatge es basa en una etiqueta diferent - istio-green,
  2. Les beines tenen una etiqueta version: green.

Com que ambdós desplegaments tenen una etiqueta app: sa-frontend,sol·licituds encaminades pel servei virtual sa-external-services pel servei sa-frontend, es redirigirà a totes les seves instàncies i la càrrega es distribuirà mitjançant algorisme round-robin, que donarà lloc a la situació següent:

Torna als microserveis amb Istio. Part 2
No s'han trobat els fitxers sol·licitats

Aquests fitxers no s'han trobat perquè tenen un nom diferent en diferents versions de l'aplicació. Assegurem-nos d'això:

$ 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

Vol dir això index.html, sol·licitant una versió de fitxers estàtics, l'equilibrador de càrrega es pot enviar a pods que tinguin una versió diferent, on, per raons òbvies, aquests fitxers no existeixen. Per tant, perquè l'aplicació funcioni, hem d'establir una restricció: "la mateixa versió de l'aplicació que va servir index.html hauria de servir les sol·licituds posteriors».

Hi arribarem amb un equilibri de càrrega consistent basat en hash (equilibri de càrrega hash coherent). En aquest cas les sol·licituds del mateix client s'envien a la mateixa instància de backend, per al qual s'utilitza una propietat predefinida, per exemple, una capçalera HTTP. Implementat mitjançant DestinationRules.

Regles de destinació

Després Servei Virtual enviat una sol·licitud al servei desitjat, mitjançant DestinationRules podem definir polítiques que s'aplicaran al trànsit destinat a les instàncies d'aquest servei:

Torna als microserveis amb Istio. Part 2
Gestió del trànsit amb recursos d'Istio

Nota: L'impacte dels recursos d'Istio en el trànsit de xarxa es presenta aquí d'una manera fàcil d'entendre. Concretament, la decisió sobre a quina instància enviar la sol·licitud la pren l'Envoy a la Ingress Gateway configurada al CRD.

Amb les regles de destinació, podem configurar l'equilibri de càrrega per utilitzar hash coherents i assegurar-nos que la mateixa instància de servei respon al mateix usuari. La configuració següent us permet aconseguir-ho (destinationrule-sa-frontend.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sa-frontend
spec:
  host: sa-frontend
  trafficPolicy:
    loadBalancer:
      consistentHash:
        httpHeaderName: version   # 1

1: es generarà hash en funció del contingut de la capçalera HTTP version.

Apliqueu la configuració amb l'ordre següent:

$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created

Ara executeu l'ordre següent i assegureu-vos que obteniu els fitxers correctes quan especifiqueu la capçalera version:

$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep main

Nota: Per afegir diferents valors a la capçalera i provar els resultats directament al navegador, podeu utilitzar aquesta extensió a Chrome (O amb aquest per a Firefox - aprox. trad.).

En general, DestinationRules té més capacitats en l'àrea de l'equilibri de càrrega: comproveu-ne els detalls documentació oficial.

Abans d'estudiar més VirtualService, suprimim la "versió verda" de l'aplicació i la regla de direcció del trànsit corresponent executant les ordres següents:

$ 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” deleted

Mirroring: serveis virtuals a la pràctica

Ombrejat ("protecció") o Mirall ("mirall") s'utilitza en els casos en què volem provar un canvi en la producció sense afectar els usuaris finals: per fer-ho, dupliquem sol·licituds ("mirall") a una segona instància on s'han fet els canvis desitjats i observem les conseqüències. En poques paraules, és quan el vostre col·lega tria el problema més crític i fa una sol·licitud d'extracció en forma d'un gruix de brutícia tan gran que ningú pot revisar-lo.

Per provar aquest escenari en acció, creem una segona instància de SA-Logic amb errors (buggy) executant l'ordre següent:

$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created

I ara executem l'ordre per assegurar-nos que totes les instàncies amb app=sa-logic També tenen etiquetes amb les versions corresponents:

$ 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

Servei sa-logic orienta les beines amb una etiqueta app=sa-logic, de manera que totes les sol·licituds es distribuiran entre totes les instàncies:

Torna als microserveis amb Istio. Part 2

... però volem que les sol·licituds s'enviïn a instàncies v1 i s'hi reflecteixin a instàncies v2:

Torna als microserveis amb Istio. Part 2

Això ho aconseguirem mitjançant VirtualService en combinació amb DestinationRule, on les regles determinaran els subconjunts i les rutes del VirtualService a un subconjunt específic.

Definició de subconjunts a les regles de destinació

Subconjunts (subconjunts) estan determinats per la configuració següent (sa-logic-subsets-destinationrule.yaml):

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

  1. Amfitrió (host) defineix que aquesta norma s'aplica només als casos en què la ruta va cap al servei sa-logic;
  2. Títols (name) els subconjunts s'utilitzen quan s'encaminen a instàncies de subconjunts;
  3. Etiqueta (label) defineix els parells clau-valor que les instàncies han de coincidir per formar part del subconjunt.

Apliqueu la configuració amb l'ordre següent:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created

Ara que els subconjunts estan definits, podem continuar i configurar el VirtualService per aplicar regles a les sol·licituds a sa-logic perquè:

  1. Encaminat a un subconjunt v1,
  2. Replicat a un subconjunt v2.

El següent manifest et permet aconseguir els teus plans (sa-logic-subsets-shadowing-vs.yaml):

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: v2

No cal cap explicació aquí, així que només ho veiem en acció:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created

Afegim la càrrega cridant a l'ordre següent:

$ while true; do curl -v http://$EXTERNAL_IP/sentiment 
    -H "Content-type: application/json" 
    -d '{"sentence": "I love yogobella"}'; 
    sleep .8; done

Mirem els resultats a Grafana, on podeu veure que la versió amb errors (buggy) provoca errors per a un 60% de les sol·licituds, però cap d'aquests errors afecta els usuaris finals, ja que els respon un servei en execució.

Torna als microserveis amb Istio. Part 2
Respostes satisfactòries de diferents versions del servei sa-logic

Aquí vam veure per primera vegada com s'aplica VirtualService als enviats dels nostres serveis: quan sa-web-app fa una petició a sa-logic, passa pel sidecar Envoy, que, mitjançant VirtualService, està configurat per dirigir la sol·licitud al subconjunt v1 i reflectir la sol·licitud al subconjunt v2 del servei. sa-logic.

Ho sé, potser ja penseu que els serveis virtuals són senzills. A la següent secció, ho ampliarem dient que també són realment genials.

Desplegaments de Canàries

Canary Deployment és el procés de llançament d'una nova versió d'una aplicació a un nombre reduït d'usuaris. S'utilitza per assegurar-se que no hi ha problemes en el llançament i només després d'això, ja confiant en la seva qualitat (del llançament), distribuir-lo a altres usuaris.оpúblic més gran.

Per demostrar els llançaments canaris, continuarem treballant amb un subconjunt buggy у sa-logic.

No perdem el temps amb petiteses i enviem immediatament el 20% dels usuaris a la versió amb errors (això representarà el nostre llançament canari) i el 80% restant al servei normal. Per fer-ho, utilitzeu el següent VirtualService (sa-logic-subsets-canary-vs.yaml):

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 és el pes (weight), que especifica el percentatge de sol·licituds que es dirigiran a un destinatari o a un subconjunt del destinatari.

Actualitzem la configuració anterior de VirtualService per sa-logic amb la següent comanda:

$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

... i veurem immediatament que algunes sol·licituds condueixen a errors:

$ 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

Els serveis virtuals permeten llançaments canaris: en aquest cas, hem reduït l'impacte potencial dels problemes al 20% de la base d'usuaris. Meravellós! Ara, en tots els casos quan no estem segurs del nostre codi (és a dir, sempre...), podem utilitzar la rèplica i els llançaments canaris.

Temps morts i reintents

Però els errors no sempre acaben al codi. A la llista de "8 idees errònies sobre la informàtica distribuïda"En primer lloc està la creença errònia que "la xarxa és fiable". En realitat la xarxa no fiable, i per aquest motiu necessitem temps morts (temps morts) i reintents (reintenta).

Per a la demostració, continuarem utilitzant la mateixa versió del problema sa-logic (buggy), i simularem la falta de fiabilitat de la xarxa amb fallades aleatòries.

Deixeu que el nostre servei amb errors tingui 1/3 de possibilitats de trigar massa a respondre, 1/3 de possibilitats d'acabar amb un error intern del servidor i 1/3 de possibilitats de tornar la pàgina correctament.

Per mitigar l'impacte d'aquests problemes i millorar la vida dels usuaris, podem:

  1. afegir un temps d'espera si el servei triga més de 8 segons a respondre,
  2. torna-ho a provar si la sol·licitud falla.

Per a la implementació, utilitzarem la següent definició de recurs (sa-logic-retries-timeouts-vs.yaml):

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

  1. El temps d'espera per a la sol·licitud s'estableix en 8 segons;
  2. Les sol·licituds es tornen a intentar 3 vegades;
  3. I cada intent es considera infructuós si el temps de resposta supera els 3 segons.

Es tracta d'una optimització perquè l'usuari no haurà d'esperar més de 8 segons i farem tres nous intents per obtenir resposta en cas de fallades, augmentant les possibilitats d'una resposta satisfactòria.

Apliqueu la configuració actualitzada amb l'ordre següent:

$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

I comproveu als gràfics de Grafana que el nombre de respostes reeixides ha augmentat més amunt:

Torna als microserveis amb Istio. Part 2
Millores en les estadístiques de resposta correcta després d'afegir temps d'espera i reintents

Abans de passar a la següent secció (o millor dit, a la següent part de l'article, perquè en això no hi haurà més experiments pràctics - aprox. trad.), esborrar sa-logic-buggy i VirtualService executant les ordres següents:

$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” deleted

Patrons d'interruptors i mampares

Estem parlant de dos patrons importants en l'arquitectura de microserveis que permeten aconseguir l'auto-recuperació (autocuració) serveis.

Tallacircuits ("tallacircuits") s'utilitza per finalitzar les sol·licituds que arriben a una instància d'un servei que es considera no saludable i restaurar-la mentre les sol·licituds dels clients es redirigeixen a instàncies saludables d'aquest servei (la qual cosa augmenta el percentatge de respostes satisfactòries). (Nota: es pot trobar una descripció més detallada del patró, per exemple, aquí.)

Cap gros ("partició") aïlla les fallades del servei perquè afectin tot el sistema. Per exemple, el servei B està trencat i un altre servei (el client del servei B) fa una sol·licitud al servei B, fet que fa que esgoti el seu grup de fils i no pugui atendre altres peticions (encara que no siguin del servei B). (Nota: es pot trobar una descripció més detallada del patró, per exemple, aquí.)

Ometré els detalls d'implementació d'aquests patrons perquè són fàcils de trobar documentació oficial, i també vull mostrar l'autenticació i l'autorització, que es parlarà a la següent part de l'article.

PS del traductor

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari