Kubernetes-də ilk tətbiqi yerləşdirərkən beş qaçır

Kubernetes-də ilk tətbiqi yerləşdirərkən beş qaçırAris Dreamer tərəfindən uğursuzluq

Bir çox insanlar tətbiqi Kubernetes-ə köçürməyin kifayət olduğunu düşünür (ya Helm-dən istifadə edərək, ya da əl ilə) - və xoşbəxtlik olacaq. Ancaq hər şey o qədər də sadə deyil.

Komanda Mail.ru Bulud Həlləri DevOps mühəndisi Julian Gindy-nin məqaləsini tərcümə etdi. O, miqrasiya prosesində şirkətinin hansı tələlərlə üzləşdiyini deyir ki, siz eyni dırmıqda addımlamayasınız.

Birinci addım: Pod sorğuları və limitləri qurun

Podlarımızın işləyəcəyi təmiz bir mühit qurmaqla başlayaq. Kubernetes pod planlaşdırma və uğursuzluqda əladır. Ancaq məlum oldu ki, planlaşdırıcı bəzən müvəffəqiyyətlə işləmək üçün nə qədər resurs lazım olduğunu təxmin etmək çətindirsə, pod yerləşdirə bilmir. Resurslar və məhdudiyyətlər üçün sorğuların göründüyü yer budur. Sorğu və limitlərin təyin edilməsinə ən yaxşı yanaşma haqqında çoxlu mübahisələr var. Bəzən elə gəlir ki, bu, həqiqətən də elmdən daha çox sənətdir. Bizim yanaşmamız budur.

Pod sorğuları podu optimal şəkildə yerləşdirmək üçün planlaşdırıcının istifadə etdiyi əsas dəyərdir.

Haqqında Kubernetes sənədləri: Filtr addımı Podun planlaşdırıla biləcəyi qovşaqlar dəstini müəyyən edir. Məsələn, PodFitsResources filtri qovşağın xüsusi resurs sorğularını təmin etmək üçün kifayət qədər resurs olub olmadığını yoxlayır.

Tətbiq sorğularından elə istifadə edirik ki, nə qədər resurs olduğunu təxmin edə bilək əslində Tətbiqin düzgün işləməsi üçün ona ehtiyac var. Bu şəkildə planlaşdırıcı qovşaqları real şəkildə yerləşdirə bilər. Biz hər bir podun kifayət qədər çox sayda resursa malik olmasını təmin etmək üçün əvvəlcə marja ilə sorğular təyin etmək istəyirdik, lakin biz qeyd etdik ki, planlaşdırma vaxtları əhəmiyyətli dərəcədə artıb və bəzi podlar heç vaxt tam planlaşdırılmayıb, sanki onlar üçün heç bir resurs sorğusu alınmayıb.

Bu halda, planlaşdırıcı tez-tez podları "sıxıb çıxarar" və onları yenidən planlaşdıra bilməzdi, çünki idarəetmə müstəvisində proqramın planlaşdırma alqoritminin əsas komponenti olan nə qədər resurs tələb olunacağı barədə heç bir təsəvvür yox idi.

Pod məhdudiyyətləri pod üçün daha aydın limitdir. Bu, klasterin konteynerə ayıracağı resursların maksimum miqdarını təmsil edir.

Yenə -dən rəsmi sənədlər: Konteynerin 4 GiB yaddaş limiti varsa, kubelet (və konteynerin işləmə müddəti) onu tətbiq edəcək. İş vaxtı konteynerin göstərilən resurs limitindən çox istifadə etməsinə mane olur. Məsələn, konteynerdəki proses icazə verilən yaddaş miqdarından çox istifadə etməyə çalışdıqda, sistem nüvəsi prosesi "yaddaş tükəndi" (OOM) xətası ilə dayandırır.

Konteyner həmişə resurs sorğusunun müəyyən etdiyindən daha çox resurs istifadə edə bilər, lakin heç vaxt limitdən artıq istifadə edə bilməz. Bu dəyəri düzgün təyin etmək çətindir, lakin çox vacibdir.

İdeal olaraq, sistemdəki digər proseslərə müdaxilə etmədən bir prosesin həyat dövrü ərzində podun resurs tələblərinin dəyişməsini istəyirik - bu, məhdudiyyətlərin qoyulmasının məqsədidir.

