Krav for å utvikle en applikasjon i Kubernetes

I dag planlegger jeg å snakke om hvordan du skriver søknader og hva som er kravene for at søknaden din skal fungere godt i Kubernetes. Slik at det ikke er noen hodepine med applikasjonen, slik at du ikke trenger å finne opp og bygge noen "riper" rundt den - og alt fungerer slik Kubernetes selv hadde tenkt.

Dette foredraget er en del av "Slurm Night School på Kubernetes" Du kan se de åpne teoretiske forelesningene til Aftenskolen på Youtube, gruppert i en spilleliste. For de som foretrekker tekst fremfor video, har vi utarbeidet denne artikkelen.

Mitt navn er Pavel Selivanov, for tiden er jeg den ledende DevOps-ingeniøren hos Mail.ru Cloud Solutions, vi lager skyer, vi lager administrasjonskubernetes og så videre. Mine oppgaver inkluderer nå bistand til utvikling, utrulling av disse skyene, utrulling av applikasjonene som vi skriver og direkte utvikling av verktøyene som vi tilbyr brukerne våre.

Krav for å utvikle en applikasjon i Kubernetes

Jeg har drevet med DevOps, tror jeg de siste, sannsynligvis, tre årene. Men i prinsippet har jeg gjort det DevOps gjør i omtrent fem år nå. Før det var jeg mest involvert i admin-ting. Jeg begynte å jobbe med Kubernetes for lenge siden - det har sikkert gått rundt fire år siden jeg begynte å jobbe med det.

Generelt startet jeg da Kubernetes var versjon 1.3, sannsynligvis, og kanskje 1.2 - da den fortsatt var i sin spede begynnelse. Nå er det ikke lenger i startfasen – og det er åpenbart at det er en enorm etterspørsel i markedet etter ingeniører som gjerne vil kunne drive med Kubernetes. Og bedrifter har veldig stor etterspørsel etter slike folk. Derfor dukket faktisk dette foredraget opp.

Hvis vi snakker i henhold til planen om det jeg skal snakke om, ser det slik ut, i parentes står det skrevet (TL;DR) - "for lenge; ikke les". Presentasjonen min i dag vil bestå av uendelige lister.

Krav for å utvikle en applikasjon i Kubernetes

Faktisk liker jeg ikke slike presentasjoner når de lages, men dette er et slikt tema at da jeg forberedte denne presentasjonen, fant jeg rett og slett ikke ut hvordan jeg skulle organisere denne informasjonen annerledes.

For i det store og hele er denne informasjonen «ctrl+c, ctrl+v», fra blant annet vår Wiki i DevOps-delen, hvor vi har skrevet krav til utviklere: «gutta, slik at vi lanserer applikasjonen din i Kubernetes, det skal være slik."

Det er derfor presentasjonen viste seg å være en så stor liste. Beklager. Jeg skal prøve å fortelle så mye som mulig slik at det ikke blir kjedelig om mulig.

Hva vi skal se på nå:

  • dette er for det første logger (applikasjonslogger?), hva skal man gjøre med dem i Kubernetes, hva man skal gjøre med dem, hva de skal være;
  • hva du skal gjøre med konfigurasjoner i Kubernetes, hva er de beste og verste måtene å konfigurere en applikasjon for Kubernetes på;
  • La oss snakke om hva tilgjengelighetssjekker generelt er, hvordan de skal se ut;
  • la oss snakke om hva en grasiøs nedleggelse er;
  • la oss snakke om ressurser igjen;
  • La oss berøre temaet datalagring nok en gang;
  • og til slutt vil jeg fortelle deg hva begrepet denne mystiske skybaserte applikasjonen er. Cloudnativeness, som et adjektiv for dette begrepet.

Tømmerstokker

Jeg foreslår at du starter med loggene - med hvor disse loggene må skyves i Kubernetes. Nå har du lansert en applikasjon i Kubernetes. I følge klassikerne skrev tidligere applikasjoner alltid logger et sted i en fil. Dårlige applikasjoner skrev logger til en fil i hjemmekatalogen til utvikleren som startet applikasjonen. Gode ​​applikasjoner skrev logger til en fil et sted i /var/log.

Krav for å utvikle en applikasjon i Kubernetes

Følgelig hadde gode administratorer noen ting konfigurert i infrastrukturene deres som disse loggene kunne rotere - den samme rsyslog, som ser på disse loggene og når noe skjer med dem, er det mange av dem, den lager sikkerhetskopier, legger logger der , sletter gamle filer, mer enn en uke, seks måneder og noen mer. I teorien bør vi ha bestemmelser slik at bare fordi applikasjonen skriver logger, går ikke plassen på produksjonsserverne (kampservere?) tom. Og følgelig stoppet ikke hele produksjonen på grunn av tømmerstokkene.

Når vi flytter til Kubernetes-verdenen og kjører det samme der, er det første du kan være oppmerksom på det faktum at folk, mens de skrev logger i en fil, fortsetter å skrive dem.

Det viser seg at hvis vi snakker om Kubernetes, er det rette stedet å skrive logger et sted fra en docker-container ganske enkelt å skrive dem fra applikasjonen til den såkalte Stdout/Stderr, det vil si standard utdatastrømmene til operativsystemet, standard feilutgang. Dette er den mest korrekte, enkleste og mest logiske måten å legge logger i prinsippet i Docker og spesifikt i Kubernetis. For hvis applikasjonen din skriver logger til Stdout/Stderr, er det opp til Docker og Kubernetes-tillegget å bestemme hva de skal gjøre med disse loggene. Docker vil som standard bygge sine spesialfiler i JSON-format.

Her oppstår spørsmålet, hva vil du gjøre videre med disse loggene? Den enkleste måten er klar, vi har evnen til å gjøre kubectl logs og se på disse loggene over disse "podene". Men sannsynligvis er dette ikke et veldig godt alternativ - noe annet må gjøres med loggene.

For nå, la oss snakke på samme tid, siden vi berørte emnet logger, om noe slikt som logger skal se ut. Det vil si at dette ikke gjelder direkte for Kubernetes, men når vi begynner å tenke på hva vi skal gjøre med logger, vil det være greit å tenke på dette også.

Vi trenger et slags verktøy, på en vennskapelig måte, som tar disse loggene som vår docker legger inn i filene sine og sender dem et sted. I det store og hele lanserer vi vanligvis en slags agent inne i Kubernetes i form av et DaemonSet – en loggsamler, som enkelt blir fortalt hvor loggene som Docker samler inn befinner seg. Og denne innsamlingsagenten tar dem ganske enkelt, kanskje analyserer dem på en eller annen måte underveis, beriker dem kanskje med litt ekstra metainformasjon og sender dem til slutt for lagring et sted. Variasjoner er allerede mulig der. Det vanligste er nok Elasticsearch, hvor du kan lagre logger og du enkelt kan hente dem derfra. Deretter, bruk en forespørsel, bruk Kibana, for eksempel, bygg grafer basert på dem, bygg varsler basert på dem, og så videre.

Den viktigste ideen, jeg vil gjenta den igjen, er at inne i Docker, spesielt inne i Kubernetes, er det en veldig dårlig idé å lagre loggene dine i en fil.

