Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Tilbake i 2016, vi hos Buffer byttet til Kubernetes, og nå kjører omtrent 60 noder (på AWS) og 1500 containere på vår k8s-klynge under kontroll av sparkeVi byttet imidlertid til mikrotjenester ved prøving og feiling, og selv etter flere år med å jobbe med k8-er, møter vi fortsatt nye problemer for oss selv. I dette innlegget skal vi snakke om prosessorbegrensningerhvorfor vi syntes de var god praksis, og hvorfor de viste seg å ikke være så gode.

Prosessorbegrensninger og begrensning

Som mange andre Kubernetes-brukere, Google anbefaler på det sterkeste å konfigurere prosessorgrenserUten et slikt oppsett kan containere i en node ta opp all prosessorkraften, noe som igjen kan føre til at viktige Kubernetes-prosesser (for eksempel kubelet) vil slutte å svare på forespørsler. Så det å sette CPU-grenser er en god måte å beskytte nodene dine på.

CPU-grenser angir en maksimal CPU-tid som en container kan bruke i en gitt periode (standard er 100 ms), og containeren vil aldri overskride denne grensen. I Kubernetes, strupling beholderen og for å forhindre at den overskrider grensen, brukes et spesialverktøy CFS-kvote, men til syvende og sist reduserer disse kunstige CPU-begrensningene ytelsen og øker responstiden til containerne dine.

Hva kan skje hvis vi ikke setter prosessorgrenser?

Dessverre måtte vi håndtere dette problemet selv. Hver node har en prosess som er ansvarlig for å administrere containere. kubelet, og den sluttet å svare på forespørsler. Noden vil, når dette skjer, gå inn i tilstanden NotReady, og containere fra den vil bli omdirigert et annet sted og skape de samme problemene på nye noder. Ikke et ideelt scenario, for å si det mildt.

Manifestasjon av problemet med gassregulering og respons

Den viktigste metrikken for containersporing er trottling, viser den hvor mange ganger containeren din har blitt strupt. Vi var interesserte i å se struping i noen containere, uavhengig av om CPU-belastningen var på sitt maksimale eller ikke. La oss som et eksempel se på en av våre viktigste API-er:

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Som du kan se nedenfor, har vi satt grensen til 800m (0.8 eller 80 % av kjernen), og toppverdiene når best mulig 200m (20 % av kjernen). Det ser ut til at vi fortsatt har rikelig med prosessorkraft før tjenestebegrensning, men...

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser
Du har kanskje lagt merke til at selv når prosessorbelastningen er under de angitte grensene – betydelig under – forekommer det fortsatt struping.

Stilt overfor dette oppdaget vi snart flere ressurser (problem på github, presentasjon om Zadano, innlegg på omio) om fallet i ytelse og responstid for tjenester på grunn av begrensning.

Hvorfor ser vi struping ved lav CPU-belastning? Краткая версия звучит так: «в ядре Linux есть баг, из-за которого срабатывает необязательный троттлинг контейнеров с заданными процессорными ограничениями». Если вас интересует природа проблемы, вы можете ознакомиться с презентацией (video и tekst varianter) av Dave Chiluk.

Fjerne CPU-begrensninger (med ekstrem forsiktighet)

Etter lange diskusjoner har vi besluttet å fjerne prosessorbegrensninger fra alle tjenester som direkte eller indirekte påvirket kritisk funksjonalitet for brukerne våre.

Avgjørelsen var ikke enkel, fordi vi verdsetter stabiliteten til klyngen vår høyt. Tidligere hadde vi allerede eksperimentert med ustabilitet i klyngen vår, og da forbrukte tjenestene for mye ressurser og bremset arbeidet til hele noden. Denne gangen var ting litt annerledes: vi hadde en klar forståelse av hva vi forventet av klyngene våre, samt en god strategi for å implementere de planlagte endringene.

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser
Forretningskorrespondanse om et presserende spørsmål.

Hvordan beskytte nodene dine når restriksjonene oppheves?

Isolering av «ubegrensede» tjenester:

Tidligere har vi allerede sett noen noder komme i en tilstand notReady, først og fremst på grunn av tjenester som forbrukte for mye ressurser.

Vi bestemte oss for å plassere slike tjenester i separate («merkede») noder slik at de ikke ville forstyrre «koblede» tjenester. Som et resultat oppnådde vi større kontroll over klyngen ved å merke noen noder og legge til toleranseparameteren til «ikke-koblede» tjenester, og det ble enklere for oss å identifisere problemer med noder. For å utføre lignende prosesser selv, kan du lese dokumentasjon.

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Tilordne riktig prosessor og minneforespørsel:

