Kubernetes жүйесінде бірінші қолданбаны орналастыру кезінде бес қате

Kubernetes жүйесінде бірінші қолданбаны орналастыру кезінде бес қатеAris Dreamer түсірген сәтсіздік

Көптеген адамдар қосымшаны Kubernetes-ке беру жеткілікті деп ойлайды (Helm арқылы немесе қолмен) - және бақыт болады. Бірақ бәрі соншалықты қарапайым емес.

команда Mail.ru бұлтты шешімдері DevOps инженері Джулиан Джиндидің мақаласын аударған. Ол компанияның көші-қон процесінде қандай қиындықтарға тап болғанын айтады, сонда сіз бір тырмаға баспаңыз.

Бірінші қадам: Pod сұраулары мен шектеулерін орнату

Біздің бөтелкелер жұмыс істейтін таза ортаны орнатудан бастайық. Кубернетес подкастты жоспарлауда және істен шығуда тамаша. Бірақ сәтті жұмыс істеу үшін қанша ресурстар қажет екенін бағалау қиын болса, жоспарлаушы кейде подкастты орналастыра алмайтыны белгілі болды. Бұл жерде ресурстар мен шектеулерге сұраулар пайда болады. Сұраулар мен шектеулерді орнатудың ең жақсы тәсілі туралы көптеген пікірталастар бар. Кейде бұл шынымен ғылымнан гөрі өнер сияқты көрінеді. Міне, біздің көзқарасымыз.

Под сұраулары подкастты оңтайлы орналастыру үшін жоспарлаушы пайдаланатын негізгі мән.

Қайдан Kubernetes құжаттамасы: Сүзгі қадамы Pod жоспарлауға болатын түйіндер жинағын анықтайды. Мысалы, PodFitsResources сүзгісі түйіннен нақты ресурс сұрауларын қанағаттандыру үшін жеткілікті ресурстардың бар-жоғын тексеру үшін тексереді.

Қолданба сұрауларын біз қанша ресурстарды бағалай алатындай етіп пайдаланамыз іс жүзінде Қолданба дұрыс жұмыс істеуі үшін қажет. Осылайша жоспарлаушы түйіндерді нақты орналастыра алады. Бастапқыда біз әрбір Pod үшін жеткілікті ресурстарды қамтамасыз ету үшін сұрауларды артық жоспарлағымыз келді, бірақ біз жоспарлау уақыты айтарлықтай ұлғайғанын байқадық, ал кейбір Podтар олар үшін ресурс сұраулары болмағандай толық жоспарланбаған.

Бұл жағдайда жоспарлаушы жиі бөліктерді «сығып тастайды» және оларды қайта жоспарлауға мүмкіндігі болмайды, өйткені басқару жазықтығы жоспарлау алгоритмінің негізгі құрамдас бөлігі болып табылатын қолданбаға қанша ресурстар қажет болатынын білмеді.

Қоспа шектеулері подвод үшін нақтырақ шектеу болып табылады. Ол кластер контейнерге бөлетін ресурстардың ең көп мөлшерін көрсетеді.

Тағы да, бастап ресми құжаттама: Контейнердің жад шегі 4 ГБ болса, кубелет (және контейнердің орындалу уақыты) оны мәжбүрлейді. Орындау уақыты контейнердің көрсетілген ресурс шегінен артық пайдалануына жол бермейді. Мысалы, контейнердегі процесс жадтың рұқсат етілген көлемінен артық пайдалануға әрекет жасағанда, жүйе ядросы процесті «жады жоқ» (OOM) қатесі арқылы тоқтатады.

Контейнер әрқашан ресурс сұрауы көрсеткеннен көбірек ресурстарды пайдалана алады, бірақ ол ешқашан шектеуден артық пайдалана алмайды. Бұл мәнді дұрыс орнату қиын, бірақ бұл өте маңызды.

Ең дұрысы, жүйедегі басқа процестерге кедергі келтірмей, процестің өмірлік циклі кезінде подводтың ресурс талаптары өзгергенін қалаймыз - бұл шектеулерді орнату мақсаты.

