Девет Кубернетес савета за перформансе

Девет Кубернетес савета за перформансе

Здраво свима! Моје име је Олег Сидоренков, радим у ДомЦлицк-у као шеф тима за инфраструктуру. Кубик користимо у производњи више од три године и за то време смо са њим доживели много различитих занимљивих тренутака. Данас ћу вам рећи како, уз прави приступ, можете да исцедите још више перформанси из ваниле Кубернетес-а за свој кластер. Спремни, стабилно!

Сви добро знате да је Кубернетес скалабилан систем отвореног кода за оркестрацију контејнера; па, или 5 бинарних датотека које раде магично тако што управљају животним циклусом ваших микросервиса у окружењу сервера. Поред тога, то је прилично флексибилан алат који се може саставити као Лего за максимално прилагођавање за различите задатке.

И чини се да је све у реду: баците сервере у кластер као дрва за огрев у ложиште и нећете знати никакву тугу. Али ако сте за животну средину, помислићете: „Како да задржим ватру и поштедим шуму?“ Другим речима, како пронаћи начине за побољшање инфраструктуре и смањење трошкова.

1. Надгледајте тим и ресурсе апликације

Девет Кубернетес савета за перформансе

Једна од најчешћих, али ефикасних метода је увођење захтева/ограничења. Поделите апликације по именским просторима, а именске просторе по развојним тимовима. Пре примене, подесите вредности апликације за потрошњу процесорског времена, меморије и ефемерне меморије.

resources:
   requests:
     memory: 2Gi
     cpu: 250m
   limits:
     memory: 4Gi
     cpu: 500m

Искуством смо дошли до закључка: не би требало да надувавате захтеве од лимита више од два пута. Обим кластера се израчунава на основу захтева, а ако апликацијама дате разлику у ресурсима, на пример, 5-10 пута, онда замислите шта ће се десити са вашим чвором када се напуни подовима и изненада прими оптерећење. Ништа добро. У најмању руку, пригушивањем, а максимално, опростићете се од радника и добити циклично оптерећење на преосталим чворовима након што махуне почну да се крећу.

Поред тога, уз помоћ limitranges На почетку можете поставити вредности ресурса за контејнер - минималне, максималне и подразумеване:

➜  ~ kubectl describe limitranges --namespace ops
Name:       limit-range
Namespace:  ops
Type        Resource           Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----        --------           ---   ---   ---------------  -------------  -----------------------
Container   cpu                50m   10    100m             100m           2
Container   ephemeral-storage  12Mi  8Gi   128Mi            4Gi            -
Container   memory             64Mi  40Gi  128Mi            128Mi          2

Не заборавите да ограничите ресурсе простора имена тако да један тим не може да преузме све ресурсе кластера:

➜  ~ kubectl describe resourcequotas --namespace ops
Name:                   resource-quota
Namespace:              ops
Resource                Used          Hard
--------                ----          ----
limits.cpu              77250m        80
limits.memory           124814367488  150Gi
pods                    31            45
requests.cpu            53850m        80
requests.memory         75613234944   150Gi
services                26            50
services.loadbalancers  0             0
services.nodeports      0             0

Као што се види из описа resourcequotas, ако оперативни тим жели да распореди подове који ће потрошити још 10 процесора, планер то неће дозволити и испоставиће грешку:

Error creating: pods "nginx-proxy-9967d8d78-nh4fs" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10

Да бисте решили такав проблем, можете написати алат, на пример, као ово, способан да складишти и урезује ресурсе стања команде.

2. Изаберите оптимално складиште датотека

Девет Кубернетес савета за перформансе

Овде бих желео да се дотакнем теме упорних волумена и дисковног подсистема Кубернетес радних чворова. Надам се да нико не користи „Коцку“ на ХДД-у у производњи, али понекад обичан ССД више није довољан. Наишли смо на проблем где су евиденције убијале диск због И/О операција, а нема много решења:

  • Користите ССД дискове високих перформанси или пређите на НВМе (ако управљате сопственим хардвером).

  • Смањите ниво евидентирања.

  • Урадите „паметно“ балансирање махуна које силују диск (podAntiAffinity).

Екран изнад показује шта се дешава под нгинк-ингресс-цонтроллер на диску када је омогућено евидентирање аццесс_логс (~12 хиљада логова/сек). Ово стање, наравно, може довести до деградације свих апликација на овом чвору.

Што се тиче ПВ-а, авај, нисам све пробао врсте Персистент Волумес. Користите најбољу опцију која вам одговара. Историјски се код нас дешавало да мали део сервиса захтева РВКС волумене, а давно су почели да користе НФС складиште за овај задатак. Јефтино и... довољно. Наравно, он и ја смо јели говна - благослов, али научили смо да то искључимо и глава ме више не боли. И ако је могуће, пређите на С3 складиште објеката.

