Produksjonsklare bilder for k8s

Denne historien handler om hvordan vi bruker containere i et produksjonsmiljø, nærmere bestemt Kubernetes. Artikkelen er viet innsamling av beregninger og logger fra containere, samt å bygge bilder.

Produksjonsklare bilder for k8s

Vi er fra fintech-selskapet Exness, som utvikler tjenester for netthandel og fintech-produkter for B2B og B2C. Vår FoU har mange forskjellige team, utviklingsavdelingen har 100+ ansatte.

Vi representerer teamet som er ansvarlig for plattformen for våre utviklere for å samle inn og kjøre kode. Spesielt er vi ansvarlige for å samle inn, lagre og rapportere beregninger, logger og hendelser fra applikasjoner. Vi driver for tiden omtrent tre tusen Docker-containere i et produksjonsmiljø, vedlikeholder vår 50 TB stordatalagring og tilbyr arkitektoniske løsninger som er bygget rundt vår infrastruktur: Kubernetes, Rancher og ulike offentlige skyleverandører. 

Vår motivasjon

Hva brenner? Ingen kan svare. Hvor er ildstedet? Det er vanskelig å forstå. Når tok det fyr? Du kan finne ut av det, men ikke med en gang. 

Produksjonsklare bilder for k8s

Hvorfor står noen containere mens andre har falt? Hvilken container hadde skylden? Tross alt er utsiden av beholderne den samme, men innvendig har hver sin Neo.

Produksjonsklare bilder for k8s

Utviklerne våre er kompetente gutter. De lager gode tjenester som gir profitt til selskapet. Men det er feil når containere med applikasjoner kommer på avveie. En beholder bruker for mye CPU, en annen forbruker nettverket, en tredje bruker I/O-operasjoner, og den fjerde er helt uklart hva den gjør med sockets. Det hele faller og skipet synker. 

Agenter

For å forstå hva som skjer inne, bestemte vi oss for å plassere agenter direkte i containere.

Produksjonsklare bilder for k8s

Disse midlene er begrensende programmer som holder beholdere i en slik tilstand at de ikke bryter hverandre. Agenter er standardiserte, og dette åpner for en standardisert tilnærming til service av containere. 

I vårt tilfelle må agenter levere logger i standardformat, tagget og strupet. De bør også gi oss standardiserte beregninger som kan utvides fra et forretningsapplikasjonsperspektiv.

Agenter betyr også verktøy for drift og vedlikehold som kan fungere i forskjellige orkestreringssystemer som støtter forskjellige bilder (Debian, Alpine, Centos, etc.).

Til slutt må agenter støtte enkel CI/CD som inkluderer Docker-filer. Ellers vil skipet falle fra hverandre, fordi containere vil begynne å bli levert langs "skjeve" skinner.

Bygg prosess og målbildeenhet

For å holde alt standardisert og håndterbart, må en slags standard byggeprosess følges. Derfor bestemte vi oss for å samle containere for containere - dette er rekursjon.

Produksjonsklare bilder for k8s

Her er beholderne representert med solide konturer. Samtidig bestemte de seg for å legge distribusjonssett i dem slik at "livet ikke ser ut som bringebær." Hvorfor dette ble gjort, vil vi forklare nedenfor.
 
Resultatet er et byggeverktøy – en versjonsspesifikk beholder som refererer til spesifikke distribusjonsversjoner og spesifikke skriptversjoner.

Hvordan bruker vi det? Vi har en Docker Hub som inneholder en container. Vi speiler det inne i systemet vårt for å bli kvitt eksterne avhengigheter. Resultatet er en beholder merket med gult. Vi lager en mal for å installere alle distribusjonene og skriptene vi trenger i containeren. Etter det setter vi sammen et klart-til-bruk-bilde: utviklere legger kode og noen av sine egne spesielle avhengigheter inn i det. 

