Тоғыз Kubernetes өнімділігі туралы кеңестер

Тоғыз Kubernetes өнімділігі туралы кеңестер

Бәріңе сәлем! Менің атым Олег Сидоренков, мен DomClick-те инфрақұрылымдық топтың жетекшісі болып жұмыс істеймін. Біз Кубикті өндірісте үш жылдан астам қолданып келеміз және осы уақыт ішінде біз онымен көптеген түрлі қызықты сәттерді бастан өткердік. Бүгін мен сізге дұрыс тәсілмен кластеріңіз үшін ванильді Кубернетес өнімділігін қалай сығып алуға болатынын айтамын. Тұрақты жүруге дайын!

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

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

1. Топ пен қолданба ресурстарын бақылау

Тоғыз Kubernetes өнімділігі туралы кеңестер

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

resources:
   requests:
     memory: 2Gi
     cpu: 250m
   limits:
     memory: 4Gi
     cpu: 500m

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

Сонымен қатар, көмегімен limitranges Бастапқыда контейнер үшін ресурс мәндерін орнатуға болады - минималды, максималды және әдепкі:

➜  ~ kubectl describe limitranges --namespace ops
Name:       limit-range
Namespace:  ops
Type        Resource           Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----        --------           ---   ---   ---------------  -------------  -----------------------
Container   cpu                50m   10    100m             100m           2
Container   ephemeral-storage  12Mi  8Gi   128Mi            4Gi            -
Container   memory             64Mi  40Gi  128Mi            128Mi          2

Бір топ кластердің барлық ресурстарын иелене алмайтындай етіп аттар кеңістігі ресурстарын шектеуді ұмытпаңыз:

➜  ~ kubectl describe resourcequotas --namespace ops
Name:                   resource-quota
Namespace:              ops
Resource                Used          Hard
--------                ----          ----
limits.cpu              77250m        80
limits.memory           124814367488  150Gi
pods                    31            45
requests.cpu            53850m        80
requests.memory         75613234944   150Gi
services                26            50
services.loadbalancers  0             0
services.nodeports      0             0

Сипаттамадан көрініп тұрғандай resourcequotas, егер операциялық топ тағы 10 процессорды тұтынатын қосқыштарды орналастырғысы келсе, жоспарлаушы бұған рұқсат бермейді және қате жібереді:

Error creating: pods "nginx-proxy-9967d8d78-nh4fs" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10

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

2. Оңтайлы файл сақтау орнын таңдаңыз

Тоғыз Kubernetes өнімділігі туралы кеңестер

Мұнда мен тұрақты томдар тақырыбына және Kubernetes жұмысшы түйіндерінің дискілік ішкі жүйесіне тоқталғым келеді. Өндірісте HDD-де ешкім «Кубты» пайдаланбайды деп үміттенемін, бірақ кейде әдеттегі SSD жеткіліксіз. Біз енгізу/шығару әрекеттеріне байланысты журналдар дискіні өлтіретін мәселеге тап болдық және көптеген шешімдер жоқ:

  • Жоғары өнімді SSD дискілерін пайдаланыңыз немесе NVMe-ге ауысыңыз (егер сіз өзіңіздің аппараттық құралыңызды басқарсаңыз).

  • Тіркеу деңгейін төмендетіңіз.

  • Дискіні зақымдайтын түйіршіктерді «ақылды» теңгерімдеңіз (podAntiAffinity).

Жоғарыдағы экран access_logs журналы қосулы кезде дискіге nginx-ingress-controller астында не болатынын көрсетеді (~12 мың журнал/сек). Бұл жағдай, әрине, осы түйіндегі барлық қолданбалардың деградациясына әкелуі мүмкін.

PV-ге келетін болсақ, өкінішке орай, мен бәрін сынап көрмедім түрлер Тұрақты көлемдер. Сізге сәйкес келетін ең жақсы нұсқаны пайдаланыңыз. Тарихи тұрғыдан алғанда, біздің елімізде қызметтердің аз бөлігі RWX көлемдерін қажет ететін жағдай болды және олар осы тапсырма үшін NFS жадын ұзақ уақыт бұрын пайдалана бастады. Арзан және... жеткілікті. Әрине, ол екеуміз боқ жедік - жарылқаңыз, бірақ біз оны реттеуді үйрендік, ал менің басым ауырмайды. Мүмкін болса, S3 нысан сақтау орнына көшіңіз.

