Néng Kubernetes Leeschtung Rotschléi

Néng Kubernetes Leeschtung Rotschléi

Moien alleguer! Mäin Numm ass Oleg Sidorenkov, ech schaffen bei DomClick als Chef vun der Infrastrukturteam. Mir hunn Kubik an der Produktioun fir méi wéi dräi Joer benotzt, a während dëser Zäit hu mir vill verschidden interessant Momenter domat erlieft. Haut wäert ech Iech soen wéi Dir mat der richteger Approche nach méi Leeschtung aus Vanille Kubernetes fir Äre Stärekoup ausdrécke kënnt. Bereet stänneg goen!

Dir wësst all ganz gutt datt Kubernetes e skalierbare Open Source System fir Containerorchestratioun ass; gutt, oder 5 Binären déi Magie funktionnéieren andeems Dir de Liewenszyklus vun Äre Mikroservicer an engem Serverëmfeld managen. Zousätzlech ass et e zimlech flexibel Tool dat ka montéiert ginn wéi Lego fir maximal Personnalisatioun fir verschidden Aufgaben.

An alles schéngt gutt ze sinn: geheien Serveren an de Stärekoup wéi Brennholz an e Feierkëscht, an Dir wësst keng Trauer. Awer wann Dir fir d'Ëmwelt sidd, denkt Dir: "Wéi kann ech d'Feier brennen an de Bësch erspueren?" An anere Wierder, wéi Dir Weeër fannt fir d'Infrastruktur ze verbesseren an d'Käschte ze reduzéieren.

1. Monitor Equipe an Applikatioun Ressourcen

Néng Kubernetes Leeschtung Rotschléi

Ee vun den allgemengsten, awer effektivste Methoden ass d'Aféierung vun Ufroen / Limiten. Deelt Uwendungen no Nummraim, an Nummraim duerch Entwécklungsteams. Virum Deployment, setzt d'Applikatiounswäerter fir de Konsum vu Prozessor Zäit, Erënnerung an ephemeral Späichere fest.

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

Duerch d'Erfahrung si mir zur Konklusioun komm: Dir sollt d'Demande vun de Grenzen net méi wéi zweemol opblasen. De Volume vum Stärekoup gëtt op Ufroe berechent, a wann Dir Uwendungen en Ënnerscheed an de Ressourcen gitt, zum Beispill 5-10 Mol, da stellt Iech vir wat mat Ärem Node geschitt wann et mat Pods gefëllt ass an op eemol eng Belaaschtung kritt. Näischt gutt. Op e Minimum, throttling, a maximal, Dir Äddi dem Aarbechter a kritt eng zyklesch Belaaschtung op déi verbleiwen Noden nodeems d'Pods ufänken ze beweegen.

Zousätzlech, mat der Hëllef limitranges Am Ufank kënnt Dir Ressourcewäerter fir de Container setzen - Minimum, Maximum a Standard:

➜  ~ 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

Vergiesst net d'Namespace Ressourcen ze limitéieren sou datt eng Equipe net all d'Ressourcen vum Cluster iwwerhuelen kann:

➜  ~ 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

Wéi kann aus der Beschreiwung gesi ginn resourcequotas, Wann d'Ops-Team Pods ofsetzen wëllt, déi nach 10 CPU verbrauchen, erlaabt de Scheduler dëst net a werfen e Feeler:

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

Fir esou e Problem ze léisen, kënnt Dir e Tool schreiwen, zum Beispill, wéi dat, kënnen den Zoustand vun de Kommando Ressourcen späicheren an engagéieren.

2. Wielt déi optimal Dateilagerung

Néng Kubernetes Leeschtung Rotschléi

Hei géif ech gär op d'Thema vun persistent Bänn an der Disk Subsystem vun Kubernetes Aarbechter Node beréieren. Ech hoffen datt keen de "Cube" op enger HDD an der Produktioun benotzt, awer heiansdo ass eng regulär SSD net méi genuch. Mir hunn e Problem begéint wou d'Logbicher den Disk ëmbréngen wéinst I/O Operatiounen, an et ginn net vill Léisungen:

  • Benotzt High-Performance SSDs oder schalt op NVMe (wann Dir Är eege Hardware verwalten).

  • Reduzéieren de Logbicherniveau.

  • Maacht "smart" Balance vu Pods déi d'Disk vergewaltegt (podAntiAffinity).

