Kontit, mikropalvelut ja palveluverkot

Internetissä pino artikkelit о palveluverkko (palveluverkko), ja tässä on toinen. Hurraa! Mutta miksi? Sitten haluan ilmaista mielipiteeni, että olisi ollut parempi, jos palveluverkot ilmestyisivät 10 vuotta sitten, ennen konttialustojen, kuten Dockerin ja Kubernetesin, tuloa. En väitä, että minun näkökulmani on parempi tai huonompi kuin muut, mutta koska palveluverkot ovat melko monimutkaisia ​​eläimiä, useat näkökulmat auttavat ymmärtämään niitä paremmin.

Puhun dotCloud-alustasta, joka rakennettiin yli sataan mikropalveluun ja tuki tuhansia konttisovelluksia. Selitän haasteita, joita kohtasimme sen kehittämisessä ja lanseerauksessa, ja kuinka palveluverkot voisivat (tai eivät) auttaa.

dotCloudin historia

Olen kirjoittanut dotCloudin historiasta ja tämän alustan arkkitehtuurivalinnoista, mutta en ole puhunut paljon verkkokerroksesta. Jos et halua sukeltaa lukemiseen viimeinen artikkeli dotCloudista, tässä on ydin pähkinänkuoressa: se on PaaS-alusta palveluna, jonka avulla asiakkaat voivat käyttää monenlaisia ​​sovelluksia (Java, PHP, Python...) ja tukea monenlaista dataa palvelut (MongoDB, MySQL, Redis...) ja työnkulku, kuten Heroku: Lataat koodisi alustalle, se rakentaa konttikuvat ja ottaa ne käyttöön.

Kerron kuinka liikenne ohjattiin dotCloud-alustalle. Ei siksi, että se olisi erityisen siistiä (vaikka järjestelmä toimi hyvin omaan aikaansa!), vaan ennen kaikkea siksi, että nykyaikaisilla työkaluilla tällainen suunnittelu on helppo toteuttaa lyhyessä ajassa vaatimattomalle tiimille, jos he tarvitsevat tavan ohjata liikennettä joukon välillä. mikropalveluista tai joukosta sovelluksia. Näin voit vertailla vaihtoehtoja: mitä tapahtuu, jos kehität kaiken itse tai käytät olemassa olevaa palveluverkkoa. Vakiovalinta on tehdä se itse tai ostaa.

Liikenteen reititys isännöidyille sovelluksille

DotCloudin sovellukset voivat paljastaa HTTP- ja TCP-päätepisteitä.

HTTP-päätepisteet lisätty dynaamisesti kuormantasausklusterin kokoonpanoon Hipache. Tämä on samanlaista kuin mitä resurssit tekevät nykyään Sisääntulo Kubernetesissa ja kuormituksen tasapainottimessa, kuten Traefik.

Asiakkaat muodostavat yhteyden HTTP-päätepisteisiin asianmukaisten verkkotunnusten kautta edellyttäen, että verkkotunnuksen nimi osoittaa dotCloud-kuormituksen tasapainottajiin. Ei mitään erityistä.

TCP-päätepisteet liittyy porttinumeroon, joka välitetään sitten kaikkiin pinon säilöihin ympäristömuuttujien kautta.

Asiakkaat voivat muodostaa yhteyden TCP-päätepisteisiin käyttämällä asianmukaista isäntänimeä (kuten gateway-X.dotcloud.com) ja porttinumeroa.

Tämä isäntänimi ratkaisee "nats"-palvelinklusterin (ei liity NATS), joka reitittää saapuvat TCP-yhteydet oikeaan säilöön (tai kuormitustasattujen palvelujen tapauksessa oikeisiin säilöihin).

Jos tunnet Kubernetesin, tämä todennäköisesti muistuttaa sinua Palveluista Solmuportti.

DotCloud-alustalla ei ollut vastaavia palveluita KlusteriIP: Yksinkertaisuuden vuoksi palveluihin päästiin samalla tavalla sekä alustan sisältä että ulkopuolelta.

Kaikki järjestettiin yksinkertaisesti: HTTP- ja TCP-reititysverkkojen alkuperäiset toteutukset olivat luultavasti vain muutama sata Python-riviä kumpikin. Yksinkertaiset (sanoisin naiivit) algoritmit, joita jalostettiin alustan kasvaessa ja lisävaatimuksia ilmaantuessa.