For det første er det vanskelig å få loggene inn i beholderen i en fil. Du må først gå inn i containeren, kjøre der, og så se på loggene. Det neste punktet er at hvis du har logger i en fil, så har containerne vanligvis et minimalistisk miljø og det er ingen verktøy som vanligvis trengs for normalt arbeid med logger. Begrav dem, se på dem, åpne dem i et tekstredigeringsprogram. Det neste øyeblikket er når vi har logger i en fil inne i en container, hvis denne beholderen blir slettet, forstår du, vil loggene dø sammen med den. Følgelig betyr enhver omstart av beholderen at det ikke er flere logger. Igjen, dårlig alternativ.

Og det siste poenget er at inne i containere har du vanligvis søknaden din og det er det - det er vanligvis den eneste prosessen som kjører. Det er ikke snakk om noen prosess som vil rotere filer med loggene dine. Så snart loggene begynner å bli skrevet til en fil, betyr dette at vi, unnskyld meg, begynner å miste produksjonsserveren. For det første er de vanskelige å finne, ingen sporer dem, pluss at ingen kontrollerer dem - følgelig vokser filen uendelig til plassen på serveren går tom. Derfor sier jeg igjen at det er en dårlig idé å logge på Docker, spesielt i Kubernetes, til en fil.

Neste punkt, her vil jeg snakke om dette igjen - siden vi berører emnet logger, ville det være greit å snakke om hvordan logger skal se ut for å gjøre det praktisk å jobbe med dem. Emnet er som sagt ikke direkte relatert til Kubernetes, men det relaterer seg veldig godt til emnet DevOps. Om temaet utviklingskultur og vennskap mellom disse to forskjellige avdelingene - Dev og Ops, slik at alle er komfortable.

Dette betyr at i dag ideelt sett bør logger skrives i JSON-format. Hvis du har en egen uforståelig applikasjon, som skriver logger i uforståelige formater fordi du setter inn en slags utskrift eller noe sånt, så er det på tide å google et slags rammeverk, en slags innpakning som lar deg implementere normal logging; aktiver loggingsparametere i JSON der, fordi JSON er et enkelt format, er det enkelt å analysere det.

Hvis din JSON ikke fungerer i henhold til noen kriterier, ingen vet hva, så skriv i det minste logger i et format som kan parses. Her er det heller verdt å tenke på det faktum at hvis du for eksempel kjører en haug med containere eller bare prosesser med nginx, og hver har sine egne logginnstillinger, så ser det sannsynligvis ut til at det vil være veldig upraktisk for deg å analysere dem. Fordi for hver nye nginx-forekomst må du skrive din egen parser, fordi de skriver logger annerledes. Igjen, det var sannsynligvis verdt å tenke på å sørge for at alle disse nginx-forekomstene hadde den samme loggingskonfigurasjonen og skrev alle loggene deres helt ensartet. Det samme gjelder absolutt alle søknader.

Til slutt vil jeg også legge bensin på bålet som ideelt sett bør unngå flerlinjeformatlogger. Her er tingen, hvis du noen gang har jobbet med logger, så har du mest sannsynlig sett hva de lover deg, at de kan jobbe med flerlinjelogger, vet hvordan de skal samles inn, og så videre. Faktisk, etter min mening, kan ikke en eneste samler i dag samle flerlinjelogger normalt, fullstendig og uten feil. På en menneskelig måte, slik at det er praktisk og feilfritt.

Krav for å utvikle en applikasjon i Kubernetes

Men stack trace er alltid multi-line logger og hvordan unngå dem. Spørsmålet her er at en logg er en registrering av en hendelse, og stactrace er faktisk ikke en logg. Hvis vi samler logger og legger dem et sted i Elasticsearch og deretter tegner grafer fra dem, bygger noen rapporter om brukeraktivitet på nettstedet ditt, så når du får en stabelsporing, betyr det at noe uventet skjer, en uhåndtert situasjon i applikasjonen din. Og det er fornuftig å automatisk laste opp en stabelsporing et sted inn i et system som kan spore dem.

Dette er programvare (samme Sentry) som er laget spesielt for å jobbe med stack trace. Den kan umiddelbart lage automatiserte oppgaver, tilordne dem til noen, varsle når stacttraces oppstår, gruppere disse stacttraces etter én type, og så videre. I prinsippet gir det ikke mye mening å snakke om stactraces når vi snakker om logger, fordi dette tross alt er forskjellige ting med forskjellige formål.

Konfigurasjon

Deretter snakker vi om konfigurasjon i Kubernetes: hva du skal gjøre med den og hvordan applikasjoner inne i Kubernetes skal konfigureres. Generelt pleier jeg å si at Docker ikke handler om containere. Alle vet at Docker handler om containere, selv de som ikke har jobbet mye med Docker. Jeg gjentar, Docker handler ikke om containere.

Docker, etter min mening, handler om standarder. Og det finnes standarder for praktisk talt alt: standarder for å bygge applikasjonen din, standarder for installasjon av applikasjonen.

Krav for å utvikle en applikasjon i Kubernetes

Og denne tingen - vi brukte den før, den ble bare spesielt populær med ankomsten av containere - denne tingen kalles ENV (miljø) variabler, det vil si miljøvariabler som er i operativsystemet ditt. Dette er generelt en ideell måte å konfigurere applikasjonen din på, for hvis du har applikasjoner i JAVA, Python, Go, Perl, Gud forby, og de alle kan lese databaseverten, databasebrukeren, databasepassordvariablene, så er det ideelt. Du har applikasjoner på fire forskjellige språk konfigurert i databaseplanen på samme måte. Det er ikke flere forskjellige konfigurasjoner.

Alt kan konfigureres ved hjelp av ENV-variabler. Når vi snakker om Kubernetes, er det en fin måte å deklarere ENV-variabler rett inne i Deployment. Følgelig, hvis vi snakker om hemmelige data, kan vi umiddelbart skyve hemmelige data fra ENV-variabler (passord til databaser, etc.) inn i en hemmelighet, opprette en hemmelig klynge og indikere i ENV-beskrivelsen i Deployment at vi ikke direkte erklærer verdien av denne variabelen, og verdien til denne databasepassordvariabelen vil bli lest fra hemmeligheten. Dette er standard Kubernetes-adferd. Og dette er det mest ideelle alternativet for å konfigurere applikasjonene dine. Bare på kodenivå, igjen gjelder dette utviklere. Hvis du er DevOps, kan du spørre: «Gutter, vennligst lær applikasjonen din å lese miljøvariabler. Og vi vil alle være glade.»

Hvis alle i selskapet leser de samme navngitte miljøvariablene, så er det flott. Slik at det ikke skjer at noen venter på postgres-databasen, andre venter på databasenavnet, andre venter på noe annet, andre venter på en dbn av noe slag, slik at det følgelig blir ensartethet.

Problemet kommer når du har så mange miljøvariabler at du bare åpner Deployment - og det er fem hundre linjer med miljøvariabler. I dette tilfellet har du ganske enkelt vokst ut av miljøvariabler – og du trenger ikke lenger å torturere deg selv. I dette tilfellet vil det være fornuftig å begynne å bruke konfigurasjoner. Det vil si, tren applikasjonen din til å bruke konfigurasjoner.