3. Оңтайландырылған кескіндерді жинаңыз

Тоғыз Kubernetes өнімділігі туралы кеңестер

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

Оңтайландырылған кескіндер мынаны білдіреді:

  • тек бір қолданбаны қамтиды немесе бір ғана функцияны орындайды;

  • өлшемі кішкентай, өйткені үлкен кескіндер желі арқылы нашар беріледі;

  • Kubernetes тоқтап қалған жағдайда әрекет етуге мүмкіндік беретін денсаулық пен дайындықтың соңғы нүктелері болуы;

  • конфигурация қателеріне төзімдірек, контейнерге ыңғайлы операциялық жүйелерді (мысалы, Alpine немесе CoreOS) пайдаланыңыз;

  • ілеспе көздерді емес, тек құрастырылған қолданбаларды орналастыру үшін көп сатылы құрастыруларды пайдаланыңыз.

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

  1. Бүкіл кластерге желі жүктемесі азайтылды.

  2. Контейнерді іске қосу уақытын қысқарту.

  3. Бүкіл Docker тізілімінің кішірек өлшемі.

4. DNS кэшін пайдаланыңыз

Тоғыз Kubernetes өнімділігі туралы кеңестер

Егер біз жоғары жүктемелер туралы айтатын болсақ, онда кластердің DNS жүйесін баптаусыз өмір өте нашар. Бір кездері Kubernetes әзірлеушілері kube-dns шешімін қолдады. Ол мұнда да іске асырылды, бірақ бұл бағдарламалық жасақтама ерекше реттелмеген және қарапайым тапсырма сияқты көрінгенімен, қажетті өнімділікті бермеді. Содан кейін біз ауысқан және ешқандай қайғы-қасіретсіз coredns пайда болды; ол кейінірек K8s жүйесінде әдепкі DNS қызметі болды. Бір кездері біз DNS жүйесіне 40 мың rps дейін өстік, бұл шешім де жеткіліксіз болды. Бірақ, сәттілікке орай, Nodelocaldns шықты, aka node local cache, aka NodeLocal DNSCache.

Біз мұны не үшін қолданамыз? Linux ядросында қате бар, ол UDP арқылы NAT қосылымы арқылы бірнеше қоңырау шалу, контрак кестелеріндегі жазбалар үшін жарыс жағдайына әкеліп соқтырады және NAT арқылы трафиктің бір бөлігі жоғалады (қызмет арқылы әрбір сапар NAT болып табылады). Nodelocaldns бұл мәселені NAT-тан арылту және TCP қосылымын жоғары ағынды DNS-ке жаңарту, сондай-ақ жоғары ағындық DNS сұрауларын жергілікті кэштеу (оның ішінде қысқа 5 секундтық теріс кэш) арқылы шешеді.

5. Бөлшектерді көлденең және тігінен автоматты түрде масштабтаңыз

Тоғыз Kubernetes өнімділігі туралы кеңестер

Барлық микросервистер жүктемені екі-үш есе арттыруға дайын деп сеніммен айта аласыз ба? Қолданбаларыңызға ресурстарды қалай дұрыс бөлуге болады? Жұмыс жүктемесінің шегінен тыс жұмыс істейтін бірнеше қосқыштарды сақтау артық болуы мүмкін, бірақ оларды бір-бірінен кейін ұстап тұру қызметке трафиктің кенеттен ұлғаюынан тоқтап қалу қаупін тудырады. сияқты қызметтер Көлденең Pod Autoscaler и Vertical Pod Autoscaler.

