Containers, microservizi è rete di serviziu

In internet un muntuni articuli о rete di serviziu (maglia di serviziu), è eccu un altru. Eura! Ma perchè ? Allora, vogliu sprime a mo opinione chì saria megliu se e rete di serviziu apparsu 10 anni fà, prima di l'avventu di e plataforme di cuntainer cum'è Docker è Kubernetes. Ùn dicu micca chì u mo puntu di vista hè megliu o peggiu di l'altri, ma postu chì e rete di serviziu sò animali abbastanza cumplessi, parechji punti di vista aiutanu à capiscenu megliu.

Parlaraghju di a piattaforma dotCloud, chì hè stata custruita nantu à più di un centu di microservizi è supportatu millaie di applicazioni containerizzate. Spiegheraghju e sfide chì avemu affruntatu in u sviluppu è u lanciamentu, è cumu e rete di serviziu puderanu (o ùn pudianu micca) aiutà.

Storia di dotCloud

Aghju scrittu annantu à a storia di dotCloud è l'scelti di l'architettura per sta piattaforma, ma ùn aghju micca parlatu assai di a strata di a rete. Se ùn vulete micca immerse in a lettura ultimu articulu nantu à dotCloud, eccu l'essenza in poche parole: hè una piattaforma PaaS-as-a-service chì permette à i clienti di gestisce una larga gamma di applicazioni (Java, PHP, Python...), cù supportu per una larga gamma di dati. servizii (MongoDB, MySQL, Redis...) è un flussu di travagliu cum'è Heroku: Caricate u vostru còdice à a piattaforma, custruisce l'imaghjini di u containeru è li implementa.

Vi diceraghju cumu u trafficu hè statu direttu à a piattaforma dotCloud. Micca perchè era particularmente cool (ancu se u sistema hà travagliatu bè per u so tempu!), Ma soprattuttu perchè cù l'arnesi muderni un tali disignu pò esse facilmente implementatu in pocu tempu da una squadra modesta s'ellu ci hè bisognu di un modu per indirizzà u trafficu trà un gruppu. di microservizi o una mansa di applicazioni. In questu modu, pudete paragunà l'opzioni: ciò chì succede s'ellu si sviluppa tuttu sè stessu o utilizate una rete di serviziu esistenti. A scelta standard hè di fà sè stessu o cumprà.

Instradamentu di u trafficu per l'applicazioni ospitate

L'applicazioni nantu à dotCloud ponu espose i punti finali HTTP è TCP.

Punti finali HTTP aghjuntu dinamicamente à a cunfigurazione di cluster di bilanciatore di carica Hipache. Questu hè simile à ciò chì i risorse facenu oghje Ingress in Kubernetes è un equilibratore di carica cum'è Traefic.

I clienti si cunnettanu à i punti finali HTTP per mezu di domini appropritati, sempre chì u nome di u duminiu punta à i bilanciatori di carica dotCloud. Nunda di speciale.

Punti finali TCP assuciatu cù un numeru di portu, chì hè dopu passatu à tutti i cuntenituri in quella pila per via di variabili ambientali.

I clienti ponu cunnette à i punti finali TCP utilizendu u nome d'ospitu adattatu (qualcosa cum'è gateway-X.dotcloud.com) è u numeru di portu.

Questu hostname si risolve à u cluster di servitori "nats" (micca ligatu à NATS), chì indirizzanu e cunnessione TCP entranti à u containeru currettu (o, in u casu di servizii equilibrati di carica, à i cuntenituri curretti).

Sè vo site familiarizatu cù Kubernetes, questu probabilmente vi ricurdarà i servizii NodePort.

Ùn ci era micca servizii equivalenti nantu à a piattaforma dotCloud ClusterIP: Per simplicità, i servizii sò stati accessu da a listessa manera sia da l'internu sia fora di a piattaforma.