Spørsmålet er bare at konfigurasjoner ikke er det du tror. Config.pi er ikke en config som er praktisk å bruke. Eller noen konfig i ditt eget format, alternativt begavet - dette er heller ikke konfigurasjonen jeg mener.

Det jeg snakker om er konfigurasjon i akseptable formater, det vil si at den desidert mest populære standarden er .yaml-standarden. Det er tydelig hvordan man leser det, det er lesbart for mennesker, det er tydelig hvordan man leser det fra applikasjonen.

Følgelig kan du i tillegg til YAML også for eksempel bruke JSON, parsing er omtrent like praktisk som YAML når det gjelder å lese applikasjonskonfigurasjonen derfra. Det er merkbart mer upraktisk for folk å lese. Du kan prøve formatet, a la ini. Det er ganske praktisk å lese, fra et menneskelig synspunkt, men det kan være upraktisk å behandle det automatisk, i den forstand at hvis du noen gang vil generere dine egne konfigurasjoner, kan ini-formatet allerede være upraktisk å generere.

Men uansett hvilket format du velger, er poenget at fra et Kubernetes-synspunkt er det veldig praktisk. Du kan legge hele konfigurasjonen din i Kubernetes, i ConfigMap. Og så ta dette konfigurasjonskartet og be det monteres inne i poden din i en bestemt katalog, der programmet vil lese konfigurasjonen fra denne konfigurasjonskartet som om det bare var en fil. Dette er faktisk det som er bra å gjøre når du har mange konfigurasjonsmuligheter i applikasjonen din. Eller det er bare en slags kompleks struktur, det er hekking.

Hvis du har et configmap, så kan du godt lære applikasjonen din, for eksempel å automatisk spore endringer i filen der configmap er montert, og også automatisk laste inn applikasjonen på nytt når konfigurasjonene endres. Dette vil generelt være et ideelt alternativ.

Igjen, jeg har allerede snakket om dette - hemmelig informasjon er ikke i konfigurasjonskartet, hemmelig informasjon er ikke i variabler, hemmelig informasjon er ikke i hemmeligheter. Derfra kobler du denne hemmelige informasjonen til diplomati. Vanligvis lagrer vi alle beskrivelser av Kubernetes-objekter, distribusjoner, configmaps, tjenester i git. Følgelig er det en dårlig idé å legge passordet til databasen i git, selv om det er din git, som du har internt i selskapet. Fordi git som et minimum husker alt, og det er ikke så lett å fjerne passord derfra.

Helsesjekk

Det neste punktet er denne tingen som heter helsesjekk. Generelt er en helsesjekk ganske enkelt å sjekke at applikasjonen din fungerer. Samtidig snakker vi oftest om visse nettapplikasjoner, som følgelig fra et helsesjekksynspunkt (det er bedre å ikke oversette her og videre) vil være en spesiell URL, som de behandler som en standard, gjør de vanligvis /health.

Når du får tilgang til denne nettadressen, sier applikasjonen vår enten "ja, ok, alt er bra med meg, 200" eller "nei, alt er ikke bra med meg, rundt 500." Følgelig, hvis applikasjonen vår ikke er http, ikke en nettapplikasjon, snakker vi nå om en slags demon, vi kan finne ut hvordan vi gjør helsesjekker. Det vil si at det ikke er nødvendig, hvis applikasjonen ikke er http, så fungerer alt uten helsesjekk og dette kan ikke gjøres på noen måte. Du kan periodisk oppdatere noe informasjon i filen, du kan komme opp med en spesiell kommando for daemonen din, som, daemon status, som vil si "ja, alt er bra, demonen fungerer, den er i live."

Hva er den til? Det første og mest åpenbare er nok hvorfor det trengs en helsesjekk – for å forstå at applikasjonen fungerer. Jeg mener, det er bare dumt, når det er oppe nå, ser det ut som det fungerer, så du kan være sikker på at det fungerer. Og det viser seg at applikasjonen kjører, beholderen kjører, instansen fungerer, alt er bra - og så har brukerne allerede kuttet alle telefonnumrene fra teknisk støtte og sagt "hva er du..., du sovnet, ingenting fungerer."

En helsesjekk er nettopp en slik måte å se fra brukerens synspunkt at den fungerer. En av metodene. La oss si det slik. Fra Kubernetes synspunkt er dette også en måte å forstå når applikasjonen starter, fordi vi forstår at det er forskjell på når beholderen ble lansert, opprettet og startet, og når applikasjonen ble lansert direkte i denne beholderen. For hvis vi tar en gjennomsnittlig java-applikasjon og prøver å starte den i dokken, kan den starte helt fint i førti sekunder, eller til og med et minutt eller ti. I dette tilfellet kan du i det minste banke på portene, den vil ikke svare der, det vil si at den ennå ikke er klar til å motta trafikk.

Igjen, ved hjelp av en helsesjekk og ved hjelp av det faktum at vi snur oss hit, kan vi forstå i Kubernetes at ikke bare beholderen har steget i applikasjonen, men selve applikasjonen har startet, den svarer allerede på helsesjekk, som betyr at vi kan sende trafikk dit.

Krav for å utvikle en applikasjon i Kubernetes

Det jeg snakker om nå kalles Readiness/Liveness-tester i Kubernetes; følgelig er beredskapstestene våre ansvarlige for tilgjengeligheten til applikasjonen i balansering. Det vil si at hvis beredskapstester utføres i applikasjonen, så er alt ok, klienttrafikk går til applikasjonen. Hvis beredskapstester ikke utføres, deltar ganske enkelt ikke applikasjonen, denne spesielle forekomsten deltar ikke i balansering, den fjernes fra balansering, klienttrafikk flyter ikke. Følgelig er Liveness-tester i Kubernetes nødvendig, slik at hvis applikasjonen setter seg fast, kan den startes på nytt. Hvis liveness-testen ikke fungerer for en applikasjon som er deklarert i Kubernetes, blir applikasjonen ikke bare fjernet fra balansering, den startes på nytt.

Og her er et viktig poeng som jeg vil nevne: fra et praktisk synspunkt brukes beredskapstesten vanligvis oftere og er oftere nødvendig enn livlighetstesten. Det vil si, å bare tankeløst erklære både beredskaps- og liveness-tester, fordi Kubernetes kan gjøre det, og la oss bruke alt det kan gjøre, er ikke en veldig god idé. Jeg skal forklare hvorfor. For punkt nummer to i testing er at det vil være en god idé å sjekke den underliggende tjenesten i helsesjekkene dine. Dette betyr at hvis du har en nettapplikasjon som gir ut noe informasjon, som den igjen, naturligvis, må ta fra et sted. I en database, for eksempel. Vel, det lagrer informasjonen som kommer inn i denne REST API i samme database. Følgelig, hvis helsesjekken din svarer ganske enkelt som kontaktet slashhealth, sier applikasjonen "200, ok, alt er bra", og samtidig er applikasjonens database utilgjengelig, og helsesjekk-applikasjonen sier "200, ok, alt er i orden" ” – Dette er en dårlig helsesjekk. Det er ikke slik det skal fungere.