Vår største frykt var at prosessen ville bruke opp for mange ressurser og at noden ville slutte å svare. Siden vi nå (takket være Datadog) tydelig kunne overvåke alle tjenestene i klyngen vår, analyserte jeg flere måneder av tjenestene vi planla å sette som "ubundet". Jeg satte ganske enkelt maksimal CPU-bruk med en margin på 20 %, og allokerte dermed plass på noden i tilfelle k8s prøvde å tilordne andre tjenester til noden.

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Som du kan se fra grafen, har den maksimale belastningen på prosessoren nådd 242m CPU-kjerner (0.242 prosessorkjerner). For en prosessorforespørsel er det nok å ta et tall litt større enn denne verdien. Merk at siden tjenestene er brukerorienterte, sammenfaller toppbelastningsverdiene med trafikken.

Gjør det samme med minnebruk og forespørsler, og vips – du er klar! For ekstra sikkerhet kan du legge til horisontal pod-autoskalering. På denne måten vil autoskalering opprette nye pods når ressursbelastningen er høy, og kubernetes vil distribuere dem til noder med ledig plass. Hvis det ikke er plass igjen i selve klyngen, kan du sette opp et varsel eller konfigurere å legge til nye noder via autoskaleringen deres.

På den negative siden er det verdt å merke seg at vi tapte i «beholdertetthet", dvs. antall containere som kjører i én node. Vi kan også ha mange "avslapninger" ved lav trafikktetthet, og det er også en sjanse for at du vil nå en høy prosessorbelastning, men autoskalering av noder bør hjelpe med sistnevnte.

Funn

Jeg er glad for å kunne publisere disse flotte resultatene fra eksperimentene de siste ukene. Vi har allerede sett betydelige forbedringer i responstiden på tvers av alle modifiserte tjenester:

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Vi oppnådde det beste resultatet på hovedsiden vår (buffer.com), der har tjenesten akselerert i tjueto ganger!

Kubernetes: Få fart på tjenestene dine ved å fjerne CPU-grenser

Исправлен ли баг ядра Linux?

Да, Feilen er allerede fikset, og rettelsen er lagt til i kjernen distribusjonsversjon 4.19 og høyere.

Men når man leser Kubernetes-problemer på GitHub for 2020. september XNUMX мы все еще сталкиваемся с упоминаниями некоторых Linux-проектов с аналогичным багом. Я полагаю, что в некоторых дистрибутивах Linux все еще есть эта ошибка и сейчас только ведется работа над ее исправлением.

Если ваша версия дистрибутива ниже 4.19, я бы порекомендовал обновиться до последней, но вам в любом случае стоит попробовать снять процессорные ограничения и посмотреть сохранится ли троттлинг. Ниже можно ознакомиться с неполным списком управляющих Kubernetes сервисов и Linux distribusjoner:

  • Debian: фикс интегрирован в последнюю версию дистрибутива, buster, og ser ganske frisk ut (August 2020Noen tidligere versjoner kan også være fikset.
  • Ubuntu: фикс интегрирован в последнюю версию Ubuntu Focal Fossa 20.04
  • EKS har fått en ny løsning i desember 2019Hvis versjonen din er eldre enn dette, bør du oppdatere AMI-en din.
  • kops: Siden juni 2020 у kops 1.18+ основным образом хоста станет Ubuntu 20.04. Если ваша версия kops старше, вам, вероятно, придется подождать фикса. Мы и сами сейчас ждем.
  • GKE (Google Cloud): Fiks integrert i januar 2020det er imidlertid problemer med gassregulering blir fortsatt observert.

Hva skal jeg gjøre hvis løsningen løste problemet med gassregulering?

Jeg er ikke sikker på om problemet er helt løst. Når vi kommer til en kjerneversjon med en løsning, skal jeg teste klyngen og oppdatere innlegget. Hvis noen allerede har oppdatert, vil jeg gjerne se resultatene deres.

Konklusjon

  • Если вы работаете с Docker-контейнерами под Linux (не важно Kubernetes, Mesos, Swarm или еще какими), ваши контейнеры могут терять в производительности из-за троттлинга;
  • Prøv å oppdatere til den nyeste versjonen av distribusjonen din i håp om at feilen allerede er fikset;
  • Å fjerne prosessorbegrensninger vil løse problemet, men dette er en farlig teknikk som bør brukes med ekstrem forsiktighet (det er bedre å først oppdatere kjernen og sammenligne resultatene);
  • Hvis du har fjernet CPU-grensene, må du nøye overvåke CPU- og minnebruken og sørge for at CPU-ressursene dine er overforbrukt.
  • Et trygt alternativ ville være å autoskalere poder for å opprette nye poder når maskinvarebelastningen er høy, slik at Kubernetes tilordner dem til ledige noder.

Jeg håper dette innlegget hjelper deg med å forbedre ytelsen til containersystemene dine.

PS Her Forfatteren opprettholder korrespondanse med lesere og kommentatorer (på engelsk).


Kilde: www.habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig webhotell med DDoS-beskyttelse, VPS VDS-servere | ProHoster