Den Écran hei uewen weist wat geschitt ënner nginx-ingress-Controller op der Scheif wann Access_logs Logbuch aktivéiert ass (~ 12 Tausend Logbicher / sec). Dës Konditioun kann natierlech zu der Degradatioun vun all Uwendungen op dësem Node féieren.

Wat PV ugeet, leider, ech hunn net alles probéiert Arten Persistent Volumen. Benotzt déi bescht Optioun déi Iech passt. Historesch ass et an eisem Land geschitt, datt e klengen Deel vun de Servicer RWX-Bänn erfuerderen, a viru laanger Zäit hunn se ugefaang NFS-Späichere fir dës Aufgab ze benotzen. Bëlleg an ... genuch. Natierlech hunn hien an ech Schäiss giess - Segen dech, awer mir hunn geléiert et auszestëmmen, a mäi Kapp mécht net méi wéi. A wa méiglech, plënneren op S3 Objet Stockage.

3. Sammelt optimiséiert Biller

Néng Kubernetes Leeschtung Rotschléi

Et ass am beschten fir Container-optimiséiert Biller ze benotzen fir datt Kubernetes se méi séier kënne sichen a méi effizient ausféieren. 

Optimiséiert heescht datt d'Biller:

  • nëmmen eng Applikatioun enthalen oder nëmmen eng Funktioun ausféieren;

  • kleng a Gréisst, well grouss Biller méi schlëmm iwwer d'Netz iwwerdroe ginn;

  • Gesondheet a Bereetschaft Endpunkter hunn, déi Kubernetes erlaben Handlung am Fall vun Ausdauer ze huelen;

  • benotzen Container-frëndlech Betribssystemer (wéi Alpine oder CoreOS), déi méi resistent géint Konfiguratioun Feeler sinn;

  • benotzt Multi-Etapp Builds sou datt Dir nëmmen kompiléiert Uwendungen ofsetzen kënnt an net déi begleedend Quellen.

Et gi vill Tools a Servicer déi Iech erlaben Biller op der Flucht ze kontrolléieren an ze optimiséieren. Et ass wichteg se ëmmer um neiste Stand ze halen a fir Sécherheet ze testen. Als Resultat kritt Dir:

  1. Reduzéiert Netzwierkbelaaschtung op de ganze Cluster.

  2. Reduzéiert Container Startzäit.

  3. Méi kleng Gréisst vun Ärem ganze Docker Registry.

4. Benotzt DNS Cache

Néng Kubernetes Leeschtung Rotschléi

Wa mir iwwer héich Lasten schwätzen, dann ass d'Liewen zimlech schlecht ouni den DNS-System vum Cluster ofzestëmmen. Eemol hunn d'Kubernetes Entwéckler hir Kube-dns Léisung ënnerstëtzt. Et gouf och hei ëmgesat, awer dës Software war net besonnesch ofgestëmmt an huet net déi erfuerderlech Leeschtung produzéiert, obwuel et schéngt eng einfach Aufgab ze sinn. Dunn erschéngen Coredns, op déi mir gewiesselt hunn a keng Trauer haten; et gouf spéider de Standard DNS Service a K8s. Irgendwann sinn mir op 40 Tausend RPS op den DNS System gewuess, an dës Léisung gouf och net genuch. Awer, duerch Gléck, Nodelocaldns koum eraus, alias Node lokal Cache, alias NodeLocal DNSCache.

Firwat benotze mir dëst? Et gëtt e Feeler am Linux Kernel, deen, wann multiple Uriff duerch Conntrack NAT iwwer UDP, zu enger Coursebedingung fir Entréen an Conntrack Dëscher féieren, an en Deel vum Traffic duerch NAT ass verluer (all Rees duerch de Service ass NAT). Nodelocaldns léist dëse Problem andeems Dir NAT entlooss gëtt an d'Verbindung mat TCP op Upstream DNS upgraden, souwéi lokal Cache Upstream DNS Ufroen (inklusiv e kuerzen 5 Sekonnen negativen Cache).

5. Skala pods horizontal a vertikal automatesch

Néng Kubernetes Leeschtung Rotschléi

Kënnt Dir mat Vertraue soen datt all Är Mikroservicer prett sinn fir eng zwee bis dräimol Erhéijung vun der Belaaschtung? Wéi richteg Ressourcen op Är Uwendungen ze verdeelen? E puer Pods laafen iwwer d'Aarbechtslaascht ze halen kann iwwerflësseg sinn, awer se zréck an zréck ze halen riskéiert d'Ausdauer vun enger plötzlecher Erhéijung vum Traffic op de Service. Servicer wéi z Horizontal Pod Autoscaler и Vertikal Pod Autoscaler.