Det vil si søknaden din, når en forespørsel kommer til den /health, den svarer ikke bare, "200, ok", den går først, for eksempel til databasen, prøver å koble til den, gjør noe veldig grunnleggende der, som å velge en, bare sjekker at det er en forbindelse i databasen, og du kan spørre databasen. Hvis alt dette var vellykket, så er svaret "200, ok." Hvis det ikke lykkes, står det at det er en feil, databasen er utilgjengelig.

Derfor, i denne forbindelse, går jeg igjen tilbake til beredskaps-/livetestene - hvorfor du mest sannsynlig trenger en beredskapstest, men det er snakk om en livenesstest. For hvis du beskriver helsesjekker akkurat som jeg sa, så vil det vise seg at det ikke er tilgjengelig i instansdelenв или со всех instancei en database, for eksempel. Da du erklærte en beredskapstest, begynte helsesjekkene våre å mislykkes, og følgelig blir alle applikasjonene som databasen ikke er tilgjengelige fra, ganske enkelt slått av fra balansering og faktisk "henger" bare i en forsømt tilstand og venter på at databasene deres skal arbeid.

Hvis vi har erklært en liveness-test, så tenk deg at databasen vår har gått i stykker, og i Kubernetes begynner halvparten av alt å starte på nytt fordi liveness-testen mislykkes. Dette betyr at du må starte på nytt. Dette er slett ikke det du ønsker, jeg hadde til og med personlig erfaring i praksis. Vi hadde en chat-applikasjon som ble skrevet i JS og matet inn i en Mongo-database. Og problemet var at det var i begynnelsen av arbeidet mitt med Kubernetes, vi beskrev beredskapen, livligheten til tester på prinsippet om at Kubernetes kan gjøre det, så vi vil bruke det. Følgelig ble Mongo på et tidspunkt litt "kjedelig" og prøven begynte å mislykkes. Følgelig, ifølge regntesten, begynte belgene å "drepe".

Som du forstår, når de blir "drept", er dette en chat, det vil si at det er mange forbindelser fra klienter som henger på den. De blir også "drept" - nei, ikke klienter, bare forbindelser - ikke alle på samme tid, og på grunn av det faktum at de ikke blir drept samtidig, noen tidligere, noen senere, starter de ikke samtidig tid. Pluss standard tilfeldig, vi kan ikke forutsi med millisekunders nøyaktighet starttidspunktet for applikasjonen hver gang, så de gjør det en forekomst om gangen. Ett infopunkt reiser seg, legges til i balanseringen, alle klienter kommer dit, den tåler ikke en slik belastning, fordi den er alene, og grovt sett er det et titalls av dem som jobber der, og det faller. Den neste reiser seg, hele lasset er på ham, han faller også. Vel, disse fossene fortsetter bare å fosse. Til slutt, hvordan dette ble løst - vi måtte bare strengt tatt stoppe brukertrafikken til denne applikasjonen, la alle forekomster stige og deretter starte all brukertrafikk på en gang slik at den allerede var fordelt på alle ti forekomstene.

Hvis det ikke var for at denne liveness-testen ble annonsert, som ville tvinge det hele til å starte på nytt, ville applikasjonen ha taklet det helt fint. Men alt fra balansering er deaktivert for oss, fordi databasene er utilgjengelige og alle brukere har "falt av". Så, når denne databasen blir tilgjengelig, er alt inkludert i balanseringen, men applikasjoner trenger ikke å starte på nytt, og det er ingen grunn til å kaste bort tid og ressurser på dette. De er alle her allerede, de er klare for trafikk, så trafikken åpner bare, alt er i orden - applikasjonen er på plass, alt fortsetter å fungere.

Derfor er beredskaps- og livlighetstester forskjellige, dessuten kan man teoretisk gjøre forskjellige helsesjekker, en type radier, en type liv, for eksempel, og sjekke forskjellige ting. Under beredskapstester, sjekk backends. Og på en liveness-test, for eksempel, sjekker du ikke fra synspunktet at liveness-testen generelt bare er en applikasjon som svarer, hvis den er i stand til å svare i det hele tatt.

Fordi livlighetstesten i det store og hele er når vi "står fast". En endeløs loop har startet eller noe annet - og ingen flere forespørsler behandles. Derfor er det fornuftig å til og med skille dem - og implementere annen logikk i dem.

Angående hva du skal svare når du har en test, når du gjør helsesjekker. Det er bare virkelig vondt. De som er kjent med dette vil nok le - men seriøst, jeg har sett tjenester i mitt liv som svarer "200" i XNUMX % av tilfellene. Det vil si hvem som er vellykket. Men samtidig skriver de i selve svaret «en slik og slik feil».

Det vil si at svarstatusen kommer til deg - alt er vellykket. Men samtidig må du analysere kroppen, fordi kroppen sier "beklager, forespørselen endte med en feil", og dette er bare virkeligheten. Jeg så dette i virkeligheten.

Og slik at noen mennesker ikke synes det er morsomt, og andre synes det er veldig smertefullt, er det fortsatt verdt å følge en enkel regel. I helsesjekker, og i prinsippet ved arbeid med webapplikasjoner.

Hvis alt gikk bra, så svar med to hundredels svar. I prinsippet vil ethvert to hundredels svar passe deg. Hvis du leser ragsy veldig godt og vet at noen svarstatuser er forskjellige fra andre, kan du svare med de passende: 204, 5, 10, 15, hva som helst. Hvis det ikke er veldig bra, så bare "to null null." Hvis alt går dårlig og helsesjekken ikke svarer, så svar med en hvilken som helst femhundredel. Igjen, hvis du forstår hvordan du skal svare, hvordan forskjellige responsstatuser skiller seg fra hverandre. Hvis du ikke forstår, er 502 alternativet ditt til å svare på helsesjekker hvis noe går galt.

Dette er et annet poeng, jeg vil komme tilbake litt om å sjekke de underliggende tjenestene. Hvis du for eksempel begynner å sjekke alle de underliggende tjenestene som står bak søknaden din – alt generelt. Det vi får fra synspunktet til mikrotjenestearkitektur, har vi et konsept som "lav kobling" - det vil si når tjenestene dine er minimalt avhengige av hverandre. Hvis en av dem mislykkes, vil alle de andre uten denne funksjonaliteten ganske enkelt fortsette å fungere. Noe av funksjonaliteten fungerer rett og slett ikke. Følgelig, hvis du knytter alle helsesjekkene til hverandre, vil du ende opp med at en ting faller i infrastrukturen, og fordi den falt, begynner også alle helsesjekkene til alle tjenester å mislykkes - og det er mer infrastruktur generelt for hele mikrotjenestearkitekturen nr. Alt ble mørkt der.

Derfor vil jeg gjenta dette igjen at du må sjekke de underliggende tjenestene, de som søknaden din i hundre prosent av tilfellene ikke kan gjøre jobben sin uten. Det vil si at det er logisk at hvis du har en REST API som brukeren lagrer til databasen eller henter fra databasen, så kan du i fravær av en database ikke garantere arbeid med brukerne dine.