Olemassa olevan koodin laajaa refaktorointia ei tarvittu. Erityisesti, 12 tekijän sovellukset voi käyttää suoraan ympäristömuuttujien kautta saatua osoitetta.

Miten tämä eroaa nykyaikaisesta palveluverkosta?

Rajoitettu näkyvyys. Meillä ei ollut lainkaan mittareita TCP-reititysverkolle. Mitä tulee HTTP-reitittämiseen, myöhemmissä versioissa esiteltiin yksityiskohtaisia ​​HTTP-mittareita virhekoodeilla ja vasteajoilla, mutta nykyaikaiset palveluverkot menevät vielä pidemmälle tarjoamalla integraation mittareiden keruujärjestelmiin, kuten esimerkiksi Prometheus.

Näkyvyys on tärkeä paitsi toiminnallisesta näkökulmasta (auttaa vianmääritykseen), mutta myös uusia ominaisuuksia julkaistaessa. Kyse on turvallisuudesta sinivihreä käyttöönotto и kanarialaisten käyttöönotto.

Reitityksen tehokkuus on myös rajoitettu. DotCloud-reititysverkossa kaiken liikenteen piti kulkea omistettujen reitityssolmujen klusterin läpi. Tämä tarkoitti mahdollisesti useiden AZ (Availability Zone) -rajojen ylittämistä ja merkittävästi lisäävää latenssia. Muistan vianmäärityskoodin, joka teki yli sata SQL-kyselyä sivua kohden ja avasi uuden yhteyden SQL-palvelimeen jokaiselle kyselylle. Paikallisesti suoritettaessa sivu latautuu välittömästi, mutta dotCloudissa sen latautuminen kestää muutaman sekunnin, koska jokainen TCP-yhteys (ja sitä seuraava SQL-kysely) vie kymmeniä millisekunteja. Tässä nimenomaisessa tapauksessa jatkuvat yhteydet ratkaisivat ongelman.

Nykyaikaiset palveluverkot selviävät paremmin tällaisista ongelmista. Ensinnäkin he tarkistavat, että yhteydet on reititetty lähteessä. Looginen kulku on sama: клиент → меш → сервис, mutta nyt mesh toimii paikallisesti eikä etäsolmuissa, joten yhteys клиент → меш on paikallinen ja erittäin nopea (mikrosekunteja millisekuntien sijasta).

Nykyaikaiset palveluverkot toteuttavat myös älykkäämpiä kuormituksen tasapainotusalgoritmeja. Seuraamalla taustaohjelmien kuntoa ne voivat lähettää enemmän liikennettä nopeampiin taustajärjestelmiin, mikä parantaa yleistä suorituskykyä.

Безопасность parempi myös. DotCloud-reititysverkko kulki kokonaan EC2 Classicissa eikä salannut liikennettä (olettaen, että jos joku onnistui laittamaan haistelijan EC2-verkkoliikenteeseen, olit jo suurissa vaikeuksissa). Nykyaikaiset palveluverkot suojaavat läpinäkyvästi kaikkea liikennettämme esimerkiksi keskinäisellä TLS-todennuksella ja myöhemmällä salauksella.

Liikenteen reitittäminen alustapalveluille

Okei, olemme keskustelleet sovellusten välisestä liikenteestä, mutta entä itse dotCloud-alusta?

Itse alusta koostui noin sadasta eri toiminnoista vastaavasta mikropalvelusta. Jotkut ottivat vastaan ​​pyyntöjä muilta, ja jotkut olivat taustatyöntekijöitä, jotka liittyivät muihin palveluihin, mutta eivät itse hyväksyneet yhteyksiä. Joka tapauksessa jokaisen palvelun on tiedettävä niiden osoitteiden päätepisteet, joihin sen on muodostettava yhteys.

Monet korkean tason palvelut voivat käyttää yllä kuvattua reititysverkkoa. Itse asiassa monet dotCloudin yli sadasta mikropalvelusta on otettu käyttöön tavallisina sovelluksina itse dotCloud-alustalla. Mutta pieni määrä matalan tason palveluita (erityisesti ne, jotka toteuttavat tämän reititysverkon) tarvitsi jotain yksinkertaisempaa, vähemmän riippuvuuksia (koska ne eivät voineet riippua itsestään - vanha kunnon kana ja muna -ongelma).