Hva er bra med denne tilnærmingen? 

  • Først full versjonskontroll av byggeverktøy - bygg container, skript og distribusjonsversjoner. 
  • For det andre har vi oppnådd standardisering: vi lager maler, mellombilde og bruksklare bilder på samme måte. 
  • For det tredje gir containere oss portabilitet. I dag bruker vi Gitlab, og i morgen bytter vi til TeamCity eller Jenkins og vi vil kunne kjøre containerne våre på samme måte. 
  • For det fjerde, minimere avhengigheter. Det var ingen tilfeldighet at vi la distribusjonssett i containeren, for dette gjør at vi slipper å laste dem ned fra Internett hver gang. 
  • For det femte har byggehastigheten økt - tilstedeværelsen av lokale kopier av bilder lar deg unngå å kaste bort tid på nedlasting, siden det er et lokalt bilde. 

Vi har med andre ord oppnådd en kontrollert og fleksibel monteringsprosess. Vi bruker de samme verktøyene for å bygge alle fullversjonerte containere. 

Hvordan byggeprosedyren vår fungerer

Produksjonsklare bilder for k8s

Monteringen startes med én kommando, prosessen utføres i bildet (uthevet i rødt). Utvikleren har en Docker-fil (uthevet i gult), vi gjengir den, og erstatter variabler med verdier. Og underveis legger vi til topp- og bunntekst – dette er våre agenter. 

Header legger til distribusjoner fra de tilsvarende bildene. Og bunntekst installerer tjenestene våre inne, konfigurerer lansering av arbeidsbelastning, logging og andre agenter, erstatter inngangspunkt osv. 

Produksjonsklare bilder for k8s

Vi tenkte lenge på om vi skulle installere en veileder. Til slutt bestemte vi oss for at vi trengte ham. Vi valgte S6. Veilederen gir containeradministrasjon: lar deg koble til den hvis hovedprosessen krasjer og gir manuell administrering av containeren uten å gjenskape den. Logger og beregninger er prosesser som kjører inne i beholderen. De må også kontrolleres på en eller annen måte, og det gjør vi ved hjelp av en veileder. Til slutt tar S6 seg av husstell, signalbehandling og andre oppgaver.

Siden vi bruker forskjellige orkestreringssystemer, etter bygging og drift, må containeren forstå hvilket miljø den er i og handle i henhold til situasjonen. For eksempel:
Dette lar oss bygge ett bilde og kjøre det i forskjellige orkestreringssystemer, og det vil bli lansert under hensyntagen til spesifikasjonene til dette orkestreringssystemet.

 Produksjonsklare bilder for k8s

For samme container får vi forskjellige prosesstrær i Docker og Kubernetes:

Produksjonsklare bilder for k8s

Nyttelasten utføres under tilsyn av S6. Vær oppmerksom på samlere og hendelser - dette er våre agenter som er ansvarlige for logger og beregninger. Kubernetes har dem ikke, men Docker har det. Hvorfor? 

Hvis vi ser på spesifikasjonen til "poden" (heretter – Kubernetes pod), vil vi se at hendelsesbeholderen utføres i en pod, som har en separat samlebeholder som utfører funksjonen med å samle inn metrikk og logger. Vi kan bruke egenskapene til Kubernetes: kjøre containere i én pod, i en enkelt prosess og/eller nettverksplass. Introduser faktisk agentene dine og utføre noen funksjoner. Og hvis den samme containeren lanseres i Docker, vil den motta alle de samme egenskapene som output, det vil si at den vil kunne levere logger og beregninger, siden agentene vil bli lansert internt. 

Beregninger og logger

Å levere beregninger og logger er en kompleks oppgave. Det er flere aspekter ved hennes beslutning.
Infrastrukturen er laget for utførelse av nyttelasten, og ikke for masselevering av logger. Det vil si at denne prosessen må utføres med minimale krav til beholderressurs. Vi streber etter å hjelpe utviklerne våre: "Få en Docker Hub-beholder, kjør den, og vi kan levere loggene." 