Men hvis brukerne dine, når du tar dem ut av databasen, i tillegg er beriket med noen andre metadata, fra en annen backend, som du skriver inn før du sender et svar til frontend - og denne backend ikke er tilgjengelig, betyr dette at du gir din svare uten noen del av metadataene.

Deretter har vi også et av de smertefulle problemene når vi starter applikasjoner.

Dette gjelder faktisk ikke bare Kubernetes i det store og hele, det skjedde at kulturen med en slags masseutvikling og spesielt DevOps begynte å spre seg omtrent samtidig som Kubernetes. Derfor viser det seg i det store og hele at du må stenge applikasjonen din elegant uten Kubernetes. Allerede før Kubernetes gjorde folk dette, men med bruken av Kubernetes begynte vi å snakke om det massevis.

Grasiøs nedleggelse

Generelt, hva er Graceful Shutdown og hvorfor er det nødvendig? Dette handler om når programmet krasjer av en eller annen grunn, må du gjøre app stop - eller du mottar for eksempel et signal fra operativsystemet, applikasjonen din må forstå det og gjøre noe med det. Det verste tilfellet er selvfølgelig når søknaden din mottar en SIGTERM og er som "SIGTERM, la oss henge på, jobbe, ikke gjøre noe." Dette er et direkte dårlig alternativ.

Krav for å utvikle en applikasjon i Kubernetes

Et nesten like dårlig alternativ er når applikasjonen din mottar en SIGTERM og er som "de sa segterm, det betyr at vi slutter, jeg har ikke sett, jeg kjenner ikke til noen brukerforespørsler, jeg vet ikke hva slags forespørsler jeg jobber med akkurat nå, sa de SIGTERM, det betyr at vi avslutter " Dette er også et dårlig alternativ.

Hvilket alternativ er bra? Det første punktet er å ta hensyn til ferdigstillelse av operasjoner. Et godt alternativ er at serveren din fortsatt tar hensyn til hva den gjør hvis den mottar en SIGTERM.

SIGTERM er en myk nedleggelse, den er spesialdesignet, den kan avskjæres på kodenivå, den kan behandles, si at nå, vent, vi vil først fullføre arbeidet vi har, så vil vi avslutte.

Fra et Kubernetes-perspektiv er det slik det ser ut. Når vi sier til en pod som kjører i en Kubernetes-klynge, «vær så snill, stopp, gå bort», eller en omstart skjer, eller en oppdatering skjer når Kubernetes gjenskaper podene, sender Kubernetes akkurat den samme SIGTERM-meldingen til poden, venter på litt tid, og , dette er tiden han venter, den er også konfigurert, det er en slik spesiell parameter i diplomer og den kalles Graceful ShutdownTimeout. Som du forstår, heter det ikke det for ingenting, og det er ikke for ingenting vi snakker om det nå.

Der kan vi spesifikt si hvor lenge vi må vente fra vi sender SIGTERM til søknaden og når vi forstår at søknaden ser ut til å ha blitt gal for noe eller sitter fast og ikke kommer til å ta slutt - og vi må send den SIGKILL, det vil si hardt fullføre arbeidet. Det vil si, følgelig har vi en slags demon i gang, den behandler operasjoner. Vi forstår at operasjonene våre som demonen jobber med i gjennomsnitt ikke varer mer enn 30 sekunder om gangen. Følgelig, når SIGTERM ankommer, forstår vi at demonen vår maksimalt kan fullføre 30 sekunder etter SIGTERM. Vi skriver det for eksempel 45 sekunder for sikkerhets skyld og sier at SIGTERM. Etter det venter vi 45 sekunder. I teorien skulle demonen i løpet av denne tiden ha fullført sitt arbeid og avsluttet seg selv. Men hvis det plutselig ikke kunne, betyr det at det mest sannsynlig sitter fast – det behandler ikke lenger forespørslene våre normalt. Og på 45 sekunder kan du trygt, faktisk, spikre ham fast.

Og her kan faktisk til og med 2 aspekter tas i betraktning. For det første, forstå at hvis du mottok en forespørsel, begynte du å jobbe med den på en eller annen måte og ga ikke et svar til brukeren, men du mottok for eksempel SIGTERM. Det er fornuftig å avgrense det og gi et svar til brukeren. Dette er punkt nummer én i denne forbindelse. Punkt nummer to her er at hvis du skriver din egen applikasjon, generelt bygger arkitekturen på en slik måte at du mottar en forespørsel om applikasjonen din, så starter du litt arbeid, begynner å laste ned filer fra et sted, laste ned en database og sånt. - At. Generelt, brukeren din, henger forespørselen din i en halv time og venter på at du skal svare ham - da, mest sannsynlig, må du jobbe med arkitekturen. Det vil si, bare ta hensyn til sunn fornuft at hvis operasjonene dine er korte, er det fornuftig å ignorere SIGTERM og endre den. Hvis operasjonene dine er lange, gir det ingen mening å ignorere SIGTERM i dette tilfellet. Det er fornuftig å redesigne arkitekturen for å unngå så lange operasjoner. Slik at brukerne ikke bare henger og venter. Jeg vet ikke, lag en slags websocket der, lag reverse hooks som serveren din allerede vil sende til klienten, noe annet, men ikke tving brukeren til å henge i en halvtime og bare vente på en økt til du svar ham. Fordi det er uforutsigbart hvor det kan gå i stykker.

Når applikasjonen din avsluttes, bør du oppgi en passende utgangskode. Det vil si at hvis søknaden din ble bedt om å lukke, stoppe, og den var i stand til å stoppe seg selv normalt, trenger du ikke å returnere en slags utgangskode 1,5,255 og så videre. Alt som ikke er nullkode, i det minste i Linux-systemer, er jeg sikker på dette, anses som mislykket. Det vil si at det anses at søknaden din i dette tilfellet endte med en feil. Følgelig, på en minnelig måte, hvis søknaden din ble fullført uten feil, sier du 0 på utgangen. Hvis applikasjonen mislykkes av en eller annen grunn, sier du ikke-0 i utdataene. Og du kan jobbe med denne informasjonen.

Og det siste alternativet. Det er dårlig når brukeren din sender en forespørsel og henger i en halv time mens du behandler den. Men generelt vil jeg også si om hva som generelt sett er verdt det fra klientens side. Det spiller ingen rolle om du har en mobilapplikasjon, front-end osv. Det er nødvendig å ta hensyn til at brukerens økt generelt kan avsluttes, alt kan skje. En forespørsel kan sendes, for eksempel underbehandlet og ingen svar returnert. Frontend-en din eller mobilapplikasjonen din - hvilken som helst grensesnitt generelt, la oss si det sånn - bør ta hensyn til dette. Hvis du jobber med websockets, er dette generelt den verste smerten jeg noen gang har hatt.

