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.

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə

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.

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
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

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
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ü):

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
Ssenari 1: 2 başlıq və 200ms limiti. Tıxanma yoxdur

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
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;
  • throttled_time nanosaniyələrdə yığılmış tənzimləmə vaxtıdır.

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə

Əslində nə baş verir?

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

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
Bir kritik xidmət üçün HTTP 5xx xətaları

p95 cavab müddəti

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
Kritik Xidmət Sorğunun Gecikməsi, 95-ci faiz

Əməliyyat xərcləri

Kubernetes-də CPU məhdudiyyətləri və aqressiv tənzimləmə
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:

Kubernetes səhv hesabatları:

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!

Tərcüməçidən PS

Bloqumuzda da oxuyun:

Mənbə: www.habr.com

Добавить комментарий