{"id":77693,"date":"2020-04-13T01:42:39","date_gmt":"2020-04-12T23:42:39","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes"},"modified":"2020-04-13T01:42:39","modified_gmt":"2020-04-12T23:42:39","slug":"cpu-limity-i-agressivnyj-trottling-v-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes","title":{"rendered":"Limity CPU i agresywny throttling w Kubernetes","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Przyp. t\u0142um.<\/b>: ta pouczaj\u0105ca historia Omio \u2014 europejskiego agregatora podr\u00f3\u017cy \u2014 prowadzi czytelnik\u00f3w od podstawowej teorii do fascynuj\u0105cych praktycznych szczeg\u00f3\u0142\u00f3w w konfiguracji Kubernetes. Zapoznanie si\u0119 z takimi przypadkami pomaga nie tylko poszerzy\u0107 horyzonty, ale tak\u017ce zapobiega\u0107 niecodziennym problemom.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/1175c9df746e43b5a7d81476164929db.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCzy zdarzy\u0142o si\u0119, \u017ce aplikacja 'zawiesza\u0142a si\u0119', przestawa\u0142a odpowiada\u0107 na zapytania o stan (health check) i nie mogli\u015bcie zrozumie\u0107 przyczyny takiego zachowania? Jednym z mo\u017cliwych wyja\u015bnie\u0144 jest limit kwot na zasoby CPU. O tym b\u0119dzie mowa w tym artykule.<\/p>\n<p><b>TL;DR:<br \/>\nZdecydowanie zalecamy rezygnacj\u0119 z limit\u00f3w CPU w Kubernetes (lub wy\u0142\u0105czenie kwot CFS w Kubelet), je\u015bli u\u017cywana jest wersja j\u0105dra Linux z b\u0142\u0119dem kwot CFS. W j\u0105drze <noindex><a rel=\"nofollow\" href=\"https:\/\/bugzilla.kernel.org\/show_bug.cgi?id=198197\">jest<\/a><\/noindex> jest powa\u017cny i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/67577\">dobrze znany<\/a><\/noindex> b\u0142\u0105d, kt\u00f3ry prowadzi do nadmiernego throttlingu i op\u00f3\u017anie\u0144.<\/b>.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>W Omio <b>ca\u0142a infrastruktura jest zarz\u0105dzana przez Kubernetes.<\/b>. Wszystkie nasze obci\u0105\u017cenia stateful i stateless dzia\u0142aj\u0105 wy\u0142\u0105cznie na Kubernetes (korzystamy z Google Kubernetes Engine). W ci\u0105gu ostatnich sze\u015bciu miesi\u0119cy zacz\u0119li\u015bmy obserwowa\u0107 losowe spowolnienia. Aplikacje zawieszaj\u0105 si\u0119 lub przestaj\u0105 odpowiada\u0107 na health checki, trac\u0105 po\u0142\u0105czenie z sieci\u0105 itd. Takie zachowanie przez d\u0142ugi czas stawia\u0142o nas w martwym punkcie, a w ko\u0144cu postanowili\u015bmy zaj\u0105\u0107 si\u0119 tym problemem na powa\u017cnie.<\/p>\n<p>Streszczenie artyku\u0142u:<\/p>\n<ul>\n<li> Kilka s\u0142\u00f3w o kontenerach i Kubernetes;<\/li>\n<li> Jak realizowane s\u0105 requesty i limity CPU;<\/li>\n<li> Jak dzia\u0142a limit CPU w \u015brodowiskach z wieloma rdzeniami;<\/li>\n<li> Jak \u015bledzi\u0107 throttling CPU;<\/li>\n<li> Rozwi\u0105zanie problemu i jego niuanse.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Kilka s\u0142\u00f3w o kontenerach i Kubernetes<\/h2>\n<p>\nKubernetes jest w zasadzie wsp\u00f3\u0142czesnym standardem w \u015bwiecie infrastruktury. Jego g\u0142\u00f3wnym zadaniem jest orkiestracja kontener\u00f3w.<\/p>\n<h3>Kontenery<\/h3>\n<p>\nW przesz\u0142o\u015bci musieli\u015bmy tworzy\u0107 artefakty takie jak Java JAR'y\/WAR'y, Python Egg'i czy pliki wykonywalne do dalszego uruchamiania na serwerach. Jednak, aby je uruchomi\u0107, trzeba by\u0142o wykona\u0107 dodatkow\u0105 prac\u0119: zainstalowa\u0107 \u015brodowisko wykonawcze (Java\/Python), umie\u015bci\u0107 niezb\u0119dne pliki w odpowiednich miejscach, zapewni\u0107 zgodno\u015b\u0107 z konkretn\u0105 wersj\u0105 systemu operacyjnego itd. Innymi s\u0142owy, trzeba by\u0142o zwr\u00f3ci\u0107 szczeg\u00f3ln\u0105 uwag\u0119 na zarz\u0105dzanie konfiguracjami (co cz\u0119sto by\u0142o powodem spor\u00f3w mi\u0119dzy programistami a administratorami system\u00f3w).<\/p>\n<p><b>Kontenery wszystko zmieni\u0142y.<\/b> Obecnie artefaktem jest obraz kontenera. Mo\u017cna go przedstawi\u0107 jako rozszerzony plik wykonywalny, zawieraj\u0105cy nie tylko program, ale tak\u017ce pe\u0142ne \u015brodowisko uruchomieniowe (Java\/Python\/\u2026) oraz niezb\u0119dne pliki\/pakiety, wst\u0119pnie zainstalowane i gotowe do uruchomienia. Kontenery mo\u017cna wdra\u017ca\u0107 i uruchamia\u0107 na r\u00f3\u017cnych serwerach bez dodatkowych dzia\u0142a\u0144.<\/p>\n<p>Co wi\u0119cej, kontenery dzia\u0142aj\u0105 w swoim w\u0142asnym piaskownicowym \u015brodowisku. Maj\u0105 sw\u00f3j w\u0142asny wirtualny adapter sieciowy, system plik\u00f3w z ograniczonym dost\u0119pem, swoj\u0105 hierarchi\u0119 proces\u00f3w, swoje ograniczenia na CPU i pami\u0119\u0107 itd. Wszystko to realizowane jest dzi\u0119ki specjalnemu podsystemowi j\u0105dra Linux - namespaces (przestrzenie nazw).<\/p>\n<h3>Kubernetes<\/h3>\n<p>\nJak ju\u017c wspomniano, Kubernetes to orkiestrator kontener\u00f3w. Dzia\u0142a to w nast\u0119puj\u0105cy spos\u00f3b: dostarczasz mu pul\u0119 maszyn, a nast\u0119pnie m\u00f3wisz: \"Hej, Kubernetes, uruchom dziesi\u0119\u0107 instancji mojego kontenera z 2 procesorami i 3 GB pami\u0119ci na ka\u017cd\u0105, i utrzymuj je w dzia\u0142aniu!\". Kubernetes zajmie si\u0119 reszt\u0105. Znajdzie wolne zasoby, uruchomi kontenery i b\u0119dzie je restartowa\u0107 w razie potrzeby, zaktualizuje je przy zmianie wersji itd. W zasadzie Kubernetes pozwala abstrahowa\u0107 od sprz\u0119tu i sprawia, \u017ce r\u00f3\u017cnorodno\u015b\u0107 system\u00f3w jest gotowa do wdra\u017cania i dzia\u0142ania aplikacji.<\/p>\n<p><img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/6509bb1b66a4a0f5e9a479d0bd6ececb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Kubernetes z punktu widzenia zwyk\u0142ego u\u017cytkownika<\/i><\/p>\n<h2>Czym s\u0105 requesty i limity w Kubernetes<\/h2>\n<p>\nOk, zrozumieli\u015bmy kontenery i Kubernetes. Wiemy r\u00f3wnie\u017c, \u017ce kilka kontener\u00f3w mo\u017ce znajdowa\u0107 si\u0119 na jednej maszynie.<\/p>\n<p>Mo\u017cna przeprowadzi\u0107 analogi\u0119 do mieszkania komunalnego. Bierze si\u0119 przestronny lokal (maszyny\/w\u0119z\u0142y) i wynajmuje go kilku lokatorom (kontenerom). Kubernetes pe\u0142ni rol\u0119 po\u015brednika. Pojawia si\u0119 pytanie, jak powstrzyma\u0107 lokator\u00f3w przed konfliktami? Co je\u015bli jeden z nich, powiedzmy, zdecyduje si\u0119 zaj\u0105\u0107 \u0142azienk\u0119 na p\u00f3\u0142 dnia?<\/p>\n<p>W\u0142a\u015bnie tutaj wchodz\u0105 w gr\u0119 requesty i limity CPU. <b>Request<\/b> jest potrzebny wy\u0142\u0105cznie do planowania. To co\u015b w rodzaju \u201elisty \u017cycze\u0144\u201d kontenera i jest u\u017cywane do dobierania najbardziej odpowiedniego w\u0119z\u0142a. R\u00f3wnocze\u015bnie CPU <b>Limit<\/b> mo\u017cna por\u00f3wna\u0107 z umow\u0105 najmu - gdy ju\u017c dobierzemy w\u0119ze\u0142 dla kontenera, to <b>nie mo\u017ce<\/b> przekroczy\u0107 ustalonych limit\u00f3w. I tutaj pojawia si\u0119 problem\u2026<\/p>\n<h3>Jak realizowane s\u0105 requesty i limity w Kubernetes<\/h3>\n<p>\nKubernetes wykorzystuje wbudowany w j\u0105dro mechanizm ograniczania (throttling) do realizacji limit\u00f3w CPU. Je\u015bli aplikacja przekracza limit, uruchamiane jest ograniczenie (tzn. otrzymuje mniej takt\u00f3w CPU). Requesty i limity dla pami\u0119ci s\u0105 zorganizowane inaczej, dlatego \u0142atwiej je wykry\u0107. Wystarczy sprawdzi\u0107 ostatni status ponownego uruchomienia pod'a: czy nie zosta\u0142 'OOMKilled'. Z ograniczeniem CPU sprawy nie s\u0105 takie proste, poniewa\u017c K8s udost\u0119pnia tylko metryki dotycz\u0105ce u\u017cycia, a nie cgroups.<\/p>\n<h4>CPU Request<\/h4>\n<p>\n<img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/fbc8bf3f775ffd9513374ce94b20535d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Jak jest realizowany CPU request<\/i><\/p>\n<p>Dla uproszczenia rozwa\u017cmy proces na przyk\u0142adzie maszyny z 4-rdzeniowym CPU.<\/p>\n<p>K8s wykorzystuje mechanizm grup kontrolnych (cgroups) do zarz\u0105dzania przydzia\u0142em zasob\u00f3w (pami\u0119ci i procesora). Dla niego dost\u0119pny jest hierarchiczny model: potomstwo dziedziczy limity rodzicielskiej grupy. Szczeg\u00f3\u0142y przydzia\u0142u s\u0105 przechowywane w wirtualnym systemie plik\u00f3w (<code>\/sys\/fs\/cgroup<\/code>). W przypadku procesora to <code>\/sys\/fs\/cgroup\/cpu,cpuacct\/*<\/code>.<\/p>\n<p>K8s u\u017cywa pliku <code>cpu.share<\/code> do przydzia\u0142u zasob\u00f3w CPU. W naszym przypadku g\u0142\u00f3wna kontrolna grupa otrzymuje 4096 udzia\u0142\u00f3w zasob\u00f3w CPU \u2014 100% dost\u0119pnej mocy procesora (1 rdze\u0144 = 1024; to warto\u015b\u0107 sta\u0142a). G\u0142\u00f3wna grupa przydziela zasoby proporcjonalnie w zale\u017cno\u015bci od udzia\u0142\u00f3w potomk\u00f3w, zapisanych w <code>cpu.share<\/code>, a te z kolei post\u0119puj\u0105 analogicznie z w\u0142asnymi potomkami itd. W typowym w\u0119\u017ale Kubernetes g\u0142\u00f3wna kontrolna grupa ma trzech potomk\u00f3w: <code>system.slice<\/code>, <code>user.slice<\/code> i <code>kubepods<\/code>. Dwie pierwsze podgrupy s\u0105 u\u017cywane do przydzia\u0142u zasob\u00f3w mi\u0119dzy krytycznymi obci\u0105\u017ceniami systemowymi a aplikacjami u\u017cytkownik\u00f3w spoza K8s. Ostatnia \u2014 <code>kubepods<\/code> \u2014 tworzony przez Kubernetes do rozdzielania zasob\u00f3w mi\u0119dzy podami.<\/p>\n<p>Na schemacie powy\u017cej wida\u0107, \u017ce pierwsza i druga podgrupa otrzyma\u0142y po <b>1024<\/b> udziale, przy czym podgrupie kubepod przydzielono <b>4096<\/b> udzia\u0142\u00f3w. Jak to mo\u017cliwe: przecie\u017c g\u0142\u00f3wnej grupie dost\u0119pne s\u0105 tylko <b>4096<\/b> udzia\u0142y, a suma udzia\u0142\u00f3w jej potomk\u00f3w znacznie przekracza t\u0119 liczb\u0119 (<b>6144<\/b>)? Chodzi o to, \u017ce warto\u015b\u0107 ta ma logiczny sens, dlatego planista Linuxa (CFS) u\u017cywa jej do proporcjonalnego przydzia\u0142u zasob\u00f3w CPU. W naszym przypadku pierwsze dwie grupy otrzymuj\u0105 po <b>680<\/b> rzeczywistych udzia\u0142\u00f3w (16,6% z 4096), a kubepod otrzymuje pozosta\u0142e <b>2736<\/b> udzia\u0142y. W przypadku bezczynno\u015bci pierwsze dwie grupy nie b\u0119d\u0105 u\u017cywa\u0107 przydzielonych zasob\u00f3w.<\/p>\n<p>Na szcz\u0119\u015bcie w planie umieszczono mechanizm, kt\u00f3ry pozwala unikn\u0105\u0107 straty nieu\u017cywanych zasob\u00f3w CPU. Przekazuje on \"bezczynne\" moce do globalnej puli, z kt\u00f3rej s\u0105 one rozdzielane grupom, kt\u00f3re potrzebuj\u0105 dodatkowych mocy procesora (przekaz odbywa si\u0119 partiami, aby unikn\u0105\u0107 strat zwi\u0105zanych z zaokr\u0105glaniem). Podobna metoda jest stosowana tak\u017ce w przypadku wszystkich potomk\u00f3w potomk\u00f3w.<\/p>\n<p>Ten mechanizm zapewnia sprawiedliwy podzia\u0142 mocy procesora i dba o to, aby \u017caden proces nie \"krad\u0142\" zasob\u00f3w od innych.<\/p>\n<h4>Limit CPU<\/h4>\n<p>\nPomimo podobie\u0144stw w konfiguracjach limit\u00f3w i zapyta\u0144 w K8s, ich implementacja r\u00f3\u017cni si\u0119 zasadniczo: to <b>najbardziej myl\u0105ca<\/b> i najmniej udokumentowana cz\u0119\u015b\u0107.<\/p>\n<p>K8s wykorzystuje <noindex><a rel=\"nofollow\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/scheduler\/sched-design-CFS.txt\">mechanizm kwot CFS<\/a><\/noindex> do realizacji limit\u00f3w. Ich ustawienia okre\u015blane s\u0105 w plikach <code>cfs_period_us<\/code> i <code>cfs_quota_us<\/code> w katalogu cgroup (tam r\u00f3wnie\u017c znajduj\u0105 si\u0119 pliki <code>cpu.share<\/code>).<\/p>\n<p>W przeciwie\u0144stwie do <code>cpu.share<\/code>, kwota opiera si\u0119 na <b>okresie czasu<\/b>, a nie na dost\u0119pnej mocy procesora. <code>cfs_period_us<\/code> okre\u015bla d\u0142ugo\u015b\u0107 okresu (epoki) \u2014 zawsze 100000 \u03bcs (100 ms). W K8s istnieje mo\u017cliwo\u015b\u0107 zmiany tej warto\u015bci, jednak obecnie jest ona dost\u0119pna tylko w wersji alfa. Planista wykorzystuje epok\u0119 do ponownego uruchamiania wykorzystanych kwot. Drugi plik, <code>cfs_quota_us<\/code>, okre\u015bla dost\u0119pny czas (kwot\u0119) w ka\u017cdej epoce. Zauwa\u017c, \u017ce jest ona r\u00f3wnie\u017c podana w mikrosekundach. Kwota mo\u017ce przekracza\u0107 d\u0142ugo\u015b\u0107 epoki; innymi s\u0142owy, mo\u017ce by\u0107 wi\u0119ksza ni\u017c 100 ms.<\/p>\n<p>Przyjrzyjmy si\u0119 dw\u00f3m scenariuszom na maszynach z 16 rdzeniami (najpopularniejszy typ komputer\u00f3w u nas w Omio):<\/p>\n<p><img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/61c6105320af3a92a91cec1007da0d45.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Scenariusz 1: 2 w\u0105tki i limit 200 ms. Bez throttlingu<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/c33993341d5395bb73dda1f4c8482a11.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Scenariusz 2: 10 w\u0105tk\u00f3w i limit 200 ms. Throttling zaczyna si\u0119 po 20 ms, dost\u0119p do zasob\u00f3w CPU zostaje wznowiony po dodatkowych 80 ms<\/i><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce ustawili\u015bcie limit CPU na <b>2<\/b> rdzenie; Kubernetes przet\u0142umaczy t\u0119 warto\u015b\u0107 na 200 ms. Oznacza to, \u017ce kontener mo\u017ce wykorzysta\u0107 maksymalnie 200 ms czasu procesora bez throttlingu.<\/p>\n<p>I tu zaczyna si\u0119 najciekawsze. Jak wspomniano powy\u017cej, dost\u0119pna kwota wynosi 200 ms. Je\u015bli r\u00f3wnocze\u015bnie dzia\u0142a <b>dziesi\u0119\u0107<\/b> strumieni na 12-rdzeniowej maszynie (patrz ilustracja do scenariusza 2), podczas gdy wszystkie inne pody s\u0105 nieaktywne, kwota zostanie wyczerpana w ci\u0105gu zaledwie 20 ms (poniewa\u017c 10 * 20 ms = 200 ms), a wszystkie strumienie tego poda \"zawiesz\u0105 si\u0119\" <i>(throttle)<\/i> na nast\u0119pne 80 ms. Sytuacj\u0119 pogarsza ju\u017c wspomniany <noindex><a rel=\"nofollow\" href=\"https:\/\/bugzilla.kernel.org\/show_bug.cgi?id=198197\">b\u0142\u0105d planera<\/a><\/noindex>, przez kt\u00f3ry wyst\u0119puje nadmierne throttling i kontener nie mo\u017ce wykorzysta\u0107 nawet dost\u0119pnej kwoty.<\/p>\n<h2>Jak oceni\u0107 throttling w podach?<\/h2>\n<p>\nWystarczy wej\u015b\u0107 do poda i wykona\u0107 <code>cat \/sys\/fs\/cgroup\/cpu\/cpu.stat<\/code>.<\/p>\n<ul>\n<li> <code>nr_periods<\/code> \u2014 ca\u0142kowita liczba okres\u00f3w planera;<\/li>\n<li> <code>nr_throttled<\/code> \u2014 liczba okres\u00f3w throttlingu w sk\u0142adzie <code>nr_periods<\/code>;<\/li>\n<li> <code>throttled_time<\/code> \u2014 \u0142\u0105czny czas throttlingu w nanosekundach.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/a1818614914a8c31f7f7f1331cc02e8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Co tak naprawd\u0119 si\u0119 dzieje?<\/h3>\n<p>\nW rezultacie uzyskujemy wysoki throttling w wszystkich aplikacjach. Czasami jest on <b>p\u00f3\u0142tora raza<\/b> silniejszy ni\u017c przewidywane!<\/p>\n<p>Prowadzi to do r\u00f3\u017cnych b\u0142\u0119d\u00f3w \u2014 awarii kontroli gotowo\u015bci (readiness), zawieszania si\u0119 kontener\u00f3w, przerywania po\u0142\u0105cze\u0144 sieciowych, timeout\u00f3w w wywo\u0142aniach serwisowych. Ostatecznie objawia si\u0119 to zwi\u0119kszon\u0105 latencj\u0105 i wzrostem liczby b\u0142\u0119d\u00f3w.<\/p>\n<h2>Rozwi\u0105zanie i konsekwencje<\/h2>\n<p>\nTutaj wszystko jest proste. Zrezygnowali\u015bmy z limit\u00f3w CPU i zaj\u0119li\u015bmy si\u0119 aktualizacj\u0105 j\u0105dra systemu operacyjnego w klastrach do najnowszej wersji, w kt\u00f3rej b\u0142\u0105d zosta\u0142 naprawiony. Liczba b\u0142\u0119d\u00f3w (HTTP 5xx) w naszych us\u0142ugach natychmiast znacznie spad\u0142a:<\/p>\n<h3>B\u0142\u0119dy HTTP 5xx<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/86ab1694b952b5451a4ae075cbda2788.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>B\u0142\u0119dy HTTP 5xx jednego krytycznie wa\u017cnego serwisu<\/i><\/p>\n<h3>Czas odpowiedzi p95<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/63922c8eb468366a7d05154a3adf40e6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Op\u00f3\u017anienie zapyta\u0144 krytycznie wa\u017cnego serwisu, 95. percentyl<\/i><\/p>\n<h3>Koszty eksploatacji<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Limity CPU i agresywny throttling w Kubernetes\" src=\"\/wp-content\/uploads\/2020\/04\/8405c26fcbd82853e296fa7e3bcba131.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Liczba wydanych godzin egzemplarzowych<\/i><\/p>\n<h2>Gdzie jest haczyk?<\/h2>\n<p>\nJak wspomniano na pocz\u0105tku artyku\u0142u:<\/p>\n<blockquote><p>Mo\u017cna por\u00f3wna\u0107 to do mieszkania komunalnego\u2026 Kubernetes dzia\u0142a jako agent nieruchomo\u015bci. Ale jak powstrzyma\u0107 najemc\u00f3w przed konfliktami mi\u0119dzy sob\u0105? Co je\u015bli jeden z nich, powiedzmy, postanowi zaj\u0105\u0107 \u0142azienk\u0119 na p\u00f3\u0142 dnia?<\/p><\/blockquote>\n<p>\nOto w czym tkwi haczyk. Jeden nieodpowiedzialny kontener mo\u017ce wch\u0142on\u0105\u0107 wszystkie dost\u0119pne zasoby procesora w maszynie. Je\u015bli masz solidny stos aplikacji (na przyk\u0142ad odpowiednio skonfigurowane JVM, Go, Node VM), to nie jest problem: mo\u017cna pracowa\u0107 w takich warunkach przez d\u0142ugi czas. Ale je\u015bli aplikacje s\u0105 \u017ale zoptymalizowane lub w og\u00f3le nie s\u0105 zoptymalizowane (<code>FROM java:latest<\/code>), sytuacja mo\u017ce wymkn\u0105\u0107 si\u0119 spod kontroli. W Omio mamy zautomatyzowane podstawowe pliki Dockerfile z odpowiednimi ustawieniami domy\u015blnymi dla g\u0142\u00f3wnych j\u0119zyk\u00f3w, wi\u0119c taki problem nie wyst\u0105pi\u0142.<\/p>\n<p>Zalecamy monitorowanie metryk <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brendangregg.com\/usemethod.html\">U\u017bYJ<\/a><\/noindex> (u\u017cycie, nasycenie i b\u0142\u0119dy), op\u00f3\u017anienia API i cz\u0119sto\u015b\u0107 wyst\u0119powania b\u0142\u0119d\u00f3w. Upewnij si\u0119, \u017ce wyniki spe\u0142niaj\u0105 oczekiwania.<\/p>\n<h2>Linki<\/h2>\n<p>\nTaka jest nasza historia. Nast\u0119puj\u0105ce materia\u0142y bardzo pomog\u0142y zrozumie\u0107, co si\u0119 dzieje:<\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/scheduler\/sched-design-CFS.txt\">kernel.org \u2192 Harmonogram CFS<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/scheduler\/sched-bwc.txt\">kernel.org \u2192 Kontrola przepustowo\u015bci CFS<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/engineering.squarespace.com\/blog\/2017\/understanding-linux-container-scheduling\">Zrozumienie harmonogramowania kontener\u00f3w w systemie Linux<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/www.linuxjournal.com\/content\/everything-you-need-know-about-linux-containers-part-i-linux-control-groups-and-process\">Wszystko, co musisz wiedzie\u0107 o kontenerach Linux, cz\u0119\u015b\u0107 I: grupy kontrolne Linuxa i izolacja proces\u00f3w<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/k8s.af\/\">Historie o b\u0142\u0119dach Kubernetes<\/a><\/noindex> \u2014 szukaj \u201ecpu throttling\u201d.<\/li>\n<\/ul>\n<p>\nRaporty o b\u0142\u0119dach Kubernetes:<\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/51135#issuecomment-373454012\">#51135: Avoid setting CPU limits for Guaranteed pods<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/67577\">#67577: CFS quotas can lead to unnecessary throttling<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/bobrik\/2030ff040fad360327a5fab7a09c4ff1\">Zbyt agresywny CFS<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>\nCzy napotka\u0142e\u015b podobne problemy w swojej praktyce lub masz do\u015bwiadczenie zwi\u0105zane z ograniczaniem w konteneryzowanych \u015brodowiskach produkcyjnych? Podziel si\u0119 swoj\u0105 histori\u0105 w komentarzach!<\/p>\n<h2>P.S. od t\u0142umacza<\/h2>\n<p>\nPrzeczytaj tak\u017ce na naszym blogu:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/459326\/\">Automatyczne skalowanie i zarz\u0105dzanie zasobami w Kubernetes (przegl\u0105d i wideo z wyk\u0142adu)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/418269\/\">Jak dzia\u0142a mened\u017cer CPU w Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/342822\/\">Co si\u0119 dzieje w Kubernetes podczas uruchamiania kubectl run? Cz\u0119\u015b\u0107 2<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/489668\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u044d\u0442\u0430 \u043f\u043e\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f Omio \u2014 \u0435\u0432\u0440\u043e\u043f\u0435\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u0439 \u2014 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0442\u0435\u043e\u0440\u0438\u0438 \u0434\u043e \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0435\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Kubernetes. \u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u043b\u0443\u0447\u0430\u044f\u043c\u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043a\u0440\u0443\u0433\u043e\u0437\u043e\u0440, \u043d\u043e \u0438 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0414\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043b\u0438 \u0432\u0430\u043c \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u00ab\u0437\u0430\u0441\u0442\u0440\u0435\u0432\u0430\u043b\u043e\u00bb \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u0430\u043b\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":77694,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-77693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u044d\u0442\u0430 \u043f\u043e\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f Omio \u2014 \u0435\u0432\u0440\u043e\u043f\u0435\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u0439 \u2014 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0442\u0435\u043e\u0440\u0438\u0438 \u0434\u043e \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0435\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Kubernetes.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47CPU-\u043b\u0438\u043c\u0438\u0442\u044b \u0438 \u0430\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u044b\u0439 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 \u0432 Kubernetes | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u044d\u0442\u0430 \u043f\u043e\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f Omio \u2014 \u0435\u0432\u0440\u043e\u043f\u0435\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u0439 \u2014 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0442\u0435\u043e\u0440\u0438\u0438 \u0434\u043e \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0435\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Kubernetes.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-04-12T23:42:39+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-12T23:42:39+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Limity CPU i agresywne ograniczanie w Kubernetes | ProHoster","description":"Przyp. t\u0142um.: ta pouczaj\u0105ca historia Omio \u2014 europejskiego agregatora podr\u00f3\u017cy \u2014 prowadzi czytelnik\u00f3w od podstawowej teorii do fascynuj\u0105cych praktycznych niuans\u00f3w w konfiguracji Kubernetes.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47CPU-\u043b\u0438\u043c\u0438\u0442\u044b \u0438 \u0430\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u044b\u0439 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 \u0432 Kubernetes | ProHoster","og:description":"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u044d\u0442\u0430 \u043f\u043e\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f Omio \u2014 \u0435\u0432\u0440\u043e\u043f\u0435\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u0430 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u0439 \u2014 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0442\u0435\u043e\u0440\u0438\u0438 \u0434\u043e \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0435\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Kubernetes.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/cpu-limity-i-agressivnyj-trottling-v-kubernetes","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-04-12T23:42:39+00:00","article:modified_time":"2020-04-12T23:42:39+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"77693","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:13:23","updated":"2022-09-29 12:06:45","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/77693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=77693"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/77693\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/77694"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=77693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=77693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=77693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}