Өкінішке орай, мен қандай мәндерді орнату керектігі туралы нақты нұсқаулар бере алмаймын, бірақ біз өзіміз келесі ережелерді ұстанамыз:

  1. Жүктемені тексеру құралын пайдалана отырып, біз трафиктің негізгі деңгейін имитациялаймыз және қосалқы ресурстарды (жад және процессор) пайдалануды байқаймыз.
  2. Қондырғы сұрауларын ерікті түрде төмен мәнге орнатыңыз (ресурс шегі сұраулар мәнінен шамамен 5 есе көп) және қадағалаңыз. Сұраулар тым төмен деңгейде болғанда, процесс басталмайды, бұл көбінесе Go орындау уақытының құпия қателерін тудырады.

Мен жоғарырақ ресурс шектеулері жоспарлауды қиындататынын ескертемін, себебі подводқа жеткілікті ресурстары бар мақсатты түйін қажет.

4 ГБ жады сияқты өте жоғары ресурс шегі бар жеңіл веб-серверіңіз бар жағдайды елестетіп көріңіз. Бұл процесті көлденеңінен кеңейту қажет болуы мүмкін және әрбір жаңа подкаст кемінде 4 ГБ қолжетімді жады бар түйінде жоспарлануы керек. Егер мұндай түйін болмаса, кластер осы подкастты өңдеу үшін жаңа түйінді енгізуі керек, бұл біраз уақыт алуы мүмкін. Жылдам және тегіс масштабтауды қамтамасыз ету үшін ресурс сұраулары мен шектеулер арасындағы ең аз айырмашылыққа қол жеткізу маңызды.

Екінші қадам: Жандылық пен дайындық сынақтарын орнатыңыз

Бұл Kubernetes қауымдастығында жиі талқыланатын тағы бір нәзік тақырып. Liveness және Readiness сынақтарын жақсы түсіну маңызды, өйткені олар бағдарламалық жасақтаманың тұрақты жұмыс істеу механизмін қамтамасыз етеді және тоқтау уақытын барынша азайтады. Дегенмен, олар дұрыс конфигурацияланбаса, қолданбаның жұмысына елеулі әсер етуі мүмкін. Төменде екі үлгінің де қысқаша мазмұны берілген.

Өмір контейнер жұмыс істеп тұрғанын көрсетеді. Егер ол сәтсіз болса, kubelet контейнерді өлтіреді және ол үшін қайта іске қосу саясаты қосылады. Егер контейнер Liveness Probe құрылғысымен жабдықталмаған болса, онда көрсетілгендей әдепкі күй сәтті болады Kubernetes құжаттамасы.

Жандылық зондтары арзан болуы керек, яғни көп ресурстарды тұтынбауы керек, өйткені олар жиі жұмыс істейді және Kubernetes-ке қолданбаның жұмыс істеп тұрғаны туралы хабарлауы керек.

Егер секунд сайын іске қосу опциясын орнатсаңыз, бұл секундына 1 сұрау қосады, сондықтан бұл трафикті өңдеу үшін қосымша ресурстар қажет болатынын ескеріңіз.

Біздің компанияда Liveness сынақтары деректер (мысалы, қашықтағы дерекқордан немесе кэштен) толық қолжетімді болмаса да, қолданбаның негізгі құрамдастарын тексереді.

Біз қолданбаларда жай ғана 200 жауап кодын қайтаратын "денсаулық" соңғы нүктесін орнаттық. Бұл процестің іске қосылғанын және сұрауларды өңдеуге қабілетті екенін көрсетеді (бірақ әлі трафик емес).

Үлгі Дайындық контейнер сұрауларға қызмет көрсетуге дайын екенін көрсетеді. Дайындық тексеруі сәтсіз болса, соңғы нүкте контроллері подкасттың IP мекенжайын подкольге сәйкес келетін барлық қызметтердің соңғы нүктелерінен жояды. Бұл Kubernetes құжаттамасында да айтылған.

Дайындық зондтары көбірек ресурстарды тұтынады, өйткені олар қолданбаның сұрауларды қабылдауға дайын екенін көрсететіндей серверге түсуі керек.

Деректер базасына тікелей кіру керек пе деген сұрақ қоғамда көп пікірталас тудыруда. Үстеме шығындарды ескере отырып (тексерулер жиі болады, бірақ оларды басқаруға болады), біз кейбір қолданбалар үшін трафикке қызмет көрсетуге дайындық деректер базасынан жазбалар қайтарылғанын тексергеннен кейін ғана есептеледі деп шештік. Жақсы жобаланған дайындық сынақтары қолжетімділіктің жоғары деңгейін қамтамасыз етті және орналастыру кезінде тоқтау уақытын болдырмайды.