VPA нақты пайдаланылуына байланысты подводтағы контейнерлердің сұрауларын/шектерін автоматты түрде көтеруге мүмкіндік береді. Бұл қалай пайдалы болуы мүмкін? Егер сізде қандай да бір себептермен көлденеңінен масштабтауға болмайтын бөтелкелер болса (бұл мүлдем сенімді емес), онда оның ресурстарына өзгертулерді VPA жүйесіне сеніп тапсыруға болады. Оның мүмкіндігі метрикалық серверден алынған тарихи және ағымдағы деректерге негізделген ұсыныстар жүйесі болып табылады, сондықтан сұрауларды/шектерді автоматты түрде өзгерткіңіз келмесе, контейнерлеріңіз үшін ұсынылған ресурстарды бақылап, орталық процессор мен процессорды сақтау үшін параметрлерді оңтайландыруға болады. кластердегі жады.

Тоғыз Kubernetes өнімділігі туралы кеңестерСурет https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231 сайтынан алынды

Кубернетестегі жоспарлаушы әрқашан сұрауларға негізделген. Онда қандай мәнді қойсаңыз да, жоспарлаушы оның негізінде қолайлы түйінді іздейді. Шектеу мәндері текшені қашан дроссельдеу немесе өлтіру керектігін түсіну үшін қажет. Жалғыз маңызды параметр сұраныстардың мәні болғандықтан, VPA онымен жұмыс істейді. Қолданбаны тігінен масштабтаған сайын, сұраулардың қандай болуы керектігін анықтайсыз. Сонда шектеулер не болады? Бұл параметр де пропорционалды түрде масштабталады.

Мысалы, кәдімгі подколь параметрлері:

resources:
   requests:
     memory: 250Mi
     cpu: 200m
   limits:
     memory: 500Mi
     cpu: 350m

Ұсыныс жүйесі қолданбаңыздың дұрыс жұмыс істеуі үшін 300 м CPU және 500 Mi қажет екенін анықтайды. Сіз келесі параметрлерді аласыз:

resources:
   requests:
     memory: 500Mi
     cpu: 300m
   limits:
     memory: 1000Mi
     cpu: 525m

Жоғарыда айтылғандай, бұл манифесттегі сұраулар/шектеу арақатынасына негізделген пропорционалды масштабтау:

  • Орталық процессор: 200м → 300м: қатынасы 1:1.75;

  • Жад: 250Mi → 500Mi: қатынасы 1:2.

Қатысты HPA, онда жұмыс істеу механизмі ашық болады. Орталық процессор және жад сияқты көрсеткіштер шекті мәнге ие және барлық көшірмелердің орташа мәні шекті мәннен асатын болса, мән шекті мәннен төмен түскенше немесе көшірмелердің ең көп санына жеткенше қолданба +1 кіші мәнге масштабталады.

Тоғыз Kubernetes өнімділігі туралы кеңестерСурет https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231 сайтынан алынды

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

6. Node Affinity және Pod Affinity туралы ұмытпаңыз

Тоғыз Kubernetes өнімділігі туралы кеңестер

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

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

Сізде екі түйін бар делік: біреуі бар CPUType=HIGHFREQ және жылдам ядролардың үлкен саны, басқасы бар MemoryType=HIGHMEMORY көбірек жады және жылдамырақ өнімділік. Ең оңай жолы - түйінге орналастыруды тағайындау HIGHFREQбөліміне қосу арқылы spec селектор келесідей:

…
nodeSelector:
	CPUType: HIGHFREQ

Мұны істеудің қымбатырақ және нақты жолы - пайдалану nodeAffinity алаңда affinity razdela spec. Екі нұсқа бар:

  • requiredDuringSchedulingIgnoredDuringExecution: қатты параметр (жоспарлаушы тек белгілі бір түйіндерде (және басқа еш жерде) подкасттарды орналастырады);

  • preferredDuringSchedulingIgnoredDuringExecution: жұмсақ параметр (жоспарлаушы белгілі бір түйіндерге орналастыруға тырысады, ал егер бұл сәтсіз болса, ол келесі қолжетімді түйінге орналастыруға тырысады).

сияқты түйін белгілерін басқару үшін арнайы синтаксисті көрсетуге болады In, NotIn, Exists, DoesNotExist, Gt немесе Lt. Дегенмен, жапсырмалардың ұзын тізімдеріндегі күрделі әдістер сыни жағдайларда шешім қабылдауды бәсеңдететінін есте сақтаңыз. Басқаша айтқанда, қарапайым болыңыз.

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