VPA erlaabt Iech automatesch Ufroen / Limiten vun Äre Container am Pod eropzesetzen ofhängeg vun der aktueller Notzung. Wéi kann et nëtzlech sinn? Wann Dir Pods hutt déi net aus irgendege Grënn horizontal skaléiert kënne ginn (wat net ganz zouverlässeg ass), da kënnt Dir probéieren Ännerungen op seng Ressourcen un VPA uvertraut. Seng Feature ass e Empfehlungssystem baséiert op historeschen an aktuellen Donnéeën vum metresche Server, also wann Dir net automatesch Ufroen / Limiten wëllt änneren, kënnt Dir einfach d'recommandéiert Ressourcen fir Är Container iwwerwaachen an d'Astellunge optimiséieren fir CPU ze späicheren an Erënnerung am Stärekoup.

Néng Kubernetes Leeschtung RotschléiBild gemaach vun https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

De Scheduler a Kubernetes baséiert ëmmer op Ufroen. Egal wéi ee Wäert Dir do setzt, de Scheduler sicht no engem passenden Node baséiert op deem. D'Limite Wäerter si gebraucht fir de Cubelet ze verstoen wéini de Pod ze drosselen oder ëmbréngen. A well deen eenzege wichtege Parameter den Ufrowäert ass, wäert de VPA domat schaffen. Wann Dir eng Applikatioun vertikal skaléiert, definéiert Dir wat d'Ufroe solle sinn. Wat geschitt dann mat de Grenzen? Dëse Parameter gëtt och proportional skaléiert.

Zum Beispill, hei sinn déi üblech Pod Astellunge:

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

De Empfehlungsmotor bestëmmt datt Är Applikatioun 300m CPU an 500Mi brauch fir richteg ze lafen. Dir kritt déi folgend Astellungen:

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

Wéi uewen ernimmt, ass dëst proportional Skala baséiert op Ufroen / Limite Verhältnis am Manifest:

  • CPU: 200m → 300m: Verhältnis 1:1.75;

  • Erënnerung: 250Mi → 500Mi: Verhältnis 1:2.

Wat et ass HPA, dann ass de Mechanismus vun der Operatioun méi transparent. Metriken wéi CPU a Gedächtnis gi geschuel, a wann den Duerchschnëtt vun alle Repliken d'Schwell iwwerschreift, gëtt d'Applikatioun mat +1 Sub skaléiert bis de Wäert ënner der Schwell fällt oder bis déi maximal Unzuel vun de Repliken erreecht gëtt.

Néng Kubernetes Leeschtung RotschléiBild gemaach vun https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

Zousätzlech zu den üblechen Metriken wéi CPU a Gedächtnis, kënnt Dir Schwellen op Är personaliséiert Metriken vum Prometheus setzen a mat hinnen schaffen wann Dir mengt datt dat déi genaust Indikatioun ass wéini Dir Är Applikatioun soll skaléieren. Wann d'Applikatioun ënner dem spezifizéierte metresche Schwell stabiliséiert ass, fänkt HPA un Pods erof op d'Mindestzuel vu Repliken ze skaléieren oder bis d'Laascht de spezifizéierte Schwell entsprécht.

6. Vergiesst net iwwer Node Affinitéit a Pod Affinitéit

Néng Kubernetes Leeschtung Rotschléi

Net all Node laafen op der selwechter Hardware, an net all Pods musse Computerintensiv Uwendungen lafen. Kubernetes erlaabt Iech d'Spezialisatioun vun Noden a Pods ze benotzen Node Affinitéit и Pod Affinitéit.

Wann Dir Wirbelen hutt, déi fir Computerintensiv Operatiounen gëeegent sinn, da fir maximal Effizienz ass et besser Uwendungen un déi entspriechend Wirbelen ze verbannen. Fir dëst ze benotzen nodeSelector mat engem Node Label.

Loosst d'soen, datt Dir zwee Wirbelen hunn: ee mat CPUType=HIGHFREQ an eng grouss Zuel vu séier Käre, aner mat MemoryType=HIGHMEMORY méi Erënnerung a méi séier Leeschtung. Deen einfachste Wee ass den Détachement un engem Node ze ginn HIGHFREQandeems Dir op d'Sektioun bäidréit spec dëse Selector:

…
nodeSelector:
	CPUType: HIGHFREQ