Når utviklerne av noen vanlige chatter ikke vet det, viser det seg at websocket kan gå i stykker. For dem, når noe skjer på proxyen, endrer vi bare konfigurasjonen, og den laster på nytt. Naturligvis er alle langvarige økter revet i dette tilfellet. Utviklere kommer løpende til oss og sier: «Gutter, hva gjør dere, chatten har gått i stykker for alle våre kunder!» Vi sier til dem: «Hva gjør dere? Klarer ikke kundene dine å koble til igjen? De sier: «Nei, vi trenger at øktene ikke blir revet.» Kort sagt, dette er faktisk tull. Kundesiden må tas i betraktning. Spesielt, som jeg sier, med langvarige økter som websockets, kan den gå i stykker, og ubemerket av brukeren må du kunne installere slike økter på nytt. Og så er alt perfekt.

Ресурсы

Faktisk, her skal jeg bare fortelle deg en rett historie. Igjen fra det virkelige liv. Det sykeste jeg har hørt om ressurser.

Ressurser i dette tilfellet mener jeg, en slags forespørsler, begrensninger som du kan sette på pods i Kubernetes-klyngene dine. Det morsomste jeg hørte fra en utvikler ... En av mine medutviklere på et tidligere arbeidssted sa en gang: "Min applikasjon vil ikke starte i klyngen." Jeg så for å se at den ikke startet, men enten passet den ikke inn i ressursene, eller så hadde de satt veldig små grenser. Kort sagt, applikasjonen kan ikke starte på grunn av ressurser. Jeg sier: "Det vil ikke starte på grunn av ressurser, du bestemmer hvor mye du trenger og setter en tilstrekkelig verdi." Han sier: "Hva slags ressurser?" Jeg begynte å forklare ham at Kubernetes, grenser for forespørsler og bla, bla, bla må settes. Mannen lyttet i fem minutter, nikket og sa: «Jeg kom hit for å jobbe som utvikler, jeg vil ikke vite noe om noen ressurser. Jeg kom hit for å skrive kode, og det er det.» Det er trist. Dette er et veldig trist konsept fra en utviklers synspunkt. Spesielt i den moderne verden, så å si, av progressive devops.

Hvorfor trengs det ressurser i det hele tatt? Det er 2 typer ressurser i Kubernetes. Noen kalles forespørsler, andre kalles grenser. Med ressurser vil vi forstå at det i utgangspunktet alltid bare er to grunnleggende begrensninger. Det vil si CPU-tidsgrenser og RAM-grenser for en beholder som kjører i Kubernetes.

En grense setter en øvre grense for hvordan en ressurs kan brukes i applikasjonen din. Det vil si at hvis du sier 1 GB RAM i grensene, vil ikke applikasjonen din kunne bruke mer enn 1 GB RAM. Og hvis han plutselig vil og prøver å gjøre dette, så vil en prosess kalt oom killer, uten hukommelse, det vil si, komme og drepe applikasjonen din - det vil si at den ganske enkelt starter på nytt. Applikasjoner vil ikke starte på nytt basert på CPU. Når det gjelder CPU, hvis et program prøver å bruke mye, mer enn spesifisert i grensene, vil CPU ganske enkelt bli strengt valgt. Dette fører ikke til omstart. Dette er grensen - dette er den øvre grensen.

Og det er en forespørsel. En forespørsel er hvordan Kubernetes forstår hvordan nodene i Kubernetes-klyngen din er fylt med applikasjoner. Det vil si at en forespørsel er en slags commit av søknaden din. Det står det jeg vil bruke: "Jeg vil at du skal reservere så mye CPU og så mye minne for meg." En så enkel analogi. Hva om vi har en node som har, jeg vet ikke, 8 CPUer totalt. Og en pod kommer dit, hvis forespørsler sier 1 CPU, noe som betyr at noden har 7 CPUer igjen. Det vil si at så snart 8 pods ankommer denne noden, som hver har 1 CPU i forespørslene sine, har noden, som fra Kubernetes synspunkt, gått tom for CPU og flere pods med forespørsler kan ikke lansert på denne noden. Hvis alle nodene går tom for CPU, vil Kubernetes begynne å si at det ikke er noen egnede noder i klyngen for å kjøre podene dine fordi CPU-en har gått tom.

Hvorfor trengs forespørsler og hvorfor uten forespørsler, jeg tror det ikke er nødvendig å lansere noe i Kubernetes? La oss forestille oss en hypotetisk situasjon. Du starter applikasjonen din uten forespørsler, Kubernetes vet ikke hvor mye av det du har, hvilke noder du kan presse det til. Vel, han dytter, dytter, dytter inn på nodene. På et tidspunkt vil du begynne å få trafikk til applikasjonen din. Og en av applikasjonene begynner plutselig å bruke ressurser opp til grensene den har i henhold til grensene. Det viser seg at det er en annen applikasjon i nærheten, og den trenger også ressurser. Noden begynner faktisk å gå tom for ressurser, for eksempel OP. Noden begynner faktisk å gå tom for ressurser, for eksempel RAM (Random Access Memory). Når en node går tom for strøm, vil først av alt docker slutte å svare, deretter kubelet, deretter OS. De vil rett og slett bli bevisstløse og ALT vil definitivt slutte å fungere for deg. Det vil si at dette vil føre til at noden din blir sittende fast og du må starte den på nytt. Kort sagt, situasjonen er ikke særlig god.

Og når du har forespørsler, grensene er ikke veldig forskjellige, i hvert fall ikke mange ganger mer enn grensene eller forespørslene, da kan du ha en slik normal, rasjonell fylling av søknader på tvers av nodene til Kubernetes-klynger. Samtidig er Kubernetes omtrent klar over hvor mye av det den legger hvor, hvor mye av det som brukes hvor. Det vil si, det er akkurat et slikt øyeblikk. Det er viktig å forstå det. Og det er viktig å kontrollere at dette er indikert.

Datalagring

Vårt neste punkt handler om datalagring. Hva skal man gjøre med dem og generelt, hva skal man gjøre med utholdenhet i Kubernetes?

Jeg tror igjen, innenfor vårt Kveldsskole, var det et emne om databasen i Kubernetes. Og det ser ut til at jeg til og med omtrent vet hva kollegene dine sa til deg da de ble spurt: "Er det mulig å kjøre en database i Kubernetes?" Av en eller annen grunn ser det ut til at kollegene dine burde ha fortalt deg at hvis du stiller spørsmålet om det er mulig å kjøre en database i Kubernetes, så er det umulig.

Logikken her er enkel. Bare i tilfelle, jeg skal forklare nok en gang, hvis du er en veldig kul fyr som kan bygge et ganske feiltolerant system med distribuert nettverkslagring, forstå hvordan du passer en database inn i dette tilfellet, hvordan cloud native i containere skal fungere i en database generelt. Mest sannsynlig har du ingen spørsmål om hvordan du kjører den. Hvis du har et slikt spørsmål, og du vil forsikre deg om at det hele utfolder seg og står rett til døden i produksjonen og aldri faller, så skjer ikke dette. Du vil garantert skyte deg selv i foten med denne tilnærmingen. Så det er bedre å la være.

Hva skal vi gjøre med dataene som applikasjonen vår ønsker å lagre, noen bilder som brukere laster opp, noen ting som applikasjonen vår genererer under driften, for eksempel ved oppstart? Hva skal jeg gjøre med dem i Kubernetes?