Nämä matalan tason, kriittiset palvelut otettiin käyttöön ajamalla kontteja suoraan muutamissa tärkeissä solmuissa. Tässä tapauksessa ei käytetty vakioalustapalveluita: linkittäjä, ajoitus ja juoksija. Jos haluat verrata nykyaikaisiin konttialustoihin, se on kuin ohjaisi ohjauskonetta docker run suoraan solmuissa sen sijaan, että delegoisit tehtävän Kubernetesille. Se on konseptiltaan aika samanlainen staattiset moduulit (podit), jota se käyttää kubeadm tai bootkube kun käynnistät erillisen klusterin.

Nämä palvelut paljastettiin yksinkertaisella ja karkealla tavalla: YAML-tiedosto listasi niiden nimet ja osoitteet; ja jokaisen asiakkaan oli otettava kopio tästä YAML-tiedostosta käyttöönottoa varten.

Toisaalta se on erittäin luotettava, koska se ei vaadi ulkoisen avain-/arvovaraston, kuten Zookeeperin tukea (muista, etcd tai Consul ei ollut olemassa tuolloin). Toisaalta se vaikeutti palveluiden siirtämistä. Joka kerta kun siirto tehdään, kaikki asiakkaat saavat päivitetyn YAML-tiedoston (ja mahdollisesti uudelleenkäynnistyksen). Ei kovin mukavaa!

Myöhemmin aloimme ottaa käyttöön uutta järjestelmää, jossa jokainen asiakas liittyi paikalliseen välityspalvelimeen. Osoitteen ja portin sijaan sen tarvitsee vain tietää palvelun portin numero ja muodostaa yhteyden kautta localhost. Paikallinen välityspalvelin käsittelee tämän yhteyden ja välittää sen varsinaiselle palvelimelle. Nyt kun taustaa siirretään toiselle koneelle tai skaalataan, kaikkien asiakkaiden päivittämisen sijaan sinun tarvitsee vain päivittää kaikki nämä paikalliset välityspalvelimet; ja uudelleenkäynnistystä ei enää tarvita.

(Liikenne suunniteltiin myös kapseloida TLS-yhteyksiin ja laittaa toinen välityspalvelin vastaanottopuolelle sekä tarkistaa TLS-varmenteet ilman vastaanottavan palvelun osallistumista, joka on määritetty hyväksymään yhteydet vain localhost. Tästä lisää myöhemmin).

Tämä on hyvin samanlainen SmartStack Airbnb:ltä, mutta merkittävä ero on, että SmartStack on otettu käyttöön ja otettu käyttöön tuotantoon, kun taas dotCloudin sisäinen reititysjärjestelmä hylättiin, kun dotCloudista tuli Docker.

Itse pidän SmartStackia yhtenä Istion, Linkerdin ja Consul Connectin kaltaisten järjestelmien edeltäjistä, koska ne kaikki noudattavat samaa kaavaa:

  • Suorita välityspalvelin jokaisessa solmussa.
  • Asiakkaat muodostavat yhteyden välityspalvelimeen.
  • Ohjaustaso päivittää välityspalvelimen määritykset, kun taustaohjelmat muuttuvat.
  • ... Voitto!

Palveluverkon moderni toteutus

Jos meidän pitäisi ottaa käyttöön samanlainen verkko tänään, voisimme käyttää samanlaisia ​​periaatteita. Määritä esimerkiksi sisäinen DNS-vyöhyke yhdistämällä palvelujen nimet tilassa oleviin osoitteisiin 127.0.0.0/8. Suorita sitten HAProxy kussakin klusterin solmussa hyväksyen yhteydet jokaisessa palveluosoitteessa (tässä aliverkossa 127.0.0.0/8) ja ohjaamalla/tasapainottamalla kuorman asianmukaisiin taustaohjelmiin. HAProxy-kokoonpanoa voidaan ohjata confd, jonka avulla voit tallentaa taustatietoa etcd:hen tai Consuliin ja automaattisesti työntää päivitetyt asetukset HAProxylle tarvittaessa.