Eng méi deier a spezifesch Manéier dëst ze maachen ass ze benotzen nodeAffinity am Feld affinity Sektioun spec. Et ginn zwou Méiglechkeeten:

  • requiredDuringSchedulingIgnoredDuringExecution: schwéier Astellung (de Scheduler wäert Pods nëmmen op spezifesch Noden ofsetzen (an néierens soss));

  • preferredDuringSchedulingIgnoredDuringExecution: mëll Astellung (de Scheduler probéiert op spezifesch Wirbelen z'installéieren, a wann dat klappt, probéiert et op den nächsten verfügbaren Node z'installéieren).

Dir kënnt eng spezifesch Syntax spezifizéieren fir Node-Etiketten ze managen, wéi z In, NotIn, Exists, DoesNotExist, Gt oder Lt. Denkt awer drun datt komplex Methoden a laange Lëschte vun Etiketten d'Entscheedung an kriteschen Situatiounen verlangsamen. An anere Wierder, halen et einfach.

Wéi uewen erwähnt, erlaabt Kubernetes Iech d'Affinitéit vun den aktuellen Pods ze setzen. Dat ass, Dir kënnt sécher sinn datt verschidde Pods mat anere Pods an der selwechter Disponibilitéitszone (relevant fir Wolleken) oder Noden zesumme schaffen.

В podAffinity Rand affinity Sektioun spec déi selwecht Felder sinn disponibel wéi am Fall vun nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution и preferredDuringSchedulingIgnoredDuringExecution. Deen eenzegen Ënnerscheed ass dat matchExpressions wäert d'Pods un en Node binden, dee schonn e Pod mat deem Label leeft.

Kubernetes bitt och e Feld podAntiAffinity, wat am Géigendeel de Pod net un engem Node mat spezifesche Pods bindt.

Iwwer Ausdréck nodeAffinity Déi selwecht Berodung ka ginn: probéiert d'Regele einfach a logesch ze halen, probéiert net d'Pod-Spezifikatioun mat enger komplexer Rei vu Regelen ze iwwerlaascht. Et ass ganz einfach eng Regel ze kreéieren déi net mat de Konditioune vum Cluster entsprécht, onnéideg Belaaschtung op de Scheduler erstellt an d'Gesamtleistung reduzéiert.

7. Taints & Toleranzen

Et gëtt en anere Wee fir de Scheduler ze managen. Wann Dir e grousse Stärekoup mat Honnerte vu Wirbelen an Dausende vu Mikroservicer hutt, dann ass et ganz schwéier datt verschidde Pods net op bestëmmte Wirbelen gehost ginn.

De Mechanismus vu Verschmotzungen - Regele verbidden - hëlleft mat dësem. Zum Beispill, a bestëmmte Szenarie kënnt Dir bestëmmte Noden verbidden Pods ze lafen. Fir Taint op e spezifesche Node z'applizéieren, musst Dir d'Optioun benotzen taint an kubectl. Spezifizéiert de Schlëssel a Wäert an dann Taint wéi NoSchedule oder NoExecute:

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

Et ass och derwäert ze bemierken datt de Schmiermechanismus dräi Haapteffekter ënnerstëtzt: NoSchedule, NoExecute и PreferNoSchedule.

  • NoSchedule heescht datt et fir de Moment keng entspriechend Entrée an der Pod Spezifizéierung gëtt tolerations, et wäert net fäeg sinn um Node ofgesat ze ginn (an dësem Beispill node10).

  • PreferNoSchedule - vereinfacht Versioun NoSchedule. An dësem Fall probéiert de Scheduler net Pods ze verdeelen déi keng passende Entrée hunn tolerations pro Node, awer dëst ass keng schwéier Limitatioun. Wann et keng Ressourcen am Stärekoup sinn, da fänken Pods op dësem Node ofzesetzen.

  • NoExecute - dësen Effekt léist déi direkt Evakuéierung vu Pods aus, déi keng entspriechend Entrée hunn tolerations.

Interessanterweis kann dëst Verhalen mam Toleratiounsmechanismus annuléiert ginn. Dëst ass bequem wann et e "verbueden" Node gëtt an Dir braucht nëmmen Infrastrukturservicer drop ze placéieren. Wéi maachen ech et? Erlaabt nëmmen déi Pods fir déi et eng passend Toleranz gëtt.

Hei ass wéi d'Pod Spezifizéierung ausgesäit:

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