Det andre aspektet er å begrense volumet av logger. Hvis det oppstår en økning i volumet av logger i flere beholdere (applikasjonen sender ut en stack-trace i en sløyfe), øker belastningen på CPU, kommunikasjonskanaler og loggbehandlingssystem, og dette påvirker driften av verten som en hele og andre beholdere på verten, noen ganger fører dette til "fall" av verten. 

Det tredje aspektet er at det er nødvendig å støtte så mange metrikkinnsamlingsmetoder som mulig ut av boksen. Fra lesing av filer og polling av Prometheus-endepunkt til bruk av applikasjonsspesifikke protokoller.

Og det siste aspektet er å minimere ressursforbruket.

Vi valgte en åpen kildekode Go-løsning kalt Telegraf. Dette er en universalkontakt som støtter mer enn 140 typer inngangskanaler (input plugins) og 30 typer utgangskanaler (output plugins). Vi har ferdigstilt det, og nå vil vi fortelle deg hvordan vi bruker det ved å bruke Kubernetes som eksempel. 

Produksjonsklare bilder for k8s

La oss si at en utvikler distribuerer en arbeidsmengde og Kubernetes mottar en forespørsel om å lage en pod. På dette tidspunktet opprettes automatisk en beholder kalt Collector for hver pod (vi bruker mutasjonswebhook). Collector er vår agent. Ved starten konfigurerer denne beholderen seg til å fungere med Prometheus og logginnsamlingssystemet.

  • For å gjøre dette bruker den pod-kommentarer, og avhengig av innholdet skaper den for eksempel et Prometheus-endepunkt; 
  • Basert på pod-spesifikasjonen og spesifikke beholderinnstillinger, bestemmer den hvordan logger skal leveres.

Vi samler inn logger via Docker API: utviklere trenger bare å legge dem i stdout eller stderr, og Collector vil ordne opp. Logger samles i biter med en viss forsinkelse for å forhindre mulig overbelastning av vertene. 

Beregninger samles inn på tvers av arbeidsbelastningsforekomster (prosesser) i containere. Alt er tagget: navneområde, under, og så videre, og deretter konvertert til Prometheus-format - og blir tilgjengelig for innsamling (bortsett fra logger). Vi sender også logger, beregninger og hendelser til Kafka og videre:

  • Logger er tilgjengelige i Graylog (for visuell analyse);
  • Logger, beregninger, hendelser sendes til Clickhouse for langtidslagring.

Alt fungerer akkurat likt i AWS, bare vi erstatter Graylog med Kafka med Cloudwatch. Vi sender loggene dit, og alt viser seg veldig praktisk: det er umiddelbart klart hvilken klynge og beholder de tilhører. Det samme gjelder for Google Stackdriver. Det vil si at opplegget vårt fungerer både on-premise med Kafka og i skyen. 

Hvis vi ikke har Kubernetes med pods, er ordningen litt mer komplisert, men den fungerer etter de samme prinsippene.

Produksjonsklare bilder for k8s

De samme prosessene utføres inne i containeren, de er orkestrert ved hjelp av S6. Alle de samme prosessene kjører i samme beholder.

Som et resultat,

Vi har laget en komplett løsning for å bygge og lansere bilder, med muligheter for innsamling og levering av logger og beregninger:

  • Vi utviklet en standardisert tilnærming til å sette sammen bilder, og basert på den utviklet vi CI-maler;
  • Datainnsamlingsagenter er våre Telegraf-utvidelser. Vi testet dem godt i produksjonen;
  • Vi bruker mutasjonswebhook for å implementere containere med agenter i pods; 
  • Integrert i Kubernetes/Rancher-økosystemet;
  • Vi kan utføre de samme containerne i forskjellige orkestreringssystemer og få det resultatet vi forventer;
  • Laget en fullstendig dynamisk beholderadministrasjonskonfigurasjon. 

Medforfatter: Ilya Prudnikov

Kilde: www.habr.com

Legg til en kommentar