Istio toimii pitkälti näin! Mutta joillain eroilla:

  • Käyttää lähettiläs valtakirja HAProxyn sijaan.
  • Tallentaa taustajärjestelmän määritykset Kubernetes API:n kautta etcd:n tai Consulin sijaan.
  • Palveluille on varattu osoitteita sisäisessä aliverkossa (Kubernetes ClusterIP-osoitteet) 127.0.0.0/8 sijaan.
  • Siinä on lisäkomponentti (Citadel), joka lisää molemminpuolisen TLS-todennuksen asiakkaan ja palvelimien välille.
  • Tukee uusia ominaisuuksia, kuten piirikatkaisua, hajautettua jäljitystä, kanarian käyttöönottoa jne.

Tarkastellaanpa nopeasti joitain eroja.

lähettiläs valtakirja

Envoy Proxyn on kirjoittanut Lyft [Uberin kilpailija taksimarkkinoilla - noin. kaista]. Se on monella tapaa samanlainen kuin muut välityspalvelimet (esim. HAProxy, Nginx, Traefik...), mutta Lyft kirjoitti omansa, koska he tarvitsivat ominaisuuksia, joita muilta välityspalvelijoilta puuttui, ja tuntui fiksummalta tehdä uusi kuin laajentaa olemassa olevaa.

Envoyta voidaan käyttää sellaisenaan. Jos minulla on tietty palvelu, joka tarvitsee yhteyden muihin palveluihin, voin määrittää sen muodostamaan yhteyden Envoyyn ja sitten dynaamisesti määrittää ja määrittää Envoyn uudelleen muiden palvelujen sijainnin mukaan, samalla kun saan paljon upeita lisätoimintoja, kuten näkyvyyden. Mukautetun asiakaskirjaston tai puhelujälkien lisäämisen sijaan koodiin lähetämme liikennettä Envoylle, joka kerää mittareita puolestamme.

Mutta lähettiläs pystyy toimimaan myös mm datataso (tietotaso) palveluverkolle. Tämä tarkoittaa, että Envoy on nyt määritetty tätä palveluverkkoa varten ohjaustaso (ohjaustaso).

Ohjaustaso

Ohjaustason osalta Istio luottaa Kubernetes API:hen. Tämä ei eroa kovinkaan paljon confd:n käytöstä, joka käyttää etcd:tä tai Consulia tarkastellakseen tietovaraston avainjoukkoa. Istio käyttää Kubernetes-sovellusliittymää Kubernetes-resurssien katseluun.

Tämän ja sitten: Itse koin tämän hyödylliseksi Kubernetes API -kuvausjossa lukee:

Kubernetes API Server on "tyhmä palvelin", joka tarjoaa tallennustilaa, versiointia, validointia, päivitystä ja semantiikkaa API-resursseille.

Istio on suunniteltu toimimaan Kubernetesin kanssa; ja jos haluat käyttää sitä Kubernetesin ulkopuolella, sinun on suoritettava Kubernetes API -palvelimen esiintymä (ja etcd-apupalvelu).

Palvelun osoitteet

Istio luottaa Kubernetesin varaamiin ClusterIP-osoitteisiin, joten Istio-palvelut saavat sisäisen osoitteen (ei alueella 127.0.0.0/8).

Kube-välityspalvelin sieppaa liikenteen ClusterIP-osoitteeseen tietylle Kubernetes-klusterin palvelulle ilman Istioa ja lähettää sen välityspalvelimen taustajärjestelmään. Jos olet kiinnostunut teknisistä yksityiskohdista, kube-proxy määrittää iptables-säännöt (tai IPVS-kuormituksen tasaajat, riippuen siitä, miten se on määritetty) kirjoittamaan uudelleen ClusterIP-osoitteeseen menevien yhteyksien IP-kohdeosoitteet.

Kun Istio on asennettu Kubernetes-klusteriin, mikään ei muutu, ennen kuin se on erikseen otettu käyttöön tietylle kuluttajalle tai jopa koko nimiavaruudelle ottamalla käyttöön säilö sidecar mukautetuiksi paloiksi. Tämä säilö muodostaa Envoyn esiintymän ja asettaa joukon iptables-sääntöjä siepatakseen muihin palveluihin menevää liikennettä ja ohjatakseen sen uudelleen Envoyyn.

Kun se on integroitu Kubernetes DNS:ään, tämä tarkoittaa, että koodimme voi muodostaa yhteyden palvelun nimellä ja kaikki "vain toimii". Toisin sanoen koodimme aiheuttaa kyselyitä, kuten http://api/v1/users/4242sitten api ratkaista pyyntö 10.97.105.48, iptables-säännöt sieppaavat yhteydet 10.97.105.48 alkaen ja välittävät ne paikalliselle Envoy-välityspalvelimelle, ja tämä paikallinen välityspalvelin välittää pyynnön varsinaiselle tausta-API:lle. Huh huh!