Tuttu era urganizatu abbastanza simplice: l'implementazioni iniziali di e rete di routing HTTP è TCP eranu prubabilmente solu uni pochi di centu linee di Python ognunu. Algoritmi simplici (à dìcenu ingenu) chì sò stati raffinati cum'è a piattaforma hà crisciutu è apparsu esigenze supplementari.

Un refactoring estensivu di u codice esistente ùn era micca necessariu. In particulare, App di 12 fattori ponu aduprà direttamente l'indirizzu ottenutu attraversu e variabili di l'ambiente.

Cumu hè questu sfarente da una maglia di serviziu mudernu?

Limitatu visibilità. Ùn avemu micca metrica per a maglia di routing TCP in tuttu. Quandu si tratta di u routing HTTP, e versioni successive anu introduttu metriche HTTP dettagliate cù codici d'errore è tempi di risposta, ma e maglie di serviziu muderni vanu ancu più luntanu, furnisce integrazione cù sistemi di cullizzioni di metriche cum'è Prometheus, per esempiu.

A visibilità hè impurtante micca solu da una perspettiva operativa (per aiutà à risolve i prublemi), ma ancu quandu liberate novi funzioni. Si tratta di sicuru implementazione blu-verde и implementazione canaria.

Efficienza di routing hè ancu limitatu. In a maglia di routing dotCloud, tuttu u trafficu avia da passà per un cluster di nodi di routing dedicati. Questu significava potenzalmentu attraversà parechje frontiere AZ (Zona di Disponibilità) è aumenta significativamente a latenza. Mi ricordu di u codice di risoluzione di prublemi chì facia più di centu dumande SQL per pagina è apre una nova cunnessione à u servitore SQL per ogni dumanda. Quandu si eseguisce in u locu, a pagina si carica istantaneamente, ma in dotCloud ci vole uni pochi di seconde per carica perchè ogni cunnessione TCP (è a dumanda SQL successiva) piglia decine di millisecondi. In questu casu particulari, ligami persistenti risolve u prublema.

E maglie di serviziu muderni sò megliu per trattà tali prublemi. Prima di tuttu, verificanu chì e cunnessione sò instradati in a fonte. U flussu logicu hè u listessu: клиент → меш → сервис, ma avà a mesh travaglia in u locu è micca in i nodi remoti, cusì a cunnessione клиент → меш hè lucale è assai veloce (microsecondi invece di millisecondi).

E maglie di serviziu muderni implementanu ancu algoritmi di bilanciamentu di carica più intelligenti. Monitorendu a salute di i backends, ponu mandà più trafficu à backends più veloci, risultatu in un rendiment generale megliu.