В podAffinity шеттер affinity razdela spec жағдайындағы сияқты бірдей өрістер қол жетімді nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution и preferredDuringSchedulingIgnoredDuringExecution. Жалғыз айырмашылығы сол matchExpressions подкасттарды сол белгі бар подкольді іске қосып тұрған түйінге байланыстырады.

Кубернетес сонымен қатар өрісті ұсынады podAntiAffinity, ол, керісінше, бөтелкені белгілі бір түйіндері бар түйінмен байланыстырмайды.

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

7. Дақтар мен төзімділіктер

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

Бұған тыйым салу механизмі көмектеседі. Мысалы, белгілі бір сценарийлерде белгілі түйіндердің қосқыштарды іске қосуына тыйым салуға болады. Белгілі бір түйінге бояуды қолдану үшін опцияны пайдалану керек taint kubectl ішінде. Кілт пен мәнді көрсетіңіз, содан кейін ұқсастығын көрсетіңіз NoSchedule немесе NoExecute:

$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoSchedule

Сондай-ақ, ластану механизмі үш негізгі әсерді қолдайтынын атап өткен жөн: NoSchedule, NoExecute и PreferNoSchedule.

  • NoSchedule әзірге подкаст сипаттамасында сәйкес жазба болмайтынын білдіреді tolerations, оны түйінде орналастыру мүмкін болмайды (бұл мысалда node10).

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

  • NoExecute - бұл әсер сәйкес жазбасы жоқ бүршіктердің дереу эвакуациялануын тудырады tolerations.

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

Қондырғы спецификациясы келесідей болады:

spec:
   tolerations:
     - key: "node-role.kubernetes.io/ingress"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"

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

8. Pod орналастыру басымдығын орнатыңыз

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

Kubernetes Pod Priority және Preemption конфигурациялаудың әртүрлі жолдарын ұсынады. Параметр бірнеше бөліктерден тұрады: нысан PriorityClass және өрістердің сипаттамасы priorityClassName спецификацияда. Мысал қарастырайық:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 99999
globalDefault: false
description: "This priority class should be used for very important pods only"

Біз жасаймыз PriorityClass, атын, сипаттамасын және мәнін беріңіз. Жоғары value, басымдық соғұрлым жоғары болады. Мән 32 1 000 000-нан аз немесе оған тең кез келген 000 биттік бүтін сан болуы мүмкін. Жоғары мәндер әдетте алдын ала алынбайтын миссия үшін маңызды жүйе қосқыштары үшін сақталған. Ауыстыру тек жоғары басымдылықтағы бұранданың айналатын жері болмаған жағдайда ғана орын алады, содан кейін белгілі бір түйіннен түйіршіктердің бір бөлігі эвакуацияланады. Бұл механизм сіз үшін тым қатаң болса, опцияны қосуға болады preemptionPolicy: Never, содан кейін ешқандай артықшылық болмайды, подкаст кезекте бірінші болып тұрады және жоспарлаушы ол үшін бос ресурстарды табуын күтеді.

Әрі қарай, біз атауды көрсететін подкаст жасаймыз priorityClassName:

apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
 spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
  priorityClassName: high-priority
          

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

Осылайша, қажет болса, nginx-ingress-controller, coredns және т.б. сияқты маңызды қызметтерді қолданудың тиімділігін арттыруға болады.

9. ETCD кластерін оңтайландыру

Тоғыз Kubernetes өнімділігі туралы кеңестер

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

Тоғыз Kubernetes өнімділігі туралы кеңестер

Кластердегі мүшелер санын шамадан тыс арттыру өнімділік есебінен ақауларға төзімділікті арттыруы мүмкін екенін есте сақтаңыз, барлығы модерацияда болуы керек.

Қызметті орнату туралы айтатын болсақ, бірнеше ұсыныстар бар:

  1. Кластердің өлшеміне негізделген жақсы жабдыққа ие болыңыз (оқуға болады осында).

  2. Егер сіз DC жұбының немесе желіңіздің арасында кластерді таратқан болсаңыз және дискілер қалағаныңызды қалдырса, бірнеше параметрлерді өзгертіңіз (оқуға болады). осында).

қорытынды

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

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