Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

През 2016 г. ние от Buffer премина към Kubernetes, а сега около 60 възела (на AWS) и 1500 контейнера работят върху нашия k8s клъстер, управляван от ритник. Въпреки това преминахме към микроуслуги чрез опити и грешки и дори след няколко години работа с k8s все още сме изправени пред нови проблеми. В тази публикация ще говорим за ограничения на процесора: защо ги смятахме за добра практика и защо в крайна сметка не се оказаха толкова добри.

Ограничения на процесора и дроселиране

Подобно на много други потребители на Kubernetes, Google горещо препоръчва да зададете ограничения на процесора. Без такава настройка контейнерите в даден възел могат да поемат цялата мощност на процесора, което от своя страна причинява важни процеси на Kubernetes (напр. kubelet) ще спре да отговаря на заявки. По този начин задаването на ограничения на процесора е добър начин да защитите вашите възли.

Ограниченията на процесора задават контейнер на максималното процесорно време, което може да използва за определен период (по подразбиране е 100 ms) и контейнерът никога няма да превиши това ограничение. В Kubernetes за дроселиране контейнер и да се предотврати превишаването му, се използва специален инструмент Квота на CFS, но тези изкуствени ограничения на процесора в крайна сметка влошават производителността и увеличават времето за реакция на вашите контейнери.

Какво може да се случи, ако не зададем ограничения на процесора?

За съжаление ние самите трябваше да се сблъскаме с този проблем. Всеки възел има процес, отговорен за управлението на контейнери kubelet, и той спря да отговаря на заявки. Възелът, когато това се случи, ще премине в състояние NotReady, а контейнерите от него ще бъдат пренасочени някъде другаде и ще създадат същите проблеми на нови възли. Не е идеален сценарий, най-малкото.

Проява на проблема с дроселирането и реакцията

Ключовият показател за проследяване на контейнери е trottling, той показва колко пъти вашият контейнер е бил дроселиран. С интерес забелязахме наличието на throttling в някои контейнери, независимо дали натоварването на процесора е екстремно или не. Като пример, нека да разгледаме един от нашите основни API:

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

Както можете да видите по-долу, сме задали ограничението до 800m (0.8 или 80% ядро) и пикови стойности при най-добро достигане 200m (20% ядро). Изглежда, че преди да ограничим услугата, все още имаме много процесорна мощност, но...

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора
Може би сте забелязали, че дори когато натоварването на процесора е под посочените граници - значително под - тротлинг все още се получава.

Изправени пред това, скоро открихме няколко ресурса (проблем в github, презентация на zadano, публикувайте в omio) относно спада в производителността и времето за реакция на услугите поради дроселиране.

Защо виждаме дроселиране при ниско натоварване на процесора? Кратката версия е: „има грешка в ядрото на Linux, която причинява ненужно ограничаване на контейнери с определени ограничения на процесора.“ Ако се интересувате от естеството на проблема, можете да прочетете презентацията (видео и текст опции) от Дейв Чилук.

Премахване на ограниченията на процесора (с изключително внимание)

След дълги дискусии решихме да премахнем ограниченията за процесора от всички услуги, които пряко или косвено засягат критичната функционалност за нашите потребители.

Решението не беше лесно, защото ценим високо стабилността на нашия клъстер. В миналото вече експериментирахме с нестабилността на нашия клъстер и тогава услугите консумираха твърде много ресурси и забавяха работата на целия си възел. Сега всичко беше малко по-различно: имахме ясно разбиране какво очакваме от нашите клъстери, както и добра стратегия за прилагане на планираните промени.

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора
Бизнес кореспонденция по наболял проблем.

Как да защитите вашите възли, когато ограниченията бъдат премахнати?

Изолиране на „неограничени“ услуги:

В миналото вече сме виждали някои възли да влизат в състояние notReady, главно поради услуги, които консумират твърде много ресурси.

Решихме да поставим такива услуги в отделни („маркирани“) възли, така че да не пречат на „свързаните“ услуги. В резултат на това, като маркирахме някои възли и добавихме параметъра за толерантност към „несвързани“ услуги, постигнахме по-голям контрол върху клъстера и за нас стана по-лесно да идентифицираме проблеми с възлите. За да извършите сами подобни процеси, можете да се запознаете с документация.

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

Задаване на правилен процесор и заявка за памет:

Най-големият ни страх беше, че процесът ще изразходва твърде много ресурси и възелът ще спре да отговаря на заявки. Тъй като сега (благодарение на Datadog) можехме ясно да наблюдаваме всички услуги на нашия клъстер, анализирах няколко месеца работа на тези, които планирахме да обозначим като „несвързани“. Просто зададох максимално използване на процесора с марж от 20% и по този начин разпределих място във възела, в случай че k8s се опита да присвои други услуги към възела.

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