Қолданбаңыздың дайындығын тексеру үшін дерекқорды сұрауды шешсеңіз, оның мүмкіндігінше арзан екеніне көз жеткізіңіз. Мына сұрауды алайық:

SELECT small_item FROM table LIMIT 1

Міне, Kubernetes-те осы екі мәнді конфигурациялаудың мысалы:

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

Кейбір қосымша конфигурация опцияларын қосуға болады:

  • initialDelaySeconds - контейнердің ұшырылуы мен зондтардың іске қосылуы арасында қанша секунд өтеді.
  • periodSeconds — үлгілерді орындау арасындағы күту аралығы.
  • timeoutSeconds — бөтелке апатты деп есептелетін секундтар саны. Қалыпты күту уақыты.
  • failureThreshold қайта іске қосу сигналы қосқышқа жіберілгенге дейінгі сынақ сәтсіздіктерінің саны.
  • successThreshold — подвод дайын күйге өткенге дейінгі сәтті сынақтар саны (қосқыш іске қосылғанда немесе қалпына келгенде сәтсіздіктен кейін).

Үшінші қадам: Pod әдепкі желі саясаттарын орнату

Kubernetes-те «жалпақ» желі топографиясы бар, әдепкі бойынша барлық подкладкалар бір-бірімен тікелей байланысады. Кейбір жағдайларда бұл қажет емес.

Қауіпсіздіктің ықтимал мәселесі – шабуылдаушы желідегі барлық қосқыштарға трафик жіберу үшін бір осал қолданбаны пайдалануы мүмкін. Қауіпсіздіктің көптеген салаларындағы сияқты, мұнда ең аз артықшылық принципі қолданылады. Ең дұрысы, желілік саясаттар подкасттар арасындағы қандай қосылымдарға рұқсат етілгенін және қайсысы рұқсат етілмегенін нақты көрсетуі керек.

Мысалы, келесідей белгілі бір аттар кеңістігі үшін барлық кіріс трафикті жоққа шығаратын қарапайым саясат:

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

Бұл конфигурацияның визуализациясы:

Kubernetes жүйесінде бірінші қолданбаны орналастыру кезінде бес қате
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
Егжей-тегжейлі осында.

Төртінші қадам: Ілмектермен және Init Контейнерлерімен теңшелетін әрекет

Біздің басты мақсаттарымыздың бірі - әзірлеушілер үшін тоқтаусыз Kubernetes-те орналастыруды қамтамасыз ету. Бұл қиын, себебі қолданбаларды өшірудің және олардың пайдаланылған ресурстарын шығарудың көптеген нұсқалары бар.

Ерекше қиындықтар туындады Nginx. Біз бұл Podтарды ретімен орналастыру кезінде сәтті аяқталмай тұрып белсенді қосылымдар үзілгенін байқадық.

Интернеттегі кең ауқымды зерттеулерден кейін Кубернетес подкастты өшірмес бұрын Nginx қосылымдарының таусылуын күтпейтіні белгілі болды. Алдын ала тоқтату ілгегінің көмегімен біз келесі функционалдылықты іске асырдық және тоқтап қалудан толығымен құтылдық:

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

Ал міне 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

Тағы бір өте пайдалы парадигма - нақты қолданбаларды іске қосу үшін init контейнерлерін пайдалану. Бұл, әсіресе, қолданба іске қосылмай тұрып іске қосылуы қажет ресурсты көп қажет ететін дерекқорды тасымалдау процесі болса пайдалы. Сондай-ақ, негізгі қолданба үшін мұндай шектеуді орнатпай, осы процесс үшін жоғарырақ ресурс шегін көрсетуге болады.

Тағы бір кең тараған схема - бұл тіркелгі деректерін негізгі модульге беретін, негізгі қолданба модулінің өзінен құпияларға рұқсатсыз кіруді болдырмайтын init контейнеріндегі құпияларға қол жеткізу.

Әдеттегідей, құжаттамадан үзінді: init контейнерлері қолданбаның контейнер кескінінің қауіпсіздігін бұзатын пайдаланушы кодын немесе утилиталарды қауіпсіз іске қосады. Қажетсіз құралдарды бөлек сақтау арқылы қолданбаның контейнер кескінінің шабуыл бетін шектейсіз.

Бесінші қадам: ядро ​​конфигурациясы

