ProHoster > Blog > İdarə > Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
Qeyd. tərcümə.: Avropa səyahət aqreqatoru Omionun bu xəbərdarlıq hekayəsi oxucuları əsas nəzəriyyədən Kubernetes konfiqurasiyasının heyrətamiz praktik incəliklərinə aparır. Belə hallarla tanışlıq insanın dünyagörüşünün genişlənməsinə deyil, həm də qeyri-ciddi problemlərin qarşısını almağa kömək edir.
Tətbiqin yerində "ilişib qalması", sağlamlıq yoxlaması üçün sorğulara cavab verməməsi və bu davranışın səbəbini başa düşə bilmədiyiniz faktı ilə heç qarşılaşmısınızmı? Mümkün izahatlardan biri CPU resursları üzrə kvota limiti ilə bağlıdır. Bu məqalədə müzakirə olunacaq.
TL; DR:
CFS kvota xətası olan Linux nüvəsinin versiyasından istifadə edirsinizsə, Kubernetes-də CPU limitlərini deaktiv etməyi (və ya Kubelet-də CFS kvotalarını deaktiv etməyi) tövsiyə edirik. Əsasında var ciddi və yaxşı tanınır həddindən artıq tənzimləmə və gecikmələrə səbəb olan bir səhv.
Omioda bütün infrastruktur Kubernetes tərəfindən idarə olunur. Bütün dövlət və vətəndaşlığı olmayan iş yüklərimiz yalnız Kubernetes-də işləyir (biz Google Kubernetes Mühərrikindən istifadə edirik). Son altı ayda biz təsadüfi yavaşlamaları müşahidə etməyə başladıq. Proqramlar dondurulur və ya sağlamlıq yoxlamalarına cavab vermir, şəbəkə bağlantısını itirir və s. Bu cür davranış bizi uzun müddət çaşdırdı və nəhayət, problemi ciddi şəkildə həll etmək qərarına gəldik.
Məqalənin xülasəsi:
Konteynerlər və Kubernetes haqqında bir neçə söz;
CPU sorğuları və limitləri necə həyata keçirilir;
CPU limitinin çox nüvəli mühitlərdə necə işləməsi;
CPU tənzimləməsini necə izləmək olar;
Problemin həlli və detallar.
Konteynerlər və Kubernetes haqqında bir neçə söz
Kubernetes əslində infrastruktur dünyasında müasir standartdır. Onun əsas vəzifəsi konteyner orkestridir.
Konteynerlər
Keçmişdə serverlərdə işləmək üçün Java JARs/WARs, Python Eggs və ya icra olunanlar kimi artefaktlar yaratmalı idik. Bununla belə, onların işləməsi üçün əlavə iş görməli idin: iş vaxtını (Java/Python) quraşdırmaq, lazımi faylları lazımi yerlərə qoymaq, əməliyyat sisteminin müəyyən versiyası ilə uyğunluğu təmin etmək və s. Başqa sözlə, konfiqurasiya idarəçiliyinə çox diqqət yetirməli idiniz (bu, tez-tez tərtibatçılar və sistem administratorları arasında mübahisəyə səbəb olur).
Konteynerlər hər şeyi dəyişdi. İndi konteyner şəkli artefaktdır. O, yalnız proqramı deyil, həm də tam işləmə mühitini (Java / Python / ...), həmçinin əvvəlcədən quraşdırılmış və işə hazır olan zəruri faylları / paketləri ehtiva edən bir növ genişləndirilmiş icra edilə bilən fayl kimi təqdim edilə bilər. Konteynerlər heç bir əlavə addım olmadan müxtəlif serverlərdə yerləşdirilə və işlədilə bilər.
Bundan əlavə, konteynerlər öz sandbox mühitində işləyirlər. Onların öz virtual şəbəkə adapterləri, məhdud girişi olan öz fayl sistemi, öz proses iyerarxiyası, CPU və yaddaşla bağlı öz məhdudiyyətləri və s. Bütün bunlar Linux nüvəsinin xüsusi alt sistemi - ad məkanları (adlar boşluqları) sayəsində həyata keçirilir.
Kubernetes
Daha əvvəl qeyd edildiyi kimi, Kubernetes konteyner orkestridir. Bu belə işləyir: siz ona bir maşın hovuzu verirsiniz və sonra deyirsiniz: "Hey Kubernetes, hər biri 2 prosessor və 3 GB yaddaşla konteynerimin on nümunəsini işlədin və onları işləməyə davam edin!". Qalan işləri Kubernetes həll edəcək. O, pulsuz imkanlar tapacaq, konteynerləri işə salacaq və lazım olduqda onları yenidən işə salacaq, versiyaları dəyişdirərkən yeniləməni yayacaq və s. Əslində, Kubernetes avadanlığı mücərrədləşdirir və müxtəlif sistemləri tətbiqləri yerləşdirmək və işə salmaq üçün yararlı edir.
Sadə bir layman baxımından Kubernetes
Kubernetes-də istəklər və məhdudiyyətlər nədir
Yaxşı, konteynerləri və Kubernetləri tapdıq. Eyni maşında bir neçə konteynerin yerləşə biləcəyini də bilirik.
Kommunal bir mənzillə bir bənzətmə çəkə bilərsiniz. Geniş otaq (maşın/yığışdır) götürülüb bir neçə kirayəçiyə (konteyner) verilir. Kubernetes rieltor kimi fəaliyyət göstərir. Sual yaranır, kiracıları bir-biri ilə münaqişələrdən necə saxlamaq olar? Əgər onlardan biri, deyək ki, yarım gün vanna otağına getməyə qərar versə?
İstəklər və məhdudiyyətlər burada işə düşür. CPU tələb yalnız planlaşdırma məqsədləri üçün lazımdır. Bu, bir növ konteynerin "istək siyahısı" kimidir və ən uyğun qovşağı seçmək üçün istifadə olunur. Eyni zamanda, CPU Məhdudlaşdırmaq icarə müqaviləsi ilə müqayisə edilə bilər - konteyner üçün bir node seçən kimi bilməz hüdudları aşmaq. Və burada problem gəlir ...
Kubernetes-də sorğular və məhdudiyyətlər necə həyata keçirilir
Kubernetes, CPU məhdudiyyətlərini həyata keçirmək üçün nüvəyə daxil edilmiş tənzimləmə mexanizmindən (saat atlama) istifadə edir. Tətbiq limiti keçərsə, tənzimləmə aktivləşdirilir (yəni daha az CPU dövrü alır). Yaddaş sorğuları və limitləri fərqli şəkildə təşkil edilir ki, onları aşkar etmək daha asandır. Bunu etmək üçün podun son yenidən başlama vəziyyətini yoxlamaq kifayətdir: “OOMKilled”. CPU tənzimləmə o qədər də asan deyil, çünki K8s ölçüləri qruplara görə deyil, yalnız istifadəyə görə təqdim edir.
CPU sorğusu
CPU sorğusu necə həyata keçirilir
Sadəlik üçün, 4 nüvəli CPU ilə bir maşın nümunəsindən istifadə edərək prosesə baxaq.
K8s resurs bölgüsü (yaddaş və CPU) idarə etmək üçün qruplar mexanizmindən istifadə edir. Bunun üçün iyerarxik model mövcuddur: uşaq ana qrupun sərhədlərini miras alır. Dağıtım təfərrüatları virtual fayl sistemində saxlanılır (/sys/fs/cgroup). Bir prosessor vəziyyətində, bu /sys/fs/cgroup/cpu,cpuacct/*.
K8s fayldan istifadə edir cpu.share prosessor resurslarını ayırmaq. Bizim vəziyyətimizdə, kök qrupları CPU resurslarının 4096 payını alır - mövcud prosessor gücünün 100% -i (1 nüvə = 1024; bu sabit dəyərdir). Kök qrupu, göstərilən nəsillərin paylarından asılı olaraq resursları mütənasib şəkildə bölüşdürür cpu.share, onlar da öz növbəsində öz nəsilləri ilə eyni şeyi edirlər və s. Tipik bir Kubernetes hostunda kök qrupunun üç uşağı var: system.slice, user.slice и kubepods. İlk iki alt qrup kritik sistem yükləri və K8-lərdən kənar istifadəçi proqramları arasında resursları bölüşdürmək üçün istifadə olunur. Son - kubepods - resursları podlar arasında paylamaq üçün Kubernetes tərəfindən yaradılmışdır.
Yuxarıdakı diaqram birinci və ikinci alt qrupların qəbul edildiyini göstərir 1024 səhmlər, kuberpod alt qrupu isə ayrılır 4096 səhmlər. Bu necə mümkündür: kök qrupunun yalnız girişi var 4096 paylar və onun nəslinin paylarının cəmi bu rəqəmi xeyli üstələyir (6144)? Məsələ ondadır ki, dəyərin məntiqi mənası var, ona görə də Linux planlaşdırıcısı (CFS) ondan CPU resurslarını proporsional olaraq bölüşdürmək üçün istifadə edir. Bizim vəziyyətimizdə ilk iki qrup alır 680 real səhmlər (16,6-dan 4096%) və kubepod qalanları alır 2736 səhmlər. Boş vaxtlarda ilk iki qrup ayrılmış resurslardan istifadə etməyəcək.
Xoşbəxtlikdən, planlaşdırıcı istifadə edilməmiş CPU resurslarını israf etməmək üçün bir mexanizmə malikdir. O, "boş" tutumu qlobal hovuza köçürür, ondan əlavə prosessor gücünə ehtiyacı olan qruplara paylanır (köçürmə yuvarlaqlaşdırma itkilərinin qarşısını almaq üçün partiyalarda baş verir). Eyni üsul nəslin bütün nəslinə aiddir.
Bu mexanizm prosessor gücünün ədalətli paylanmasını təmin edir və heç bir prosesin başqalarından resursları “oğurlamasını” təmin edir.
CPU limiti
K8-lərdə limit və sorğu konfiqurasiyaları oxşar görünsə də, onların icrası əsaslı şəkildə fərqlidir: ən yanıltıcı və ən az sənədləşdirilmiş hissə.
K8s Dövrləri CFS kvota mexanizmi məhdudiyyətləri tətbiq etmək. Onların parametrləri fayllarda göstərilmişdir cfs_period_us и cfs_quota_us cgroup kataloqunda (bir fayl da var cpu.share).
Fərqli cpu.share, kvota əsaslanır müddət, və mövcud prosessor gücündə deyil. cfs_period_us dövrün (epoxanın) müddətini təyin edir - həmişə 100000 µs (100 ms) təşkil edir. K8-lərdə bu dəyəri dəyişdirmək üçün bir seçim var, lakin bu, hələlik yalnız alfa-da mövcuddur. Planlayıcı istifadə edilmiş kvotaları yenidən başlatmaq üçün epoxdan istifadə edir. ikinci fayl, cfs_quota_us, hər bir dövrdə mövcud vaxtı (kvota) müəyyən edir. Qeyd edək ki, o, mikrosaniyələrlə də göstərilib. Kvota bir dövrün uzunluğunu keçə bilər; başqa sözlə, 100 ms-dən çox ola bilər.
16 nüvəli maşınlarda iki ssenariyə baxaq (Omio-da ən çox yayılmış maşın növü):
Ssenari 1: 2 başlıq və 200ms limiti. Tıxanma yoxdur
Ssenari 2: 10 mövzu və 200 ms limit. Dəqiqləşdirmə 20 ms-dən sonra başlayır, CPU resurslarına giriş başqa 80 ms-dən sonra bərpa olunur
Deyək ki, siz CPU limitini təyin etdiniz 2 ləpələr; Kubernetes bu dəyəri 200 ms-ə çevirəcək. Bu o deməkdir ki, konteyner sıxılmadan maksimum 200 ms CPU vaxtından istifadə edə bilər.
Və burada əyləncə başlayır. Yuxarıda qeyd edildiyi kimi, mövcud kvota 200ms-dir. Paralel işiniz varsa on 12 nüvəli maşındakı iplər (ssenari 2 üçün təsvirə baxın), bütün digər podlar boş olarkən, kvota cəmi 20 ms-də tükənəcək (çünki 10 * 20 ms = 200 ms) və bu podun bütün ipləri asılacaq » (qaz) növbəti 80 ms üçün. Artıq qeyd olunanlar vəziyyəti daha da ağırlaşdırır planlayıcı səhvi, buna görə həddindən artıq tənzimləmə baş verir və konteyner hətta mövcud kvotanı işlədə bilmir.
Podlarda tənzimləməni necə qiymətləndirmək olar?
Sadəcə poda daxil olun və edin cat /sys/fs/cgroup/cpu/cpu.stat.
nr_periods planlaşdırıcı dövrlərin ümumi sayıdır;
nr_throttled — kompozisiyada tənzimləyici dövrlərin sayı nr_periods;
Nəticədə, bütün tətbiqlərdə yüksək tənzimləmə əldə edirik. Bəzən o da olur bir yarım dəfə gözləniləndən daha güclü!
Bu, müxtəlif səhvlərə gətirib çıxarır - hazırlıq yoxlamalarının uğursuzluğu, konteynerin donması, şəbəkə bağlantısının kəsilməsi, xidmət zəngləri daxilində fasilələr. Nəhayət, bu, artan gecikmə və artan xəta dərəcələrinə çevrilir.
Qərar və nəticələr
Burada hər şey sadədir. Biz CPU məhdudiyyətlərindən imtina etdik və klasterlərdəki OS nüvəsini səhvin düzəldildiyi ən son versiyaya yeniləməyə başladıq. Xidmətlərimizdəki səhvlərin sayı (HTTP 5xx) dərhal əhəmiyyətli dərəcədə azaldı:
HTTP 5xx səhvləri
Bir kritik xidmət üçün HTTP 5xx xətaları
p95 cavab müddəti
Kritik Xidmət Sorğunun Gecikməsi, 95-ci faiz
Əməliyyat xərcləri
Keçirilən nümunə saatlarının sayı
Tutmaq nədir?
Məqalənin əvvəlində deyildiyi kimi:
Siz kommunal mənzillə bir bənzətmə çəkə bilərsiniz ... Kubernetes rieltor kimi fəaliyyət göstərir. Bəs kirayəçiləri bir-biri ilə münaqişələrdən necə saxlamaq olar? Əgər onlardan biri, deyək ki, yarım gün vanna otağına getməyə qərar versə?
Budur, tutmaq. Bir diqqətsiz konteyner maşındakı bütün mövcud CPU resurslarını istehlak edə bilər. Ağıllı proqram yığınınız varsa (məsələn, düzgün konfiqurasiya edilmiş JVM, Go, Node VM), onda bu problem deyil: belə şəraitdə uzun müddət işləyə bilərsiniz. Lakin tətbiqlər zəif optimallaşdırılıbsa və ya ümumiyyətlə optimallaşdırılmayıbsa (FROM java:latest), vəziyyət nəzarətdən çıxa bilər. Omio-da bizdə əsas dil yığını üçün adekvat defoltlara malik avtomatlaşdırılmış əsas Dockerfiles var, ona görə də bu problem mövcud deyildi.
Metriklərə nəzarət etməyi tövsiyə edirik Istifadə (istifadə, doyma və səhvlər), API gecikmələri və səhv dərəcələri. Nəticələrin gözləntilərinizə uyğun olduğundan əmin olun.
References
Bu bizim tariximizdir. Aşağıdakı materiallar nə baş verdiyini anlamağa çox kömək etdi:
Təcrübənizdə oxşar problemlərlə qarşılaşmısınız və ya konteynerləşdirilmiş istehsal mühitlərində tənzimləmə ilə bağlı təcrübəniz varmı? Hekayənizi şərhlərdə paylaşın!