Təəssüf ki, hansı dəyərləri təyin etmək barədə konkret göstərişlər verə bilmərəm, lakin biz özümüz aşağıdakı qaydalara əməl edirik:

  1. Yük test alətindən istifadə edərək, biz trafikin əsas səviyyəsini simulyasiya edirik və pod resurslarının (yaddaş və prosessor) istifadəsini müşahidə edirik.
  2. Pod sorğularını ixtiyari olaraq aşağı qiymətə təyin edin (resurs limiti sorğuların dəyərindən təxminən 5 dəfə çoxdur) və müşahidə edin. Sorğular çox aşağı səviyyədə olduqda, proses başlaya bilmir və bu, çox vaxt sirli Go icra zamanı xətalarına səbəb olur.

Qeyd edim ki, daha yüksək resurs məhdudiyyətləri planlaşdırmanı çətinləşdirir, çünki podun kifayət qədər resursları olan hədəf node lazımdır.

Təsəvvür edin ki, 4 GB yaddaş kimi çox yüksək resurs limiti olan yüngül veb serveriniz var. Bu proses çox güman ki, üfüqi olaraq genişləndirilməli olacaq və hər bir yeni pod ən azı 4 GB mövcud yaddaşa malik bir qovşaqda planlaşdırılmalıdır. Əgər belə bir qovşaq yoxdursa, klaster bu podu emal etmək üçün yeni bir qovşaq təqdim etməlidir, bu bir az vaxt apara bilər. Sürətli və hamar miqyaslaşdırmanı təmin etmək üçün resurs sorğuları və limitlər arasında minimum fərqə nail olmaq vacibdir.

İkinci addım: Canlılıq və Hazırlıq Testlərini qurun

Bu, Kubernetes cəmiyyətində tez-tez müzakirə olunan başqa bir incə mövzudur. Canlılıq və Hazırlıq testlərini yaxşı başa düşmək vacibdir, çünki onlar proqram təminatının sabit işləməsi üçün mexanizm təmin edir və dayanma müddətini minimuma endirir. Düzgün konfiqurasiya edilmədikdə, onlar tətbiqinizin performansına ciddi təsir göstərə bilər. Aşağıda hər iki nümunənin xülasəsi verilmişdir.

Canlılıq konteynerin işlədiyini göstərir. Əgər uğursuz olarsa, kubelet konteyneri öldürür və onun üçün yenidən başlatma siyasəti aktivləşdirilir. Konteyner Canlılıq Probu ilə təchiz olunmayıbsa, defolt vəziyyət müvəffəq olacaq - qeyd edildiyi kimi Kubernetes sənədləri.

Canlılıq zondları ucuz olmalıdır, yəni çoxlu resurs istehlak etməməlidir, çünki onlar tez-tez işləyir və tətbiqin işlədiyi barədə Kubernetesə məlumat verməlidirlər.

Hər saniyədə işləmək seçimini təyin etsəniz, bu, saniyədə 1 sorğu əlavə edəcək, ona görə də unutmayın ki, bu trafiki emal etmək üçün əlavə resurslar tələb olunacaq.

Şirkətimizdə Liveness testləri tətbiqin əsas komponentlərini sınaqdan keçirir, hətta verilənlər (məsələn, uzaq verilənlər bazasından və ya keşdən) tam mövcud olmasa belə.

Tətbiqlərdə sadəcə olaraq 200 cavab kodunu qaytaran "sağlamlıq" son nöqtəsi qurmuşuq. Bu, prosesin işlədiyini və sorğuları idarə edə bilməsinin göstəricisidir (lakin hələlik trafik deyil).

Nümunə Hazırlıq konteynerin sorğulara xidmət göstərməyə hazır olub olmadığını göstərir. Hazırlıq yoxlaması uğursuz olarsa, son nöqtə nəzarətçisi podun IP ünvanını podla uyğun gələn bütün xidmətlərin son nöqtələrindən silir. Bu, Kubernetes sənədlərində də deyilir.

Hazırlıq zondları daha çox resurs istehlak edir, çünki onlar proqramın sorğuları qəbul etməyə hazır olduğunu göstərmək üçün arxa tərəfə vurmalıdırlar.

İcmada verilənlər bazasına birbaşa daxil olub-olmaması ilə bağlı çoxlu müzakirələr gedir. Yerüstü xərcləri nəzərə alaraq (yoxlamalar tez-tez olur, lakin onlara nəzarət edilə bilər), biz qərara gəldik ki, bəzi tətbiqlər üçün trafikə xidmət göstərməyə hazır olmaq yalnız qeydlərin verilənlər bazasından geri qaytarıldığını yoxladıqdan sonra hesablanır. Yaxşı tərtib edilmiş hazırlıq sınaqları daha yüksək səviyyələrdə əlçatanlığı təmin etdi və yerləşdirmə zamanı dayanma müddətini aradan qaldırdı.