Generelt, ideelt sett, ja, selvfølgelig, er Kubernetes veldig godt utformet og ble vanligvis opprinnelig utviklet for statsløse applikasjoner. Det vil si for de applikasjonene som ikke lagrer informasjon i det hele tatt. Dette er ideelt.

Men det ideelle alternativet eksisterer selvfølgelig ikke alltid. Hva så? Det første og enkleste punktet er å ta en slags S3, bare ikke en hjemmelaget, som også er uklart hvordan den fungerer, men fra en eller annen leverandør. En god, normal leverandør - og lær applikasjonen din å bruke S3. Det vil si at når brukeren din vil laste opp en fil, si "her, vær så snill, last den opp til S3." Når han vil motta den, si: "Her er en lenke til S3 tilbake og ta den herfra." Dette er ideelt.

Hvis dette ideelle alternativet plutselig av en eller annen grunn ikke er egnet, du har en applikasjon du ikke har skrevet, du ikke utvikler, eller det er en slags forferdelig arv, den kan ikke bruke S3-protokollen, men må fungere med lokale kataloger i lokale mapper. Ta noe mer eller mindre enkelt, distribuer Kubernetes. Det vil si å umiddelbart gjerde Ceph for noen minimale oppgaver, virker det som en dårlig idé. Fordi Ceph, selvfølgelig, er god og moteriktig. Men hvis du egentlig ikke forstår hva du gjør, så når du først har satt noe på Ceph, kan du veldig enkelt og rett og slett aldri få det ut derfra igjen. Fordi, som du vet, lagrer Ceph data i sin klynge i binær form, og ikke i form av enkle filer. Derfor, hvis plutselig Ceph-klyngen bryter sammen, så er det en fullstendig og høy sannsynlighet for at du aldri får dataene dine derfra igjen.

Vi skal ha et kurs om Ceph, det kan du gjør deg kjent med programmet og send inn en søknad.

Derfor er det bedre å gjøre noe enkelt som en NFS-server. Kubernetes kan jobbe med dem, du kan montere en katalog under en NFS-server - applikasjonen din er akkurat som en lokal katalog. Samtidig må du naturligvis forstå at du igjen må gjøre noe med NFS-en din, du må forstå at noen ganger kan den bli utilgjengelig og vurdere spørsmålet om hva du vil gjøre i dette tilfellet. Kanskje det bør sikkerhetskopieres et sted på en egen maskin.

Det neste punktet jeg snakket om er hva du skal gjøre hvis applikasjonen din genererer noen filer under drift. For eksempel, når den starter, genererer den en statisk fil, som er basert på noe informasjon som applikasjonen mottar bare på tidspunktet for lansering. For et øyeblikk. Hvis det ikke er mye slike data, trenger du ikke å bry deg i det hele tatt, bare installer denne applikasjonen for deg selv og jobb. Det eneste spørsmålet her er hva, se. Svært ofte, alle slags eldre systemer, som WordPress og så videre, spesielt med modifiserte noen slags utspekulerte plugins, utspekulerte PHP-utviklere, vet de ofte hvordan de skal lage det slik at de genererer en slags fil for seg selv. Følgelig genererer man én fil, den andre genererer en andre fil. De er forskjellige. Balansering skjer i kundenes Kubernetes-klynge ganske enkelt ved en tilfeldighet. Følgelig viser det seg at de for eksempel ikke vet hvordan de skal samarbeide. Den ene gir én informasjon, den andre gir brukeren en annen informasjon. Det er dette du bør unngå. Det vil si at i Kubernetes vil alt du lanserer garantert kunne fungere i flere instanser. Fordi Kubernetes er en gripende ting. Følgelig kan han flytte hva som helst, når han vil, uten å spørre noen i det hele tatt. Derfor må du regne med dette. Alt som lanseres i én instans vil før eller siden mislykkes. Jo flere reservasjoner du har, jo bedre. Men igjen, sier jeg, hvis du har noen få slike filer, så kan du legge dem rett under deg, de veier en liten mengde. Hvis det er litt flere av dem, bør du sannsynligvis ikke skyve dem inn i beholderen.

Jeg vil anbefale at det er en så fantastisk ting i Kubernetes, du kan bruke volum. Spesielt er det et volum av typen tomme dir. Det vil si, det er bare at Kubernetes automatisk oppretter en katalog i tjenestekatalogene på serveren der du startet. Og han vil gi det til deg slik at du kan bruke det. Det er bare ett viktig poeng. Det vil si at dataene dine ikke blir lagret inne i beholderen, men heller på verten du kjører på. Dessuten kan Kubernetes kontrollere slike tomme dirs under normal konfigurasjon og er i stand til å kontrollere deres maksimale størrelse og ikke tillate at den overskrides. Det eneste poenget er at det du har skrevet i tom dir ikke går tapt under omstart av pod. Det vil si at hvis poden din faller ved en feil og reiser seg igjen, vil ikke informasjonen i den tomme katalogen gå noen vei. Han kan bruke den igjen på en ny start - og det er bra. Hvis poden din drar et sted, vil han naturligvis dra uten data. Det vil si at så snart poden fra noden der den ble lansert med tom dir forsvinner, slettes tom dir.

Hva annet er bra med tomme dir? For eksempel kan den brukes som en cache. La oss forestille oss at applikasjonen vår genererer noe på farten, gir det til brukerne og gjør det i lang tid. Derfor genererer applikasjonen for eksempel og gir den til brukerne, og lagrer den samtidig et sted, slik at neste gang brukeren kommer for det samme, vil det gå raskere å gi den umiddelbart generert. Tom katalog kan bes Kubernetes om å opprette i minnet. Og dermed kan cachene dine generelt fungere lynraskt - når det gjelder disktilgangshastighet. Det vil si at du har en tom dir i minnet, i OS er det lagret i minnet, men for deg, for brukeren inne i poden, ser det ut som bare en lokal katalog. Du trenger ikke appen for spesifikt å lære bort magi. Du bare tar og legger filen direkte i en katalog, men faktisk i minnet på operativsystemet. Dette er også en veldig praktisk funksjon når det gjelder Kubernetes.

Hvilke problemer har Minio? Hovedproblemet med Minio er at for at denne tingen skal fungere, må den kjøres et sted, og det må være et slags filsystem, det vil si lagring. Og her møter vi de samme problemene som Ceph har. Det vil si at Minio må lagre filene sine et sted. Det er rett og slett et HTTP-grensesnitt til filene dine. Dessuten er funksjonaliteten klart dårligere enn Amazons S3. Tidligere var det ikke i stand til å autorisere brukeren på riktig måte. Nå kan den, så vidt jeg vet, allerede lage bøtter med ulike autorisasjoner, men igjen virker det for meg som om hovedproblemet så å si er det underliggende lagringssystemet i det minste.