Както можете да видите на графиката, максималното натоварване на процесора е достигнато 242m CPU ядра (0.242 процесорни ядра). За заявка за процесор е достатъчно да вземете число, малко по-голямо от тази стойност. Моля, имайте предвид, че тъй като услугите са ориентирани към потребителя, стойностите на пиковото натоварване съвпадат с трафика.

Направете същото с използването на паметта и заявките и готово - всичко е готово! За по-голяма сигурност можете да добавите хоризонтално автоматично мащабиране на под. По този начин всеки път, когато натоварването на ресурсите е високо, автоматичното мащабиране ще създаде нови подове и kubernetes ще ги разпредели към възли със свободно пространство. В случай, че в самия клъстер няма останало място, можете да си зададете предупреждение или да конфигурирате добавянето на нови възли чрез тяхното автоматично мащабиране.

От минусите си струва да се отбележи, че загубихме в „плътност на контейнера“, т.е. брой контейнери, работещи на един възел. Може също да имаме много „отпускания“ при ниска плътност на трафика и също така има шанс да достигнете високо натоварване на процесора, но възлите за автоматично мащабиране трябва да помогнат с последното.

резултати

Имам удоволствието да публикувам тези отлични резултати от експерименти през последните няколко седмици; вече видяхме значителни подобрения в отговора във всички модифицирани услуги:

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

Постигнахме най-добри резултати на нашата начална страница (буфер.com), там услугата се ускори в двадесет и два пъти!

Kubernetes: Ускорете услугите си, като премахнете ограниченията на процесора

Поправена ли е грешката в ядрото на Linux?

Да, Грешката вече е коригирана и корекцията е добавена към ядрото дистрибуции версия 4.19 и по-нова.

Въпреки това, при четене проблеми с kubernetes в github за втори септември 2020г все още срещаме споменавания на някои Linux проекти с подобен бъг. Вярвам, че някои Linux дистрибуции все още имат този бъг и тепърва работят по отстраняването му.

Ако вашата версия на разпространение е по-ниска от 4.19, бих препоръчал да актуализирате до най-новата, но във всеки случай трябва да опитате да премахнете ограниченията на процесора и да видите дали дроселирането продължава. По-долу можете да видите частичен списък на услугите за управление на Kubernetes и Linux дистрибуции:

  • Debian: корекция, интегрирана в най-новата версия на дистрибуцията, другар, и изглежда доста свежо (Август 2020). Някои предишни версии също може да бъдат коригирани.
  • Ubuntu: корекция, интегрирана в най-новата версия Ubuntu Focal Fossa 20.04
  • EKS все още има корекция през декември 2019 г. Ако вашата версия е по-ниска от тази, трябва да актуализирате AMI.
  • копс: От юни 2020г у kops 1.18+ Главният хост образ ще бъде Ubuntu 20.04. Ако вашата версия на kops е по-стара, може да се наложи да изчакате корекция. Ние самите чакаме сега.
  • GKE (Google Cloud): Интегрирана корекция през януари 2020 г, но има проблеми с дроселирането все още се наблюдават.

Какво да направите, ако корекцията реши проблема с дроселирането?

Не съм сигурен, че проблемът е напълно разрешен. Когато стигнем до версията на ядрото с корекцията, ще тествам клъстера и ще актуализирам публикацията. Ако някой вече е актуализирал, ще ми е интересно да прочета вашите резултати.

Заключение

  • Ако работите с Docker контейнери под Linux (без значение Kubernetes, Mesos, Swarm или други), вашите контейнери може да загубят производителност поради дроселиране;
  • Опитайте да актуализирате до най-новата версия на вашата дистрибуция с надеждата, че грешката вече е коригирана;
  • Премахването на ограниченията на процесора ще реши проблема, но това е опасна техника, която трябва да се използва с изключително внимание (по-добре е първо да актуализирате ядрото и да сравните резултатите);
  • Ако сте премахнали ограниченията на процесора, внимателно наблюдавайте използването на процесора и паметта си и се уверете, че ресурсите на процесора надвишават потреблението ви;
  • Безопасна опция би била автоматично мащабиране на подове за създаване на нови подове в случай на голямо хардуерно натоварване, така че kubernetes да ги присвоява на свободни възли.

Надявам се тази публикация да ви помогне да подобрите производителността на вашите контейнерни системи.

PS Тук авторът кореспондира с читатели и коментатори (на английски).


Източник: www.habr.com

Добавяне на нов коментар