Seguretat megliu ancu. A maglia di routing dotCloud hè stata interamente nantu à EC2 Classic è ùn hà micca criptatu u trafficu (basatu nantu à l'assunzione chì se qualchissia hà sappiutu mette un sniffer in u trafficu di a rete EC2, era digià in grande prublema). E maglie di serviziu muderni prutegge in modu trasparente tuttu u nostru trafficu, per esempiu, cù l'autentificazione TLS mutuale è a criptografia successiva.

Instradamentu di u trafficu per i servizii di piattaforma

Va bè, avemu discututu u trafficu trà l'applicazioni, ma chì ne di a piattaforma dotCloud stessu?

A piattaforma stessa era custituita da un centu di microservizi rispunsevuli di diverse funzioni. Certi anu accettatu richieste da l'altri, è alcuni eranu travagliadori di fondo chì anu cunnessu à altri servizii, ma ùn anu micca accettatu e cunnessione stessi. In ogni casu, ogni serviziu deve cunnosce i punti finali di l'indirizzi à quale deve cunnette.

Parechji servizii d'altu livellu ponu utilizà a maglia di routing descritta sopra. In fatti, assai di i più di centu microservizi di dotCloud sò stati implementati cum'è applicazioni regularmente nantu à a piattaforma dotCloud stessu. Ma un picculu numeru di servizii di livellu bassu (in particulare quelli chì implementanu sta maglia di routing) avianu bisognu di qualcosa di più simplice, cù menu dependenzii (poi ch'elli ùn puderanu micca dipende di elli stessi per travaglià - u prublema di u bonu vechju di pollo è ovu).

Questi servizii di bassu livellu, critichi di missione sò stati implementati da eseguisce cuntenituri direttamente nantu à uni pochi di nodi chjave. In questu casu, i servizii di piattaforma standard ùn sò micca stati utilizati: linker, scheduler è runner. Se vulete paragunà cù e plataforme di cuntainer muderni, hè cum'è corre un pianu di cuntrollu cù docker run direttamente nantu à i nodi, invece di delegate u compitu à Kubernetes. Hè abbastanza simile in u cuncettu moduli statici (pods), chì usa kubeadm o bootkube quandu si avvia un cluster standalone.

Questi servizii sò stati esposti in una manera simplice è cruda: un schedariu YAML hà listatu i so nomi è l'indirizzi; è ogni cliente avia da piglià una copia di stu schedariu YAML per a distribuzione.

Da una banda, hè estremamente affidabile perchè ùn hà micca bisognu di u supportu di una chjave esterna / magazzini di valore cum'è Zookeeper (ricurdate, etcd o Consul ùn esiste micca à quellu tempu). Per d 'altra banda, hà fattu difficiule di trasfurmà i servizii. Ogni volta chì una mossa hè stata fatta, tutti i clienti riceveranu un schedariu YAML aghjurnatu (è potenzialmente reboot). Micca assai còmode!

In seguitu, avemu cuminciatu à implementà un novu schema, induve ogni cliente hè cunnessu à un servitore proxy locale. Invece di un indirizzu è portu, solu bisognu di cunnosce u numeru portu di u serviziu, è cunnette via localhost. U proxy locale gestisce sta cunnessione è a trasmette à u servitore propiu. Avà, quandu si move u backend à una altra macchina o scala, invece di aghjurnà tutti i clienti, avete solu bisognu di aghjurnà tutti questi proxy lucali; è un reboot ùn hè più necessariu.

(Hè statu ancu pianificatu di incapsulà u trafficu in cunnessione TLS è mette un altru servitore proxy à u latu di ricivutu, è ancu di verificà i certificati TLS senza a participazione di u serviziu di ricezione, chì hè cunfiguratu per accettà cunnessione solu in localhost. Più nantu à questu dopu).

Questu hè assai simili à SmartStack da Airbnb, ma a diferenza significativa hè chì SmartStack hè implementatu è implementatu à a pruduzzione, mentre chì u sistema di routing internu di dotCloud hè stata abbandunata quandu dotCloud hè diventatu Docker.

Cunsideru personalmente SmartStack per esse unu di i predecessori di sistemi cum'è Istio, Linkerd è Consul Connect perchè tutti seguitanu u listessu mudellu:

  • Eseguite un proxy in ogni nodu.
  • I clienti cunnettanu à u proxy.
  • U pianu di cuntrollu aghjurnà a cunfigurazione proxy quandu i backend cambianu.
  • ... Prufittu !

Implementazione muderna di una rete di serviziu

Se avemu bisognu di implementà una griglia simili oghje, pudemu usà principii simili. Per esempiu, cunfigurà una zona DNS interna mapping names service à l'indirizzi in u spaziu 127.0.0.0/8. Allora eseguite HAProxy nantu à ogni nodu in u cluster, accettendu cunnessione à ogni indirizzu di serviziu (in quella subnet 127.0.0.0/8) è redirezzione / equilibriu a carica à i backends appropritati. A cunfigurazione HAProxy pò esse cuntrullata cunfd, chì vi permette di almacenà l'infurmazioni backend in etcd o Consul è automaticamente spinghje a cunfigurazione aghjurnata à HAProxy quandu hè necessariu.

Questu hè quasi cumu travaglia Istio! Ma cù qualchi differenzi:

  • Usi Envoy Proxy invece di HAProxy.
  • Memorizza a configurazione di backend via l'API Kubernetes invece di etcd o Consul.
  • I servizii sò attribuiti indirizzi nantu à a subnet interna (indirizzi Kubernetes ClusterIP) invece di 127.0.0.0/8.
  • Hà un cumpunente supplementu (Citadella) per aghjunghje l'autentificazione TLS mutuale trà u cliente è i servitori.
  • Supporta funzioni novi cum'è circuit breaking, traccia distribuita, implementazione canaria, etc.

Fighjemu un pocu di e sfarenze.

Envoy Proxy

Envoy Proxy hè statu scrittu da Lyft [u cuncurrente di Uber in u mercatu di taxi - circa. corsia]. Hè simile in parechje manere à l'altri proxy (per esempiu HAProxy, Nginx, Traefik...), ma Lyft hà scrittu u so perchè avianu bisognu di funziunalità chì l'altri proxies mancavanu, è pareva più intelligente per fà un novu piuttostu chè allargà l'esistente.

Envoy pò esse usatu per sè stessu. Se aghju un serviziu specificu chì deve cunnette cù altri servizii, possu cunfigurà per cunnette à Envoy, è poi cunfigurà dinamicamente è cunfigurà Envoy cù u locu di l'altri servizii, mentre uttene assai funziunalità supplementari, cum'è visibilità. Invece di una biblioteca di clientele persunalizata o injecting call traces in u codice, mandemu u trafficu à Envoy, è raccoglie metriche per noi.

Ma Envoy hè ancu capaci di travaglià cum'è pianu di dati (pianu di dati) per a rete di serviziu. Questu significa chì Envoy hè avà cunfiguratu per questa rete di serviziu pianu di cuntrollu (pianu di cuntrollu).

Aviò di cuntrollu

Per u pianu di cuntrollu, Istio si basa nantu à l'API Kubernetes. Questu ùn hè micca assai sfarente di l'usu di confd, chì s'appoghja nantu à etcd o Consul per vede u settore di chjave in a data store. Istio usa l'API Kubernetes per vede un set di risorse Kubernetes.

Trà questu è allora: Personalmente aghju trovu questu utile Descrizzione di l'API Kuberneteschì leghje:

U Kubernetes API Server hè un "servitore stupidu" chì offre almacenamentu, versione, validazione, aghjurnamentu è semantica per e risorse API.

Istio hè pensatu per travaglià cù Kubernetes; è se vulete usà fora di Kubernetes, allora avete bisognu di eseguisce una istanza di u servitore API Kubernetes (è u serviziu d'aiutu etcd).

Indirizzi di serviziu

Istio s'appoghja nantu à l'indirizzi ClusterIP chì Kubernetes attribuisce, cusì i servizii Istio ricevenu un indirizzu internu (micca in u intervalu). 127.0.0.0/8).

U trafficu à l'indirizzu ClusterIP per un serviziu specificu in un cluster Kubernetes senza Istio hè interceptatu da kube-proxy è mandatu à u backend di quellu proxy. Sè site interessatu in i dettagli tecnichi, kube-proxy stabilisce e regule iptables (o equilibratori di carica IPVS, secondu cumu hè cunfiguratu) per riscrive l'indirizzi IP di destinazione di e cunnessione chì vanu à l'indirizzu ClusterIP.

Una volta Istio hè stallatu nantu à un cluster Kubernetes, nunda ùn cambia finu à ch'ellu hè attivatu esplicitamente per un cunsumu determinatu, o ancu tuttu u spaziu di nomi, introducendu un containeru. sidecar in pods persunalizati. Stu cuntainer spingerà un'istanza di Envoy è stabilisce un settore di reguli iptables per interceptà u trafficu chì và à altri servizii è redirige u trafficu à Envoy.

Quandu hè integratu cù Kubernetes DNS, questu significa chì u nostru codice pò cunnette per nome di serviziu è tuttu "funziona solu". In altre parolle, u nostru codice emette dumande cum'è http://api/v1/users/4242allora api risolve a dumanda di 10.97.105.48, e regule iptables intercepte e cunnessione da 10.97.105.48 è trasmettenu à u proxy Envoy locale, è quellu proxy lucale trasmetterà a dumanda à l'API backend attuale. Uff!

Fulmini supplementari

Istio furnisce ancu crittografia è autentificazione end-to-end via mTLS (TLS mutuale). Un cumpunente chjamatu Citadella.

Ci hè ancu un cumpunente Mixer, chì Envoy pò dumandà di ognunu dumanda à piglià una decisione speciale nantu à quella dumanda secondu parechji fatturi, cum'è headers, backend load, etc... (ùn vi preoccupate micca: ci sò parechje manere di mantene Mixer in funziunamentu, è ancu s'ellu crash, Envoy continuarà à travaglià. bè cum'è proxy).

E, sicuru, avemu citatu a visibilità: Envoy raccoglie una quantità enorme di metriche mentre furnisce traccia distribuita. In una architettura di microservizi, se una sola dumanda API deve passà per i microservizi A, B, C è D, dopu à u login, u tracciamentu distribuitu aghjunghje un identificatore unicu à a dumanda è almacenà stu identificatore per mezu di sottorequests à tutti questi microservizi, chì permette tutte e chiamate cunnesse per esse catturate, ritardi, etc.

Sviluppà o cumprà

Istio hà a reputazione di esse cumplessu. In cuntrastu, a custruzzione di a rete di routing chì aghju descrittu à l'iniziu di stu post hè relativamente simplice cù l'arnesi esistenti. Allora, hè sensu di creà a vostra propria rete di serviziu invece?

Se avemu bisognu modestu (ùn avemu micca bisognu di visibilità, un circuit breaker è altre suttilità), allora i pinsamenti venenu à sviluppà u nostru propiu strumentu. Ma se usemu Kubernetes, ùn pò ancu esse necessariu perchè Kubernetes furnisce digià strumenti basi per a scuperta di serviziu è u bilanciamentu di carica.

Ma s'ellu avemu esigenze avanzate, allora "acquistà" una rete di serviziu pare esse una opzione assai megliu. (Questu ùn hè micca sempre un "acquistu" perchè Istio hè open source, ma avemu sempre bisognu di investisce u tempu di l'ingenieria per capiscenu, implementà è gestisce).

Deve sceglie Istio, Linkerd o Consul Connect?

Finu a ora avemu parlatu solu di Istio, ma questu ùn hè micca l'unicu maglia di serviziu. Alternativa populari - Linkerd, è ci hè più Cunnessu Consul.

Chì per elettu?

Onestamente, ùn sò micca. À u mumentu ùn mi cunsiderà micca abbastanza cumpetente per risponde à sta quistione. Ci sò uni pochi interessante articuli cun un paragone di sti arnesi è ancu benchmarks.

Un approcciu promettenti hè di utilizà un strumentu cum'è SuperGloo. Implementa una strata di astrazione per simplificà è unificà l'API esposte da e rete di serviziu. Invece di amparà l'API specifiche (è, in u mo parè, relativamente cumplessu) di diverse maglie di serviziu, pudemu usà e custruzzioni più simplici di SuperGloo - è facilmente passà da una à l'altra, cum'è s'ellu avia un furmatu di cunfigurazione intermediu chì descrive interfacce HTTP è backend capaci. di generà a cunfigurazione attuale per Nginx, HAProxy, Traefik, Apache...

Aghju dabbled un pocu cù Istio è SuperGloo, è in u prossimu articulu vogliu dimustrà cumu aghjunghje Istio o Linkerd à un cluster esistente cù SuperGloo, è cumu questu l'ultimu faci u travagliu, vale à dì, permette di cambià da una maglia di serviziu à l'altru senza sovrascrive e cunfigurazioni.

Source: www.habr.com

Add a comment