Tətbiqinizin hazırlığını yoxlamaq üçün verilənlər bazasına sorğu keçirmək qərarına gəlsəniz, onun mümkün qədər ucuz olduğundan əmin olun. Gəlin bu sorğunu götürək:

SELECT small_item FROM table LIMIT 1

Kubernetes-də bu iki dəyəri necə konfiqurasiya etdiyimizə dair bir nümunə:

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

Bəzi əlavə konfiqurasiya seçimləri əlavə edə bilərsiniz:

  • initialDelaySeconds - konteynerin işə salınması ilə zondların işə salınması arasında neçə saniyə keçəcək.
  • periodSeconds — nümunə qaçışları arasında gözləmə intervalı.
  • timeoutSeconds — podun fövqəladə hesab edildiyi saniyələrin sayı. Normal fasilə.
  • failureThreshold yenidən başladın siqnalı poda göndərilməzdən əvvəl sınaq uğursuzluqlarının sayıdır.
  • successThreshold pod hazır vəziyyətə keçməzdən əvvəl (pod işə salındıqda və ya bərpa edildikdə uğursuzluqdan sonra) uğurlu sınaqların sayıdır.

Üçüncü addım: Podun Defolt Şəbəkə Siyasətlərinin qurulması

Kubernetes "düz" şəbəkə topoqrafiyasına malikdir, standart olaraq bütün podlar bir-biri ilə birbaşa əlaqə qurur. Bəzi hallarda bu arzuolunan deyil.

Potensial təhlükəsizlik problemi ondan ibarətdir ki, təcavüzkar şəbəkədəki bütün podlara trafik göndərmək üçün tək həssas proqramdan istifadə edə bilər. Bir çox təhlükəsizlik sahələrində olduğu kimi burada da ən az imtiyaz prinsipi tətbiq olunur. İdeal olaraq, şəbəkə siyasətləri podlar arasında hansı əlaqəyə icazə verildiyini və hansının icazə verilmədiyini açıq şəkildə bildirməlidir.

Məsələn, aşağıdakılar müəyyən bir ad sahəsi üçün bütün daxil olan trafiki rədd edən sadə bir siyasətdir:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

Bu konfiqurasiyanın vizuallaşdırılması:

Kubernetes-də ilk tətbiqi yerləşdirərkən beş qaçır
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
Daha ətraflı məlumat burada.

Dördüncü addım: Qarmaqlar və Başlama Konteynerləri ilə Fərdi Davranış

Əsas məqsədlərimizdən biri tərtibatçılar üçün fasiləsiz Kubernetes-də yerləşdirmə təmin etmək idi. Bu çətindir, çünki proqramları bağlamaq və istifadə olunan resursları buraxmaq üçün bir çox variant var.

Xüsusilə çətinliklər yarandı Nginx. Bu Podları ardıcıllıqla yerləşdirərkən, uğurla tamamlanmadan aktiv bağlantıların kəsildiyini gördük.

İnternetdə geniş araşdırmadan sonra məlum oldu ki, Kubernetes podu bağlamadan əvvəl Nginx əlaqələrinin tükənməsini gözləmir. Pre-stop çəngəlinin köməyi ilə biz aşağıdakı funksionallığı həyata keçirdik və fasilələrdən tamamilə qurtula bildik:

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

Lakin nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

Başqa bir çox faydalı paradiqma, xüsusi proqramların işə salınmasını idarə etmək üçün init konteynerlərinin istifadəsidir. Tətbiq başlamazdan əvvəl işə salınmalı olan resurs-intensiv verilənlər bazası köçürmə prosesiniz varsa, bu xüsusilə faydalıdır. Siz həmçinin əsas proqram üçün belə bir limit təyin etmədən bu proses üçün daha yüksək resurs limitini təyin edə bilərsiniz.

Digər ümumi sxem bu etimadnamələri əsas modula təqdim edən init konteynerindəki sirlərə daxil olmaqdır ki, bu da əsas proqram modulunun özündən sirlərə icazəsiz girişin qarşısını alır.

Həmişə olduğu kimi, sənədlərdən bir sitat: init konteynerləri istifadəçi kodunu və ya proqramın konteyner görüntüsünün təhlükəsizliyini poza biləcək kommunal proqramları təhlükəsiz şəkildə idarə edir. Lazımsız alətləri ayrı saxlamaqla siz tətbiqin konteyner şəklinin hücum səthini məhdudlaşdırırsınız.