3. Прикупите оптимизоване слике

Девет Кубернетес савета за перформансе

Најбоље је да користите слике оптимизоване за контејнере како би Кубернетес могао да их преузме брже и да их ефикасније изврши. 

Оптимизовано значи да слике:

  • садрже само једну апликацију или обављају само једну функцију;

  • мале величине, јер се велике слике лошије преносе преко мреже;

  • имају крајње тачке здравља и спремности које омогућавају Кубернетесу да предузме акцију у случају застоја;

  • користите оперативне системе прилагођене контејнерима (као што су Алпине или ЦореОС), који су отпорнији на грешке у конфигурацији;

  • користите вишестепене градње тако да можете да примените само компајлиране апликације, а не и пратеће изворе.

Постоји много алата и услуга које вам омогућавају да проверите и оптимизујете слике у ходу. Важно је да их увек ажурирате и тестирате на безбедност. Као резултат добијате:

  1. Смањено оптерећење мреже на целом кластеру.

  2. Смањење времена покретања контејнера.

  3. Мања величина вашег целог Доцкер регистра.

4. Користите ДНС кеш меморију

Девет Кубернетес савета за перформансе

Ако говоримо о великим оптерећењима, онда је живот прилично лош без подешавања ДНС система кластера. Некада давно, Кубернетес програмери су подржавали њихово кубе-днс решење. И овде је имплементиран, али овај софтвер није био посебно подешен и није дао потребне перформансе, иако се чинило да је то једноставан задатак. Затим се појавио цореднс, на који смо прешли и није било туге, касније је постао подразумевани ДНС сервис у К8с. У једном тренутку смо нарасли на 40 хиљада рпс у ДНС систем, а и ово решење је постало недовољно. Али, срећом, изашао је Ноделоцалднс, ака локални кеш чвора, ака НодеЛоцал ДНСЦацхе.

Зашто користимо ово? Постоји грешка у Линук кернелу која, када вишеструки позиви преко цоннтрацк НАТ-а преко УДП-а, доводе до стања трке за уносе у цоннтрацк табеле, а део саобраћаја кроз НАТ се губи (свако путовање кроз услугу је НАТ). Ноделоцалднс решава овај проблем тако што се ослобађа НАТ-а и надогради везу са ТЦП-ом на узводни ДНС, као и локално кешује упстреам ДНС упите (укључујући кратку негативну кеш меморију од 5 секунди).

5. Аутоматски скалирајте махуне хоризонтално и вертикално

Девет Кубернетес савета за перформансе

Можете ли са сигурношћу рећи да су све ваше микросервисе спремне за двоструко до троструко повећање оптерећења? Како правилно додијелити ресурсе својим апликацијама? Одржавање неколико модула који раде изван радног оптерећења може бити сувишно, али њихово задржавање један уз други доводи до ризика од застоја због наглог повећања саобраћаја ка услузи. Услуге као што су Хоризонтал Под Аутосцалер и Вертицал Под Аутосцалер.

ВПА омогућава вам да аутоматски подигнете захтеве/ограничења ваших контејнера у под у зависности од стварне употребе. Како то може бити корисно? Ако имате подове који се из неког разлога не могу хоризонтално скалирати (што није сасвим поуздано), онда можете покушати да измене његових ресурса поверите ВПА. Његова карактеристика је систем препорука заснован на историјским и тренутним подацима са метричког сервера, тако да ако не желите да аутоматски мењате захтеве/ограничења, можете једноставно да надгледате препоручене ресурсе за своје контејнере и оптимизујете подешавања за уштеду ЦПУ-а и меморија у кластеру.

Девет Кубернетес савета за перформансеСлика преузета са хттпс://левелуп.гитцоннецтед.цом/кубернетес-аутосцалинг-101-цлустер-аутосцалер-хоризонтал-под-аутосцалер-анд-вертицал-под-2а441д9ад231

Планер у Кубернетесу је увек заснован на захтевима. Коју год вредност да тамо ставите, планер ће тражити одговарајући чвор на основу тога. Граничне вредности су потребне да би кубелет разумео када да пригуши или убије махуну. А пошто је једини важан параметар вредност захтева, ВПА ће радити са њим. Кад год вертикално скалирате апликацију, ви дефинишете какви треба да буду захтеви. Шта ће онда бити са границама? Овај параметар ће се такође пропорционално скалирати.

На пример, ево уобичајених подешавања под:

resources:
   requests:
     memory: 250Mi
     cpu: 200m
   limits:
     memory: 500Mi
     cpu: 350m

Механизам за препоруке утврђује да је вашој апликацији потребно 300м ЦПУ-а и 500Ми да би исправно радила. Добићете следећа подешавања:

resources:
   requests:
     memory: 500Mi
     cpu: 300m
   limits:
     memory: 1000Mi
     cpu: 525m

Као што је горе поменуто, ово је пропорционално скалирање засновано на односу захтева/ограничења у манифесту:

  • ЦПУ: 200м → 300м: однос 1:1.75;

  • Меморија: 250Ми → 500Ми: однос 1:2.

Што се тиче ХПА, онда је механизам рада транспарентнији. Метрике као што су ЦПУ и меморија су постављене на праг, а ако просек свих реплика премаши праг, апликација се скалира за +1 суб све док вредност не падне испод прага или док се не достигне максимални број реплика.

Девет Кубернетес савета за перформансеСлика преузета са хттпс://левелуп.гитцоннецтед.цом/кубернетес-аутосцалинг-101-цлустер-аутосцалер-хоризонтал-под-аутосцалер-анд-вертицал-под-2а441д9ад231

Поред уобичајених метрика као што су ЦПУ и меморија, можете поставити прагове за своје прилагођене метрике из Прометхеуса и радити са њима ако мислите да је то најтачнија индикација када треба скалирати своју апликацију. Када се апликација стабилизује испод наведеног метричког прага, ХПА ће почети да смањује подове на минимални број реплика или док оптерећење не достигне наведени праг.

6. Не заборавите на Ноде Аффинити и Под Аффинити

Девет Кубернетес савета за перформансе

Не раде сви чворови на истом хардверу, и не морају сви подови да покрећу апликације које захтевају пуно рачунара. Кубернетес вам омогућава да подесите специјализацију чворова и подова помоћу Ноде Аффинити и Под Аффинити.

Ако имате чворове који су погодни за рачунарски интензивне операције, онда је за максималну ефикасност боље повезати апликације са одговарајућим чворовима. За ово користите nodeSelector са ознаком чвора.

Рецимо да имате два чвора: један са CPUType=HIGHFREQ и велики број брзих језгара, друго са MemoryType=HIGHMEMORY више меморије и брже перформансе. Најлакши начин је да доделите примену чвору HIGHFREQдодавањем у одељак spec овај селектор:

…
nodeSelector:
	CPUType: HIGHFREQ

Скупљи и специфичнији начин да се то уради је употреба nodeAffinity у пољу affinity razdela spec. Постоје две опције:

  • requiredDuringSchedulingIgnoredDuringExecution: тешко подешавање (планер ће поставити подове само на одређене чворове (и нигде другде));

  • preferredDuringSchedulingIgnoredDuringExecution: мека поставка (планер ће покушати да се примени на одређене чворове, а ако то не успе, покушаће да се примени на следећи расположиви чвор).

Можете одредити специфичну синтаксу за управљање ознакама чворова, као што је In, NotIn, Exists, DoesNotExist, Gt или Lt. Међутим, запамтите да ће сложене методе у дугачким листама ознака успорити доношење одлука у критичним ситуацијама. Другим речима, нека буде једноставно.

Као што је горе поменуто, Кубернетес вам омогућава да подесите афинитет тренутних подова. То јест, можете да се уверите да одређени подови раде заједно са другим модулима у истој зони доступности (релевантно за облаке) или чворовима.

В podAffinity поља affinity razdela spec доступна су иста поља као у случају nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution и preferredDuringSchedulingIgnoredDuringExecution. Једина разлика је у томе matchExpressions ће повезати подове за чвор који већ покреће модул са том ознаком.

Кубернетес такође нуди поље podAntiAffinity, што, напротив, не везује махуну за чвор са одређеним подовима.

О изразима nodeAffinity Исти савет се може дати: покушајте да правила буду једноставна и логична, не покушавајте да преоптерећујете спецификацију под сложеним скупом правила. Веома је лако креирати правило које неће одговарати условима кластера, стварајући непотребно оптерећење на планеру и смањујући укупне перформансе.

7. Мрље и толеранције

Постоји још један начин управљања планером. Ако имате велики кластер са стотинама чворова и хиљадама микросервиса, онда је веома тешко не дозволити да се одређени подови хостују на одређеним чворовима.

Механизам мрља — правила забране — помаже у томе. На пример, у одређеним сценаријима можете забранити одређеним чворовима покретање подова. Да бисте применили мрљу на одређени чвор, потребно је да користите опцију taint ин кубецтл. Одредите кључ и вредност, а затим покварите као NoSchedule или NoExecute:

$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoSchedule

Такође је вредно напоменути да механизам за онечишћење подржава три главна ефекта: NoSchedule, NoExecute и PreferNoSchedule.

  • NoSchedule значи да за сада неће бити одговарајућег уноса у спецификацији под tolerations, неће моћи да се примени на чвору (у овом примеру node10).

  • PreferNoSchedule - поједностављена верзија NoSchedule. У овом случају, планер ће покушати да не додели модуле који немају одговарајући унос tolerations по чвору, али ово није тешко ограничење. Ако нема ресурса у кластеру, онда ће подови почети да се постављају на овом чвору.

  • NoExecute - овај ефекат покреће тренутну евакуацију махуна које немају одговарајући унос tolerations.

Занимљиво је да се ово понашање може поништити помоћу механизма толеранције. Ово је згодно када постоји „забрањени“ чвор и на њега треба само да поставите инфраструктурне услуге. Како се то ради? Дозволите само оне махуне за које постоји одговарајућа толеранција.

Ево како би спецификација капсула изгледала:

spec:
   tolerations:
     - key: "node-role.kubernetes.io/ingress"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"

То не значи да ће следеће поновно распоређивање пасти на овај одређени чвор, ово није механизам афинитета чвора и nodeSelector. Али комбиновањем неколико функција, можете постићи веома флексибилна подешавања планера.

8. Подесите приоритет постављања модула

Само зато што имате подове додељене чворовима не значи да се сви подови морају третирати са истим приоритетом. На пример, можда ћете желети да примените неке подове пре других.

Кубернетес нуди различите начине за конфигурисање Под Приорити и Преемптион. Поставка се састоји из неколико делова: објекат PriorityClass и описи терена priorityClassName у спецификацији махуна. Погледајмо пример:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 99999
globalDefault: false
description: "This priority class should be used for very important pods only"

Ми стварамо PriorityClass, дајте му име, опис и вредност. Више value, већи је приоритет. Вредност може бити било који 32-битни цео број мањи од или једнак 1 000 000 000. Више вредности су резервисане за системске подове који су критични за мисију који се генерално не могу предухитрити. До померања ће доћи само ако капсула високог приоритета нема где да се окрене, тада ће неке од махуна из одређеног чвора бити евакуисане. Ако вам је овај механизам превише крут, можете додати опцију preemptionPolicy: Never, а онда неће бити предности, под ће стајати први у реду и чекати да планер пронађе слободне ресурсе за њега.

Затим креирамо махуну у којој означавамо име priorityClassName:

apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
 spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
  priorityClassName: high-priority
          

Можете креирати онолико приоритетних класа колико желите, иако је препоручљиво да се не заносите овим (рецимо, ограничите се на низак, средњи и високи приоритет).

Тако, ако је потребно, можете повећати ефикасност примене критичних услуга као што су нгинк-ингресс-цонтроллер, цореднс, итд.

9. Оптимизујте ЕТЦД кластер

Девет Кубернетес савета за перформансе

ЕТЦД се може назвати мозгом читавог кластера. Веома је важно одржавати рад ове базе података на високом нивоу, јер од тога зависи брзина рада у Цубе-у. Прилично стандардно и у исто време добро решење би било да се ЕТЦД кластер задржи на главним чворовима како би се дошло до минималног кашњења кубе-аписервера. Ако то не можете да урадите, онда поставите ЕТЦД што је ближе могуће, са добрим пропусним опсегом између учесника. Такође обратите пажњу на то колико чворова из ЕТЦД може испасти без штете по кластер

Девет Кубернетес савета за перформансе

Имајте на уму да претерано повећање броја чланова у кластеру може повећати толеранцију грешака науштрб перформанси, све би требало да буде умерено.

Ако говоримо о постављању услуге, постоји неколико препорука:

  1. Имајте добар хардвер, на основу величине кластера (можете прочитати овде).

  2. Подесите неколико параметара ако сте раширили кластер између пара ДЦ-ова или ваше мреже и дискови остављају много да се пожеле (можете прочитати овде).

Закључак

Овај чланак описује тачке са којима се наш тим труди да се придржава. Ово није корак по корак опис радњи, већ опције које могу бити корисне за оптимизацију надметања кластера. Јасно је да је сваки кластер јединствен на свој начин, а конфигурациона решења могу увелико да варирају, па би било занимљиво добити ваше повратне информације о томе како надгледате свој Кубернетес кластер и како побољшавате његове перформансе. Поделите своје искуство у коментарима, биће занимљиво знати.

Извор: ввв.хабр.цом