Internetis (service mesh), ja siin on veel ĂŒks. Hooray! Aga miks? Kuna soovin jagada oma arvamust, et oleks parem, kui teenuseahelad oleks ilmunud 10 aastat tagasi enne konteineriplatformide, nagu Docker ja Kubernetes, vĂ€ljatulekut. Ma ei vĂ€ida, et minu seisukoht on parem vĂ”i halvem kui teised, kuid kuna teenuseahelad on ĂŒsna keerulised nĂ€htused, siis mitmekesisus aitab neid paremini mĂ”ista.
RÀÀgin dotCloudi platvormist, mis oli ĂŒles ehitatud rohkem kui sajale mikroteenusele ja toetas tuhandeid rakendusi konteinerites. Selgitan probleeme, millega me silmitsi seisisime selle arendamise ja juurutamise ajal, ja kuidas teenuseahelad oleksid vĂ”inud aidata (vĂ”i mitte).
dotCloudi ajalugu
Olen juba kirjutanud dotCloudi ajaloost ja arhitektuuri valikust selle platvormi jaoks, kuid vĂ€he olen rÀÀkinud vĂ”rgu tasemest. Kui te ei soovi eelmisse artiklisse sĂŒveneda dotCloudi kohta, siis lĂŒhidalt öeldes: see on platvorm teenusena PaaS, mis vĂ”imaldab klientidel kĂ€ivitada laias valikus rakendusi (Java, PHP, Python ...) laiaulatusliku andmete teenuste toetusega (MongoDB, MySQL, Redis ...) ning töökĂ€iguga nagu Heroku: te laadite oma koodi platvormile, see ehitab konteinerite pildid ja juurutab need.
RÀÀgin, kuidas suunati liiklust dotCloudi platvormile. Mitte sellepĂ€rast, et see oleks olnud eriti suurepĂ€rane (kuigi oma aja kohta töötas sĂŒsteem hĂ€sti!), vaid eelkĂ”ige seetĂ”ttu, et tĂ€napĂ€evaste vahendite abil vĂ”ib sellise disaini kiiresti ellu viia tagasihoidlik meeskond, kui neil on vaja liikluse suunamiseks lahendust hulga mikroteenuste vĂ”i rakenduste vahel. Samuti saab vĂ”rrelda valikuid: mis juhtub, kui arendate kĂ”ik ise vĂ”i kasutate olemasolevat teenuseahelat. Tavaline valik: teha ise vĂ”i osta.
Liikluse suunamine hosted rakendustele
dotCloudi rakendused saavad pakkuda HTTP ja TCP lÔpp-punkte.
HTTP lĂ”pp-punktid lisatakse dĂŒnaamiliselt koormuse tasakaalustajate konfiguratsiooni . See on sarnane sellele, mida teevad tĂ€napĂ€eval ressursid Kuberneteses ja koormuse tasakaalustaja nagu .
Kliendid saavad ĂŒhenduda HTTP lĂ”pp-punktidega vastavate domeenide kaudu, eeldusel et domeeninimi osutab dotCloudi koormuse tasakaalustajatele. Pole midagi erilist.
TCP lÔpp-punktid on port number, which is then passed to all containers of this stack via environment variables.
Clients can connect to TCP endpoints using the appropriate hostname (something like gateway-X.dotcloud.com) and port number.
This hostname resolves to a cluster of servers "nats" (not related to ), which will route incoming TCP connections to the correct container (or, in the case of load balanced services, to the correct containers).
If you are familiar with Kubernetes, this might remind you of services .
On the dotCloud platform, there was no equivalent of services : for simplicity, access to services happened equally from inside and outside the platform.
Everything was organized quite simply: the initial implementations of HTTP and TCP routing networks were probably just a few hundred lines of Python. Simple (I would say naive) algorithms that were refined as the platform grew and additional requirements emerged.
Extensive refactoring of the existing code was not required. In particular, can directly use an address obtained via environment variables.
How does this differ from modern service meshes?
Limited observability. We had no metrics at all for the TCP routing grid. As for HTTP routing, later versions introduced detailed HTTP metrics with error codes and response times, but modern service meshes go even further, providing integration with metric collection systems like Prometheus, for example.
Observability is important not only from an operational perspective (to aid in troubleshooting) but also when releasing new features. We're talking about safe ja .
Routing efficiency on samuti piiratud. DotCloudi marsruutimisvĂ”rgus pidi kogu liiklus lĂ€bima pĂŒhendatud marsruutimise sĂ”lmede klastrisse. See tĂ€hendas potentsiaalset mitme AZ (saavailability zone) piiri ĂŒletamist ja mĂ€rkimisvÀÀrset latentsuse suurenemist. MĂ€letan, kuidas lahendasin probleeme koodiga, mis tegi lehe kohta rohkem kui sada SQL-pĂ€ringut ning avas iga pĂ€ringu jaoks uue ĂŒhenduse SQL-serveriga. Kohalikult kĂ€ivitades laadib leht hetkega, kuid dotCloudis kestab laadimine mitu sekundit, kuna iga TCP-ĂŒhenduse (ja sellele jĂ€rgneva SQL-pĂ€ringu) jaoks kulub kĂŒmneid millisekundeid. Selles konkreetses olukorras lahendati probleem pĂŒsivate ĂŒhendustega.
Kaasaegsed teenuste meshid lahendavad selliseid probleeme paremini. Esiteks kontrollivad nad, et ĂŒhendused marsruutides allikast. Loogiline voog on sama: klient â mesh â teenus, kuid nĂŒĂŒd töötab mesh kohalikult, mitte eemal asuvates sĂ”lmedes, seetĂ”ttu on ĂŒhendus klient â mesh kohalik ja vĂ€ga kiire (mikrosekundid, mitte millisekundid).
Kaasaegsed teenuste meshid rakendavad ka nutikamaid koormuse tasakaalustamise algoritme. Kontrollides tagurpidi teenuste töökindlust, saavad nad saata rohkem liiklust kiirematele tagurpidi teenustele, mis viib ĂŒldise jĂ”udluse paranemiseni.
Turvalisus on samuti parem. DotCloudi marsruutimisvĂ”rk töötas tĂ€ielikult EC2 Classicus ja ei krĂŒpteerinud liiklust (pidades silmas, et kui keegi suutis paigaldada snifferi EC2 vĂ”rgu liiklusele, on teil juba tĂ”sised probleemid). Kaasaegsed teenuste meshid kaitsevad meie liiklust lĂ€bipaistvalt, nĂ€iteks vastastikuse TLS-autentimise ja sellele jĂ€rgnenud krĂŒpteerimise abil.
Liikluse marsruutimine platvormi teenustele
Noh, oleme arutanud liiklust rakenduste vahel, kuid kuidas on lood dotCloudi platvormiga endaga?
Platvorm ise koosnes umbes sajast mikroteenusest, mis vastutasid erinevate funktsioonide eest. Ăhed vĂ”tsid vastu pĂ€ringud teistelt, teised olid taustatöötajad, kes ĂŒhendusid teiste teenustega, kuid ei vĂ”tnud ise ĂŒhendusi vastu. Igatahes peab iga teenus teadma lĂ”pp-punkte, millega ĂŒhendust vĂ”tta.
Paljud kĂ”rgema taseme teenused vĂ”ivad kasutada ĂŒlaltoodud marsruutimisvĂ”rku. Tegelikult on paljud dotCloudi ĂŒle saja mikroteenusest juurutatud tavaliste rakendustena dotCloudi platvormil. Kuid vĂ€ike hulk madala taseme teenuseid (eriti need, mis rakendavad seda marsruutimisvĂ”rku) vajas midagi lihtsamat, vĂ€iksemate sĂ”ltuvustega (sest nad ei saanud sĂ”ltuda iseenesest â vana hea kana ja muna probleem).
Need madala taseme, olulised teenused juurutati konteinerite kĂ€ivitamisega otse mitmel peamisel sĂ”lmel. Sellega ei kaasatud platvormi tavaparuseid: komposiit, ajakava ja jooksja. Kui soovite vĂ”rrelda kaasaegsete konteinerite platvormidega, sarnaneb see juhtimistasandi kĂ€ivitamisega docker run otse sĂ”lmedes, selle asemel et delegeerida ĂŒlesanne Kubernetesile. See on ĂŒsna sarnane kontseptsioonile , mida kasutab vĂ”i autonoomse klastrite laadimisel.
Need teenused ekspekteeriti lihtsal ja toorel viisil: YAML-failis loeteldi nende nimed ja aadressid; iga klient pidi juurutamiseks vÔtma koopia sellest YAML-failist.
Ăhelt poolt on see ÀÀrmiselt usaldusvÀÀrne, kuna see ei vaja vĂ€list vĂ”tmete/vÀÀrtuste salvestusruumi, nagu Zookeeper (Ă€rge unustage, et sel ajal et cetd vĂ”i Consul ei eksisteerinud). Teiselt poolt raskendas see teenuste liigutamist. Iga kord, kui teenust liigutati, pidid kĂ”ik kliendid saama vĂ€rskendatud YAML-faili (ja potentsiaalselt taaskĂ€ivituma). Mitte just mugav!
Hiljem hakkasime rakendama uut skeemi, kus iga klient ĂŒhendas kohaliku vaheserveriga. Aadressi ja porti teadmiseks on tal piisavalt ainult teenuse pordi number ning ĂŒhenda lĂ€bi localhost. Kohalik vaheserver haldab seda ĂŒhendust ja suunab selle tegelikule serverile. NĂŒĂŒd, kui taustateenust liigutatakse teisele masinale vĂ”i skaleeritakse, tuleb suure hulga klientide vĂ€rskendamise asemel vĂ€rskendada ainult kĂ”iki neid kohalikke vaheserve; ja taaskĂ€ivitamine ei ole enam vajalik.
(Samuti kavandati salvestada liiklus TLS-ĂŒhendustes ja paigaldada veel ĂŒks vaheserver vastuvĂ”tupoolele, samuti kontrollida TLS-sertifikaate ilma vastuvĂ”tuteenuse osalemiseta, mis on seadistatud ĂŒhenduste vastuvĂ”tmiseks ainult) localhost. (Sellega latter).
See on vĂ€ga sarnane Airbnb'lt, kuid peamine erinevus on see, et SmartStack on ellu viidud ja tootmises, samas kui dotCloud'i sisemine marsruutimissĂŒsteem pandi kinni, kui dotCloud muutus Dockeriks.
Ma arvan isiklikult, et SmartStack on ĂŒks eelkĂ€ijaid sellistele sĂŒsteemidele nagu Istio, Linkerd ja Consul Connect, sest kĂ”ik nad jĂ€rgivad sama mustrit:
- Vaheserveri kÀivitamine igas sÔlmes.
- Kliendid ĂŒhenduvad vaheserveriga.
- Halduse tase uuendab vaheserveri konfiguratsiooni, kui tagaplaneed muutuvad.
- ⊠Kasum!
Kaasaegne teenuse-mesi rakendus
Kui me peame vajalikuks sellist vĂ”rku tĂ€na rakendada, saame kasutada sarnaseid pĂ”himĂ”tteid. NĂ€iteks seadistada sisemine DNS-zona, seostades teenuste nimed aadressidega 127.0.0.0/8. SeejĂ€rel kĂ€ivitada HAProxy igas klastrisĂ”lmes, aktsepteerides ĂŒhendusi igas teenuse aadressis (selles alavĂ”rgus 127.0.0.0/8) ja suunates/koormust tasakaalustades vastavatele tagaplaneedele. HAProxy konfiguratsiooni saab hallata , vĂ”imaldades tagaplaneedi teavet salvestada etcd-s vĂ”i Consulis ning automaatselt edastada uuendatud konfiguratsiooni HAProxy-le, kui see on vajalik.
Nii töötab umbes Istio! Aga mÔningate erinevustega:
- avalikustatakse HAProxy asemel.
- Hoida tagaplaneedi konfiguratsiooni lÀbi Kubernetes API, mitte etcd-s vÔi Consulis.
- Teenustele mÀÀratakse aadressid sisemises alavÔrgus (Kubernetes ClusterIP aadressid) 127.0.0.0/8 asemel.
- Omab tÀiendavat komponenti (Citadel), et lisada TLS-i vastastikust autentimist kliendi ja serverite vahel.
- Toetab uusi funktsioone, nagu ahela katkestamine, jaotatud jÀlgimine, kannujuhtide juurutamine jne.
Vaadakem lĂŒhidalt mĂ”ningaid erinevusi.
Envoy Proxy
Envoy Proxy kirjutas Lyft [konkurent Uberile taksoturul - tĂ”lkija mĂ€rkus]. See sarnaneb suuresti teiste vaheserveritega (nt HAProxy, Nginx, TraefikâŠ), kuid Lyft kirjutas oma, sest neile olid vajalikud funktsioonid, mida teistes vaheserverites ei olnud, ja tundus mĂ”istlikum luua uus, kui olemasolevat laiendada.
Envoy saab kasutada iseseisvalt. Kui mul on konkreetne teenus, mis peab ĂŒhenduma teiste teenustega, saan ma seadistada selle ĂŒhenduma Envoy'ga ning seejĂ€rel dĂŒnaamiliselt konfigureerida ja uuesti seadistada Envoy'd teiste teenuste asukoha mÀÀramisel, saades sealjuures palju suurepĂ€raseid lisafunktsioone, nĂ€iteks jĂ€lgitavuse. Kohandatud kliendi teegiga vĂ”i jĂ€lituskoodi integreerimise asemel suuname liikluse Envoy'le, mis kogub meie jaoks mÔÔdikud.
Kuid Envoy on ka vĂ”imeline töötama kui andmete tasand (data plane) teenuste vĂ”rgu jaoks. See tĂ€hendab, et nĂŒĂŒd konfigureeritakse Envoy selle teenuste vĂ”rgu jaoks kontrolli tasandina (control plane).
Kontrolli tasand
Kontrolli tasandis toetub Istio Kubernetes API-le. See ei erine vÀga confd kasutamisest,mis tugineb etcd-le vÔi Consulile andmehoidlas vÔtmete kogumi vaatamiseks. Istio jÀlgib Kubernetes API kaudu Kubernetes'e ressursside kogumit.
Vahepeal: isiklikult tundus mulle kasulik see , mis ĂŒtleb:
Kubernetes API server on "rumal server", mis pakub salvestamise, versiooni haldamise, valideerimise, uuendamise ja API ressursside semantika teenuseid.
Istio on loodud töötama koos Kubernetes'ega; ja kui soovite seda kasutada vÀljaspool Kubernetes't, peate kÀivitama Kubernetes API serveri eksemplari (ja abiteenusele etcd).
Teenuste aadressid
Istio toetub ClusterIP aadressidele, mida mÀÀrab Kubernetes, nii et Istio teenused saavad sisemise aadressi (mitte vahemikus 127.0.0.0/8).
Liiklus ClusterIP aadressile konkreetse teenuse jaoks Kubernetes klastris ilma Istio't, vĂ”etakse kinni kube-proxy poolt ja suunatakse selle proxy teenuse serveri osasse. Kui teid huvitavad tehnilised detailid, siis kube-proxy seadistab iptables reeglid (vĂ”i IPVS koormuse jagajad, sĂ”ltuvalt sellest, kuidas see on seadistatud), et kirjutada sihtaadresside IP-aadresse ĂŒmber, mis saadetakse ClusterIP aadressile.
PÀrast Istio seadistamist Kubernetes klastris ei muutu midagi, kuni see ei ole selgelt aktiveeritud selle tarbija vÔi isegi kogu nimede ruumi jaoks, sisestades konteineri sidecar kohandatud podidesse. See konteiner kÀivitab Envoy eksemplari ja seadistab rea iptables reegleid, et vÔtta kinni liiklus, mis lÀheb teistesse teenustesse, ning suunata see liiklus Envoy'le.
Kubernetes DNS integreerimisel tĂ€hendab see, et meie kood saab ĂŒhenduda teenuse nime kaudu ja kĂ”ik "lihtsalt töötab". TeisisĂ”nu, meie kood saadab pĂ€ringuid, nagu http://api/v1/users/4242, siis api lahendab pĂ€ringu aadressile 10.97.105.48, iptables reeglid pĂŒĂŒavad kinni ĂŒhendused aadressilt 10.97.105.48 ja suunavad need kohaliku Envoy-proksisse, mis suunab pĂ€ringu tegelikule API-tagaplaanile. Pfuh!
TĂ€psemad detailid
Istio pakub ka otseƥifreerimist ja autentimist lÀbi mTLS (vastastikune TLS). Selle eest vastutab komponent, mille nimi on Citadel.
Lisaks on olemas komponent Mixer, mida Envoy saab kĂŒsida of each pĂ€ringu osas, et teha erilisi otsuseid selle pĂ€ringu kohta erinevate tegurite, nagu pĂ€ised, tagaplaanide koormus jms, pĂ”hjal... (Ă€rge muretsege: on palju viise, kuidas tagada Mixer'i töö; isegi kui see ebaĂ”nnestub, toimib Envoy endiselt normaalselt proksina).
Ja loomulikult mainisime jĂ€lgitavust: Envoy kogub tohutul hulgal metrikoone, pakkudes samas jaotatud jĂ€lgitavust. Mikroteenuste arhitektuuris, kui ĂŒks API pĂ€ring peab lĂ€bima mikroteenused A, B, C ja D, lisab jaotatud jĂ€lgitavus sĂŒsteemi sisenedes pĂ€ringule ainulaadse identifikaatori ja hoiab seda identifikaatorit alampĂ€ringutes kĂ”igis neist mikroteenustest, vĂ”imaldades salvestada kĂ”ik seotud kutsed, nende viivitused jne.
Arendada vÔi osta
Istio maine on keerulise sĂŒsteemina. Vastupidi, selle marsruudivĂ”rgu loomine, mida ma selle postituse alguses kirjeldasin, on olemasolevate tööriistade abil suures osas lihtne. Nii et kas on mĂ”tet luua oma teenuse mesh selle asemel?
Kui meie vajadused on tagasihoidlikud (ei vaja jĂ€lgitavust, aasema katkestajat ja muid peensusi), siis tekivad mĂ”tted oma tööriista arendamise ĂŒle. Kuid kui me kasutame Kubernetes't, vĂ”ib see isegi mitte vajalik olla, kuna Kubernetes pakub juba baasvahendeid teenuste avastamiseks ja koormuse tasakaalustamiseks.
Aga kui meie nĂ”uded on keerulisemad, tundub, et teenuse mesh âostmineâ on palju parem variant. (See ei tĂ€henda alati just âostmistâ, kuna Istio on avatud lĂ€htekoodiga, kuid meil on ikkagi vajalik investeerida inseneri aega, et mĂ”ista selle toimimist, juurutada ja hallata).
Kuidas valida: Istio, Linkerd vÔi Consul Connect?
Kuigi oleme seni rÀÀkinud ainult Istio-st, ei ole see ainus teenuse vahejuht. Populaarne alternatiiv on , ning on veel .
Mida valida?
Ausalt öeldes ei tea ma. Praegu ei pea ma end selle kĂŒsimuse vastamiseks piisavalt pĂ€devaks. On mitmeid vĂ”rdlusi nende tööriistade vahel ja isegi .
Ăks paljulubavaid lĂ€henemisviise on kasutada tööriista nagu . See rakendab abstraktsioonikihi, et lihtsustada ja ĂŒhtlustada API-sid, mida teenuse vahejuht pakub. Selle asemel, et Ă”ppida tundma erinevate (ja minu arvates suhteliselt keeruliste) teenuse vahejuhi API-sid, saame kasutada lihtsamaid konstruktsioone SuperGloo - ja vahetada sujuvalt ĂŒhelt teisele, justkui oleks meil vahelahendus, mis kirjeldab HTTP-liideseid ja taustateenuseid, suudab genereerida reaalse konfiguratsiooni Nginx, HAProxy, Traefik, Apache... jaoks.
Olen natuke katsetanud Istio ja SuperGloo, ning jĂ€rgmises artiklis soovin nĂ€idata, kuidas lisada Istio vĂ”i Linkerd olemasolevasse klastrisse SuperGloo abil, ja kui hĂ€sti viimane oma tööga hakkama saab, s.o vĂ”imaldades vahetada ĂŒhelt teenuse vahejuhtilt teisele ilma konfiguratsioonide ĂŒmberkirjutamiseta.
Allikas: habr.com