Beşinci addım: Kernel konfiqurasiyası

Nəhayət, daha inkişaf etmiş bir texnika haqqında danışaq.

Kubernetes sizə uyğun gördüyünüz halda iş yüklərini idarə etməyə imkan verən son dərəcə çevik platformadır. Son dərəcə resurs tələb edən bir sıra yüksək səmərəli proqramlarımız var. Geniş yükləmə testindən sonra, defolt Kubernetes parametrləri qüvvədə olan zaman tətbiqlərdən birinin gözlənilən trafik yükünü saxlamaqda çətinlik çəkdiyini gördük.

Bununla belə, Kubernetes sizə yalnız xüsusi pod üçün kernel parametrlərini dəyişən imtiyazlı konteyner işlətməyə imkan verir. Maksimum açıq əlaqə sayını dəyişdirmək üçün istifadə etdiyimiz budur:

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

Bu, çox vaxt lazım olmayan daha təkmil bir texnikadır. Ancaq tətbiqiniz ağır yükün öhdəsindən gəlməkdə çətinlik çəkirsə, bu parametrlərdən bəzilərini dəyişdirməyə cəhd edə bilərsiniz. Bu proses və fərqli dəyərlərin təyin edilməsi haqqında daha çox məlumat - həmişə olduğu kimi rəsmi sənədlərdə.

Nəticədə

Kubernetes qeyri-adi bir həll kimi görünsə də, tətbiqlərin rəvan işləməsini təmin etmək üçün bir neçə əsas addım atılmalıdır.

Kubernetes-ə miqrasiya zamanı "yük testi dövrü"nə riayət etmək vacibdir: tətbiqi işə salın, yük altında sınaqdan keçirin, ölçüləri və miqyaslama davranışını müşahidə edin, bu məlumatlar əsasında konfiqurasiyanı tənzimləyin, sonra bu dövrü yenidən təkrarlayın.

Gözlənilən trafiklə bağlı realist olun və hansı komponentlərin əvvəlcə pozulduğunu görmək üçün ondan kənara çıxmağa çalışın. Bu təkrarlanan yanaşma ilə, uğur əldə etmək üçün sadalanan tövsiyələrdən yalnız bir neçəsi kifayət edə bilər. Və ya daha dərin fərdiləşdirmə tələb edə bilər.

Həmişə özünüzə bu sualları verin:

  1. Tətbiqlər nə qədər resurs istehlak edir və bu məbləğ necə dəyişəcək?
  2. Həqiqi miqyas tələbləri hansılardır? Tətbiq orta hesabla nə qədər trafik idarə edəcək? Bəs pik trafik haqqında?
  3. Xidmət nə qədər tez-tez genişləndirilməlidir? Trafik qəbul etmək üçün yeni podlar nə qədər tez işə düşməlidir?
  4. Podlar necə zərif şəkildə bağlanır? Ümumiyyətlə lazımdırmı? İstifadə müddəti olmadan yerləşdirməyə nail olmaq mümkündürmü?
  5. Təhlükəsizlik risklərini minimuma endirmək və hər hansı bir təhlükə altında olan podlardan zərəri necə məhdudlaşdırmaq olar? Hər hansı xidmətin ehtiyacı olmayan icazələri və ya girişləri varmı?

Kubernetes, klasterdə minlərlə xidməti yerləşdirmək üçün ən yaxşı təcrübələrdən istifadə etməyə imkan verən inanılmaz platforma təqdim edir. Ancaq bütün tətbiqlər fərqlidir. Bəzən həyata keçirmək bir az daha çox iş tələb edir.

Xoşbəxtlikdən, Kubernetes bütün texniki məqsədlərə çatmaq üçün lazımi parametrləri təmin edir. Resurs sorğuları və məhdudiyyətləri, Canlılıq və Hazırlıq zondları, başlanğıc konteynerləri, şəbəkə siyasətləri və xüsusi kernel tənzimləmələrinin birləşməsindən istifadə etməklə siz xətalara dözümlülük və sürətli miqyaslanma ilə yanaşı yüksək performansa nail ola bilərsiniz.

Başqa nə oxumaq lazımdır:

  1. İstehsal Mühitlərində Konteynerlərin və Kubernetlərin işlədilməsi üçün ən yaxşı təcrübələr və ən yaxşı təcrübələr.
  2. Kubernetes üçün 90+ Faydalı Alətlər: Yerləşdirmə, İdarəetmə, Monitorinq, Təhlükəsizlik və s.
  3. Telegram-da Kubernetes ətrafında kanalımız.

Mənbə: www.habr.com

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