Dëst bedeit net datt de nächste Redploy op dëse bestëmmte Node fällt, dëst ass net den Node Affinity Mechanismus an nodeSelector. Awer andeems Dir verschidde Funktiounen kombinéiert, kënnt Dir ganz flexibel Scheduler Astellunge erreechen.

8. Set Pod Deployment Prioritéit

Just well Dir Pods un Noden zougewisen hutt heescht net datt all Pods mat der selwechter Prioritéit behandelt musse ginn. Zum Beispill, Dir wëllt vläicht e puer Pods virun aneren ofsetzen.

Kubernetes bitt verschidde Weeër fir Pod Prioritéit a Preemption ze konfiguréieren. De Kader besteet aus verschiddenen Deeler: Objet PriorityClass an Feld Beschreiwunge priorityClassName an der Pod Spezifizéierung. Loosst eis e Beispill kucken:

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"

Mir kreéieren PriorityClass, gitt et en Numm, Beschreiwung a Wäert. Déi méi héich value, der méi héich Prioritéit. De Wäert kann all 32-Bit Ganzt manner wéi oder gläich wéi 1 sinn. D'Verschiebung wäert nëmme geschéien wann eng héich Prioritéit Pod keng Plaz huet fir sech ëmzedréien, da ginn e puer vun de Pods aus engem bestëmmte Node evakuéiert. Wann dëse Mechanismus ze steif fir Iech ass, kënnt Dir d'Optioun derbäi preemptionPolicy: Never, an da gëtt et keng Viraussetzung, de Pod steet als éischt an der Schlaang a waart op de Scheduler fir gratis Ressourcen dofir ze fannen.

Als nächst erstelle mir e Pod an deem mir den Numm uginn 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
          

Dir kënnt esou vill Prioritéit Klassen schafen wéi Dir wëllt, obwuel et recommandéiert ass net mat dëser gedroe ewech ze kréien (soen, limitéiert Iech op niddereg, mëttel- an héich Prioritéit).

Also, wann néideg, kënnt Dir d'Effizienz erhéijen fir kritesch Servicer z'installéieren wéi nginx-ingress-Controller, Coredns, etc.

9. Optimiséiert den ETCD Cluster

Néng Kubernetes Leeschtung Rotschléi

ETCD kann de Gehir vum ganze Cluster genannt ginn. Et ass ganz wichteg d'Operatioun vun dëser Datebank op engem héijen Niveau z'erhalen, well d'Vitesse vun Operatiounen am Cube hänkt dovun of. Eng zimlech Standard, a gläichzäiteg, gutt Léisung wier den ETCD Cluster op de Masterknäppchen ze halen fir e Minimum Verzögerung op de Kube-Apiserver ze hunn. Wann Dir dëst net maache kënnt, da setzt d'ETCD sou no wéi méiglech, mat gudder Bandbreedung tëscht Participanten. Opgepasst och op wéivill Wirbelen aus ETCD kënnen ausfalen ouni Schued fir de Stärekoup

Néng Kubernetes Leeschtung Rotschléi

Denkt drun, datt exzessiv Erhéijung vun der Zuel vun de Memberen an engem Stärekoup Feeler Toleranz op Käschte vun Leeschtung Erhéijung kann, alles soll an Moderatioun ginn.

Wa mir iwwer d'Ariichten vum Service schwätzen, ginn et e puer Empfehlungen:

  1. Hutt gutt Hardware, baséiert op der Gréisst vum Stärekoup (Dir kënnt liesen hei).

  2. Tweak e puer Parameteren wann Dir e Stärekoup tëscht e Paar DCs oder Ärem Netzwierk verbreet hutt an Disken léisst vill ze wënschen (Dir kënnt liesen hei).

Konklusioun

Dësen Artikel beschreift d'Punkten déi eis Team probéiert ze respektéieren. Dëst ass keng Schrëtt-fir-Schrëtt Beschreiwung vun Aktiounen, awer Optiounen déi nëtzlech kënne sinn fir de Clusteroverhead ze optimiséieren. Et ass kloer datt all Stärekoup eenzegaarteg ass op seng eege Manéier, an d'Konfiguratiounsléisungen kënnen immens variéieren, sou datt et interessant wier Äre Feedback ze kréien wéi Dir Äre Kubernetes-Cluster iwwerwaacht a wéi Dir seng Leeschtung verbessert. Deelt Är Erfahrung an de Kommentaren, et wäert interessant sinn ze wëssen.

Source: will.com