Соңында, неғұрлым жетілдірілген техника туралы сөйлесейік.

Kubernetes - бұл жұмыс жүктемелерін өзіңіз қалағаныңызша орындауға мүмкіндік беретін өте икемді платформа. Бізде ресурсты өте қажет ететін жоғары тиімді қосымшалар бар. Жүктеменің ауқымды сынағынан кейін біз әдепкі Kubernetes параметрлері жұмыс істеп тұрған кезде қолданбалардың бірінің күтілетін трафик жүктемесіне төтеп беру қиынға соққанын анықтадық.

Дегенмен, Kubernetes сізге арнайы подкаст үшін ядро ​​параметрлерін ғана өзгертетін артықшылықты контейнерді іске қосуға мүмкіндік береді. Ашық қосылымдардың максималды санын өзгерту үшін пайдаланғанымыз:

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

Бұл жиі қажет емес неғұрлым жетілдірілген әдіс. Бірақ қолданбаңыз ауыр жүктемені жеңе алмай жатса, осы параметрлердің кейбірін өзгертуге болады. Бұл процесс және әртүрлі мәндерді орнату туралы қосымша ақпарат - әдеттегідей ресми құжаттамада.

Қорытындылай келе

Kubernetes қораптан тыс шешім сияқты көрінуі мүмкін, бірақ қолданбалардың үздіксіз жұмыс істеуін қамтамасыз ету үшін бірнеше негізгі қадамдарды орындау қажет.

Kubernetes-ке көшу барысында «жүктемені тексеру циклін» сақтау маңызды: қолданбаны іске қосыңыз, оны жүктеме кезінде сынаңыз, көрсеткіштер мен масштабтау әрекетін бақылаңыз, осы деректер негізінде конфигурацияны реттеңіз, содан кейін осы циклды қайталаңыз.

Күтілетін трафик туралы шынайы болыңыз және қай құрамдастардың бірінші бұзылатынын көру үшін одан асып кетуге тырысыңыз. Бұл қайталанатын тәсілмен табысқа жету үшін аталған ұсыныстардың бірнешеуі ғана жеткілікті болуы мүмкін. Немесе тереңірек теңшеу қажет болуы мүмкін.

Әрқашан өзіңізге мына сұрақтарды қойыңыз:

  1. Қолданбалар қанша ресурстарды тұтынады және бұл сома қалай өзгереді?
  2. Нақты масштабтау талаптары қандай? Қолданба орта есеппен қанша трафикті өңдейді? Ең жоғары трафик туралы не деуге болады?
  3. Қызметті қаншалықты жиі кеңейту қажет болады? Трафикті қабылдау үшін жаңа блоктар қаншалықты жылдам іске қосылуы керек?
  4. Қапшықтар қаншалықты әдемі түрде жабылады? Бұл мүлдем қажет пе? Орналастыруға тоқтаусыз қол жеткізу мүмкін бе?
  5. Қауіпсіздік тәуекелдерін қалай азайтуға және кез келген бұзылған подкасттардың зақымдалуын шектеуге болады? Кез келген қызметтердің қажет емес рұқсаттары немесе рұқсаттары бар ма?

Kubernetes мыңдаған қызметтерді кластерде орналастыру үшін ең жақсы тәжірибелерді пайдалануға мүмкіндік беретін керемет платформаны ұсынады. Дегенмен, барлық қолданбалар әртүрлі. Кейде іске асыру біраз жұмысты қажет етеді.

Бақытымызға орай, Kubernetes барлық техникалық мақсаттарға жету үшін қажетті параметрлерді қамтамасыз етеді. Ресурс сұраулары мен шектеулерінің, Тұрақтылық пен Дайындық зондтарының, бастапқы контейнерлерінің, желі саясаттарының және реттелетін ядро ​​баптауының тіркесімін пайдалану арқылы қатеге төзімділік пен жылдам масштабтауға мүмкіндік беретін жоғары өнімділікке қол жеткізуге болады.

Тағы не оқу керек:

  1. Өндірістік орталарда контейнерлер мен кубернеттерді іске қосудың үздік тәжірибелері мен үздік тәжірибелері.
  2. Kubernetes үшін 90+ пайдалы құралдар: орналастыру, басқару, бақылау, қауіпсіздік және т.б.
  3. Telegram-дағы Kubernetes айналасындағы арнамыз.

Ақпарат көзі: www.habr.com

пікір қалдыру