Hvordan påvirker Empty dir i minnet grensene? Påvirker ikke grenser på noen måte. Det ligger i minnet til verten, og ikke i minnet til beholderen din. Det vil si at beholderen din ikke ser den tomme mappen i minnet som en del av det okkuperte minnet. Verten ser dette. Følgelig, ja, fra kubernetes synspunkt, når du begynner å bruke dette, ville det være godt å forstå at du bruker en del av minnet ditt til tom dir. Og derfor må du forstå at minnet kan gå tom ikke bare på grunn av applikasjoner, men også fordi noen skriver til disse tomme dirs.

Cloudnativeness

Og det siste underemnet er hva Cloudnative er. Hvorfor trengs det? Cloudnativeness og så videre.

Det vil si de applikasjonene som er kapable og skrevet for å fungere i en moderne skyinfrastruktur. Men faktisk har Cloudnative et annet slikt aspekt. At dette ikke bare er en applikasjon som tar hensyn til alle kravene til en moderne skyinfrastruktur, men også vet hvordan man jobber med denne moderne skyinfrastrukturen, dra nytte av fordelene og ulempene ved at det fungerer i disse skyene. Ikke bare gå over bord og arbeid i skyene, men dra nytte av fordelene ved å jobbe i skyen.

Krav for å utvikle en applikasjon i Kubernetes

La oss bare ta Kubernetes som et eksempel. Applikasjonen din kjører i Kubernetes. Applikasjonen din kan alltid, eller snarere administratorene for applikasjonen din, alltid opprette en tjenestekonto. Det vil si en konto for autorisasjon i Kubernetes selv på serveren. Legg til noen rettigheter vi trenger der. Og du kan få tilgang til Kubernetes fra applikasjonen din. Hva kan du gjøre på denne måten? For eksempel, fra applikasjonen, motta data om hvor de andre applikasjonene dine, andre lignende instanser er plassert, og sammen på en eller annen måte klynge på toppen av Kubernetes, hvis det er et slikt behov.

Igjen, vi hadde bokstavelig talt en sak nylig. Vi har én kontrollør som overvåker køen. Og når noen nye oppgaver dukker opp i denne køen, går den til Kubernetes - og inne i Kubernetes lager den en ny pod. Gir denne poden en ny oppgave og innenfor rammen av denne poden utfører poden oppgaven, sender et svar til kontrolleren selv, og kontrolleren gjør så noe med denne informasjonen. For eksempel legger den sammen en database. Det vil si, igjen, dette er et pluss ved at applikasjonen vår kjører i Kubernetes. Vi kan bruke selve den innebygde Kubernetes-funksjonaliteten for på en eller annen måte å utvide og gjøre funksjonaliteten til applikasjonen vår mer praktisk. Det vil si, ikke skjul en slags magi om hvordan du starter en applikasjon, hvordan du starter en arbeider. I Kubernetes sender du ganske enkelt en forespørsel i appen hvis applikasjonen er skrevet i Python.

Det samme gjelder hvis vi går utover Kubernetes. Vi har våre Kubernetes kjørende et sted – det er bra hvis det er i en slags sky. Igjen, vi kan bruke, og bør til og med, tror jeg, bruke mulighetene til selve skyen der vi kjører. Fra de elementære tingene som skyen gir oss. Balansering, det vil si at vi kan lage skybalansere og bruke dem. Dette er en direkte fordel av det vi kan bruke. Fordi skybalansering, for det første, ganske enkelt dumt fjerner ansvaret fra oss for hvordan det fungerer, hvordan det er konfigurert. I tillegg er det veldig praktisk, fordi vanlige Kubernetes kan integreres med skyer.

Det samme gjelder for skalering. Vanlige Kubernetes kan integreres med skyleverandører. Vet hvordan du skal forstå at hvis klyngen går tom for noder, det vil si at nodeplassen er tom, så må du legge til - Kubernetes selv vil legge til nye noder til klyngen din og begynne å lansere pods på dem. Det vil si at når lasten din kommer, begynner antallet ildsteder å øke. Når nodene i klyngen går tom for disse podene, lanserer Kubernetes nye noder, og følgelig kan antallet pods fortsatt øke. Og det er veldig praktisk. Dette er en direkte mulighet til å skalere klyngen i farten. Ikke veldig raskt, i den forstand at det ikke er et sekund, det er mer som et minutt for å legge til nye noder.

Men fra min erfaring, igjen, er det det kuleste jeg noen gang har sett. Når Cloudnative-klyngen skalert basert på tid på dagen. Det var en backend-tjeneste som ble brukt av folk i backoffice. Det vil si at de kommer på jobb klokken 9, begynner å logge på systemet, og følgelig begynner Cloudnative-klyngen, der alt kjører, å svulme opp, og lanserer nye pods slik at alle som kommer på jobb kan jobbe med applikasjonen. Når de går fra jobb kl. 8 eller 6, merker Kubernetes-klyngene at ingen bruker applikasjonen lenger og begynner å krympe. Besparelser på opptil 30 prosent er garantert. Det fungerte i Amazon på den tiden; på den tiden var det ingen i Russland som kunne gjøre det så bra.

Jeg skal si deg rett ut, besparelsene er 30 prosent bare fordi vi bruker Kubernetes og drar nytte av mulighetene til skyen. Nå kan dette gjøres i Russland. Jeg vil selvfølgelig ikke annonsere for noen, men la oss bare si at det er leverandører som kan gjøre dette, gi det rett ut av boksen med en knapp.

Det er et siste punkt som jeg også vil gjøre deg oppmerksom på. For at applikasjonen din, infrastrukturen din skal være Cloudnative, er det fornuftig å endelig begynne å tilpasse tilnærmingen kalt Infrastructure as a Code. Det vil si at dette betyr at applikasjonen din, eller snarere infrastrukturen din, er nødvendig på nøyaktig samme måte som kode Beskriv din applikasjon, din forretningslogikk i form av kode. Og jobb med den som kode, det vil si test den, rull den ut, lagre den i git, bruk CICD på den.

Og det er nettopp dette som lar deg, for det første, alltid ha kontroll over infrastrukturen din, alltid forstå hvilken tilstand den er i. For det andre, unngå manuelle operasjoner som forårsaker feil. For det tredje, unngå rett og slett det som kalles omsetning, når du hele tiden trenger å utføre de samme manuelle oppgavene. For det fjerde lar den deg komme deg mye raskere i tilfelle feil. I Russland, hver gang jeg snakker om dette, er det alltid et stort antall mennesker som sier: "Ja, det er klart, men du har tilnærminger, kort sagt, det er ikke nødvendig å fikse noe." Men det er sant. Hvis noe er ødelagt i infrastrukturen din, så fra synspunktet til Cloudnative-tilnærmingen og fra synspunktet til infrastruktur som en kode, i stedet for å fikse det, gå til serveren, finne ut hva som er ødelagt og fikse det, er det enklere for å slette serveren og opprette den på nytt. Og jeg vil få alt dette gjenopprettet.

Alle disse spørsmålene diskuteres mer detaljert på Kubernetes videokurs: Junior, Basic, Mega. Ved å følge lenken kan du gjøre deg kjent med programmet og betingelsene. Det praktiske er at du kan mestre Kubernetes ved å studere hjemmefra eller jobbe 1-2 timer om dagen.

Kilde: www.habr.com

Legg til en kommentar