Lisää röyhelöitä

Istio tarjoaa myös päästä päähän -salauksen ja todennuksen mTLS:n (muual TLS) kautta. Komponentti nimeltä Linnoitus.

Siellä on myös komponentti Mikseri, jota lähettiläs voi pyytää kukin pyyntö tehdä erityinen päätös kyseisestä pyynnöstä riippuen useista tekijöistä, kuten otsikoista, taustakuormasta jne... (älä huoli: on monia tapoja pitää Mixer käynnissä, ja vaikka se kaatuu, Envoy jatkaa toimintaansa hyvä välityspalvelimena).

Ja tietysti mainitsimme näkyvyyden: Envoy kerää valtavan määrän mittareita ja tarjoaa hajautetun jäljityksen. Jos mikropalveluarkkitehtuurissa yhden API-pyynnön on läpäistävä mikropalvelujen A, B, C ja D kautta, sisäänkirjautumisen yhteydessä hajautettu jäljitys lisää pyyntöön yksilöllisen tunnisteen ja tallentaa tämän tunnisteen alipyyntöjen kautta kaikkiin näihin mikropalveluihin, mikä mahdollistaa kaikki asiaan liittyvät puhelut siepataan, viiveet jne.

Kehitä tai osta

Istio tunnetaan monimutkaisena. Sen sijaan tämän viestin alussa kuvaileman reititysverkon rakentaminen on suhteellisen yksinkertaista olemassa olevien työkalujen avulla. Joten onko järkevää luoda oma palveluverkko sen sijaan?

Jos meillä on vaatimattomat tarpeet (emme tarvitse näkyvyyttä, katkaisijaa ja muita hienouksia), tulee ajatuksia oman työkalun kehittämiseen. Mutta jos käytämme Kubernetesia, sitä ei ehkä edes tarvita, koska Kubernetes tarjoaa jo perustyökalut palvelun löytämiseen ja kuormituksen tasapainottamiseen.

Mutta jos meillä on edistyneitä vaatimuksia, palveluverkon "ostaminen" näyttää olevan paljon parempi vaihtoehto. (Tämä ei aina ole "osto", koska Istio on avoimen lähdekoodin, mutta meidän on silti investoitava suunnitteluaikaa ymmärtääksemme, ottaaksemme käyttöön ja hallitaksemme sitä.)

Pitäisikö minun valita Istio, Linkerd vai Consul Connect?

Toistaiseksi olemme puhuneet vain Istiosta, mutta tämä ei ole ainoa palveluverkko. Suosittu vaihtoehto - Linkerd, ja on muutakin Konsuli Connect.

Mitä valita?

Rehellisesti sanottuna en tiedä. Tällä hetkellä en koe olevani tarpeeksi pätevä vastaamaan tähän kysymykseen. Niitä on muutama mielenkiintoista artikkelit näiden työkalujen vertailulla ja jopa vertailuarvot.

Yksi lupaava lähestymistapa on käyttää työkalua, kuten SuperGloo. Se toteuttaa abstraktiokerroksen yksinkertaistaakseen ja yhtenäistääkseen palveluverkkojen paljastamia API:ita. Sen sijaan, että oppisimme eri palveluverkkojen erityisiä (ja mielestäni suhteellisen monimutkaisia) API-liittymiä, voimme käyttää SuperGloon yksinkertaisempia rakenteita - ja vaihtaa helposti yhdestä toiseen, ikään kuin meillä olisi välimuotoinen konfigurointimuoto, joka kuvaa HTTP-rajapintoja ja -taustaohjelmia. Nginx, HAProxy, Traefik, Apache...

Olen perehtynyt hieman Istion ja SuperGloon kanssa, ja seuraavassa artikkelissa haluan näyttää, kuinka Istio tai Linkerd lisätään olemassa olevaan klusteriin SuperGloolla ja kuinka jälkimmäinen saa työnsä tehtyä, eli mahdollistaa siirtymisen yhdestä palveluverkosta toiseen ilman konfiguraatioiden päällekirjoittamista.

Lähde: will.com

Lisää kommentti