Over het algemeen is er altijd de noodzaak om een specifieke pool van bronnen voor een applicatie te waarborgen voor een correcte en stabiele werking. Maar wat als meerdere applicaties op dezelfde capaciteit draaien? Hoe kunnen we ervoor zorgen dat elk van hen de minimaal benodigde middelen heeft? Op welke manier kunnen we het verbruik van middelen beperken? Hoe kunnen we de belasting effectief verdelen over de nodes? Hoe kunnen we de werking van het horizontale schaalmechanisme garanderen in geval van toenemende belasting op de applicaties?

We moeten beginnen met de belangrijkste soorten middelen die in het systeem bestaan ā dit zijn natuurlijk de processortijd en het werkgeheugen. In de k8s-manifesten worden deze soorten middelen gemeten in de volgende eenheden:
- CPU ā in cores
- RAM ā in bytes
Voor elk type hulpbron is er de mogelijkheid om twee soorten eisen op te geven ā requests en limits. Requests beschrijft de minimale eisen aan de beschikbare middelen van de node voor het opstarten van de container (en de pod in het algemeen), terwijl limits een strikte beperking vaststelt van de middelen die aan de container beschikbaar zijn.
Het is belangrijk te begrijpen dat het in het manifest niet noodzakelijk is om beide typen expliciet te definiƫren, terwijl het gedrag als volgt zal zijn:
- Als alleen de limits voor de hulpbron expliciet zijn gedefinieerd, dan neemt de requests voor deze hulpbron automatisch de waarde aan die gelijk is aan de limits (dit kan worden bevestigd door de beschrijving van de entiteit aan te roepen). Dat wil zeggen, de werking van de container zal feitelijk worden beperkt door precies dezelfde hoeveelheid middelen die nodig zijn voor de opstart.
- Als voor de hulpbron alleen de requests expliciet zijn gedefinieerd, dan zijn er geen bovenlimieten voor deze hulpbron ā dat wil zeggen, de container is alleen beperkt door de middelen van de node zelf.
Er is ook de mogelijkheid om het middelenbeheer niet alleen op container-niveau, maar ook op namespace-niveau in te stellen met behulp van de volgende entiteiten:
- LimitRange ā beschrijft het beleid voor beperking op het niveau van container/pod in ns en is nodig om standaardbeperkingen voor de container/pod te beschrijven, evenals om het creĆ«ren van duidelijk te zware containers/pods (of omgekeerd) te voorkomen, hun aantal te beperken en mogelijke verschillen in waarden tussen limits en requests te bepalen.
- ResourceQuotas ā beschrijft het algemene beperkingbeleid voor alle containers in de ns en wordt meestal gebruikt om middelen tussen omgevingen te scheiden (handig wanneer omgevingen niet strikt zijn gescheiden op het niveau van knooppunten)
Hieronder staan voorbeelden van manifesten waarin de middelenbeperkingen zijn vastgesteld:
Op het niveau van een specifieke container:
containers: - name: app-nginx image: nginx resources: requests: memory: 1Gi limits: cpu: 200mDat wil zeggen, in dit geval is er minimaal 1G RAM en 0.2 CPU op het knooppunt vereist om de nginx-container te starten, terwijl de container maximaal 0.2 CPU en al het beschikbare RAM op het knooppunt kan gebruiken.
Op het niveau van de hele ns:
apiVersion: v1 kind: ResourceQuota metadata: name: nxs-test spec: hard: requests.cpu: 300m requests.memory: 1Gi limits.cpu: 700m limits.memory: 2GiDat wil zeggen, de som van alle aanvragen (requests) van de containers in de standaard ns mag niet meer zijn dan 300m voor CPU en 1G voor RAM, terwijl de som van alle limieten niet meer dan 700m voor CPU en 2G voor RAM mag zijn.
Standaard beperkingen voor containers in de ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-per-container spec: limits: - type: Container defaultRequest: cpu: 100m memory: 1Gi default: cpu: 1 memory: 2Gi min: cpu: 50m memory: 500Mi max: cpu: 2 memory: 4GiDat wil zeggen, in de standaard namespace zal voor alle containers standaard een aanvraag van 100m voor CPU en 1G voor RAM worden ingesteld, met een limiet van 1 CPU en 2G. Er zijn ook beperkingen ingesteld voor de mogelijke waarde in aanvragen/lijsten voor CPU (50m < x < 2) en RAM (500M < x < 4G).
Beperkingen op het niveau van pods in de ns:
apiVersion: v1 kind: LimitRange metadata: name: nxs-limit-pod spec: limits: - type: Pod max: cpu: 4 memory: 1GiDat wil zeggen, voor elke pod in de standaard ns is er een beperking van 4 vCPU en 1G ingesteld.
Nu willen we graag bespreken welke voordelen het instellen van deze beperkingen kan bieden.
Het mechanisme voor load balancing tussen knooppunten
Zoals bekend, is er een component in k8s, genaamd scheduler, die verantwoordelijk is voor het toewijzen van pods aan knooppunten volgens een bepaald algoritme. Dit algoritme doorloopt twee fasen bij het selecteren van de optimale knoop voor de uitvoering:
- Filtering
- Ranking
Dat wil zeggen, volgens het beschreven beleid worden in eerste instantie de knooppunten geselecteerd waar de pod kan worden uitgevoerd op basis van een set predicates (waaronder wordt gecontroleerd of er voldoende middelen op de knoop zijn voor het uitvoeren van de pod ā PodFitsResources), en vervolgens, voor elk van deze knooppunten, volgens priorities punten worden toegekend (waarbij geldt: hoe meer vrije bronnen er beschikbaar zijn op de node, hoe meer punten deze krijgt: LeastResourceAllocation/LeastRequestedPriority/BalancedResourceAllocation) en het wordt gestart op de node met het hoogste aantal punten (als meerdere nodes aan deze voorwaarde voldoen, wordt er willekeurig ƩƩn gekozen).
Het is belangrijk te begrijpen dat de scheduler bij het evalueren van de beschikbare bronnen van de node kijkt naar de gegevens die zijn opgeslagen in etcd - dat wil zeggen, naar de som van de gevraagde/l Limiet van elke pod die op deze node draait, maar niet naar het daadwerkelijke bronnenverbruik. Deze informatie kan worden verkregen met de output van de opdracht kubectl describe node $NODE, bijvoorbeeld:
# kubectl describe nodes nxs-k8s-s1
..
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
ingress-nginx nginx-ingress-controller-754b85bf44-qkt2t 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-flannel-26bl4 150m (0%) 300m (1%) 64M (0%) 500M (1%) 233d
kube-system kube-proxy-exporter-cb629 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system kube-proxy-x9fsc 0 (0%) 0 (0%) 0 (0%) 0 (0%) 233d
kube-system nginx-proxy-k8s-worker-s1 25m (0%) 300m (1%) 32M (0%) 512M (1%) 233d
nxs-monitoring alertmanager-main-1 100m (0%) 100m (0%) 425Mi (1%) 25Mi (0%) 233d
nxs-logging filebeat-lmsmp 100m (0%) 0 (0%) 100Mi (0%) 200Mi (0%) 233d
nxs-monitoring node-exporter-v4gdq 112m (0%) 122m (0%) 200Mi (0%) 220Mi (0%) 233d
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 487m (3%) 822m (5%)
memory 15856217600 (2%) 749976320 (3%)
ephemeral-storage 0 (0%) 0 (0%)Hier zien we alle pods die op een specifieke node draaien, evenals de bronnen die elke pod vraagt. En zo zien de logs van de scheduler eruit bij het starten van de pod cronjob-cron-events-1573793820-xt6q9 (deze informatie verschijnt in de log van de scheduler bij het instellen van level 10 logging in de opstartargumenten āv=10):
log
I1115 07:57:21.637791 1 scheduling_queue.go:908] Bezig met het plannen van pod nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.637804 1 scheduler.go:453] Poging om pod te plannen: nxs-stage/cronjob-cron-events-1573793820-xt6q9
I1115 07:57:21.638285 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s5 is toegestaan, Node draait slechts 16 van de 110 Pods.
I1115 07:57:21.638300 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s6 is toegestaan, Node draait slechts 20 van de 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s3 is toegestaan, Node draait slechts 20 van de 110 Pods.
I1115 07:57:21.638322 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s4 is toegestaan, Node draait slechts 17 van de 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s10 is toegestaan, Node draait slechts 16 van de 110 Pods.
I1115 07:57:21.638365 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s12 is toegestaan, Node draait slechts 9 van de 110 Pods.
I1115 07:57:21.638334 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s11 is toegestaan, Node draait slechts 11 van de 110 Pods.
I1115 07:57:21.638385 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s1 is toegestaan, Node draait slechts 19 van de 110 Pods.
I1115 07:57:21.638402 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s2 is toegestaan, Node draait slechts 21 van de 110 Pods.
I1115 07:57:21.638383 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s9 is toegestaan, Node draait slechts 16 van de 110 Pods.
I1115 07:57:21.638335 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s8 is toegestaan, Node draait slechts 18 van de 110 Pods.
I1115 07:57:21.638408 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s13 is toegestaan, Node draait slechts 8 van de 110 Pods.
I1115 07:57:21.638478 1 predicates.go:1369] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s10 is toegestaan, bestaande pods anti-affiniteitsvoorwaarden zijn vervuld.
I1115 07:57:21.638505 1 predicates.go:1369] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s8 is toegestaan, bestaande pods anti-affiniteitsvoorwaarden zijn vervuld.
I1115 07:57:21.638577 1 predicates.go:1369] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s9 is toegestaan, bestaande pods anti-affiniteitsvoorwaarden zijn vervuld.
I1115 07:57:21.638583 1 predicates.go:829] Plannen van Pod nxs-stage/cronjob-cron-events-1573793820-xt6q9 op Node nxs-k8s-s7 is toegestaan, Node draait slechts 25 van de 110 Pods.
I1115 07:57:21.638932 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: BalancedResourceAllocation, capaciteit 39900 millicores 66620178432 geheugenen bytes, totale aanvraag 2343 millicores 9640186880 geheugenen bytes, score 9
I1115 07:57:21.638946 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: LeastResourceAllocation, capaciteit 39900 millicores 66620178432 geheugenen bytes, totale aanvraag 2343 millicores 9640186880 geheugenen bytes, score 8
I1115 07:57:21.638961 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: BalancedResourceAllocation, capaciteit 39900 millicores 66620170240 geheugenen bytes, totale aanvraag 4107 millicores 11307422720 geheugenen bytes, score 9
I1115 07:57:21.638971 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: BalancedResourceAllocation, capaciteit 39900 millicores 66620178432 geheugenen bytes, totale aanvraag 5847 millicores 24333637120 geheugenen bytes, score 7
I1115 07:57:21.638975 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: LeastResourceAllocation, capaciteit 39900 millicores 66620170240 geheugenen bytes, totale aanvraag 4107 millicores 11307422720 geheugenen bytes, score 8
I1115 07:57:21.638990 1 resource_allocation.go:78] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: LeastResourceAllocation, capaciteit 39900 millicores 66620178432 geheugenen bytes, totale aanvraag 5847 millicores 24333637120 geheugenen bytes, score 7
I1115 07:57:21.639022 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: TaintTolerationPriority, Score: (10)
I1115 07:57:21.639030 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: TaintTolerationPriority, Score: (10)
I1115 07:57:21.639034 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: TaintTolerationPriority, Score: (10)
I1115 07:57:21.639041 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: NodeAffinityPriority, Score: (0)
I1115 07:57:21.639053 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: NodeAffinityPriority, Score: (0)
I1115 07:57:21.639059 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: NodeAffinityPriority, Score: (0)
I1115 07:57:21.639061 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: InterPodAffinityPriority, Score: (0)
I1115 07:57:21.639063 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639073 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: InterPodAffinityPriority, Score: (0)
I1115 07:57:21.639077 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639085 1 interpod_affinity.go:237] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: InterPodAffinityPriority, Score: (0)
I1115 07:57:21.639088 1 selector_spreading.go:146] cronjob-cron-events-1573793820-xt6q9 -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639103 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s10: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639109 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s8: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639114 1 generic_scheduler.go:726] cronjob-cron-events-1573793820-xt6q9_nxs-stage -> nxs-k8s-s9: SelectorSpreadPriority, Score: (10)
I1115 07:57:21.639127 1 generic_scheduler.go:781] Host nxs-k8s-s10 -> Score 100037
I1115 07:57:21.639150 1 generic_scheduler.go:781] Host nxs-k8s-s8 -> Score 100034
I1115 07:57:21.639154 1 generic_scheduler.go:781] Host nxs-k8s-s9 -> Score 100037
I1115 07:57:21.639267 1 scheduler_binder.go:269] AssumePodVolumes voor pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10"
I1115 07:57:21.639286 1 scheduler_binder.go:279] AssumePodVolumes voor pod "nxs-stage/cronjob-cron-events-1573793820-xt6q9", node "nxs-k8s-s10": alle PVC's gebonden en niets te doen
I1115 07:57:21.639333 1 factory.go:733] Poging om cronjob-cron-events-1573793820-xt6q9 te binden aan nxs-k8s-s10Hier zien we dat de scheduler aanvankelijk filtert en een lijst vormt van 3 knooppunten waarop de uitvoering mogelijk is (nxs-k8s-s8, nxs-k8s-s9, nxs-k8s-s10). Vervolgens wordt het aantal punten berekend op basis van verschillende parameters (waaronder BalancedResourceAllocation, LeastResourceAllocation) voor elk van deze knooppunten om de meest geschikte node te bepalen. Uiteindelijk wordt er gepland op de node met het hoogste puntenaantal (hier hebben twee nodes tegelijk 100037 punten, dus wordt er een willekeurige gekozen - nxs-k8s-s10).
Uitslag: als er pods op de node draaien waarvoor geen beperkingen zijn ingesteld, is dit voor k8s (qua resourcegebruik) equivalent aan de situatie waarin dergelijke pods helemaal niet op deze node aanwezig zijn. Daarom, als je bijvoorbeeld een pod hebt met een hongerig proces (bijvoorbeeld wowza) en voor deze pod geen beperkingen zijn ingesteld, kan het gebeuren dat deze pod feitelijk alle resources van de node verbruikt, terwijl de node voor k8s als niet belast wordt beschouwd en hetzelfde aantal punten krijgt bij de ranking (precies zoals de node zonder actieve pods), wat uiteindelijk kan leiden tot een ongelijke verdeling van de belasting tussen nodes.
Uitzetting van de pod
Zoals bekend - elke pod krijgt een van de 3 QoS-klassen toegewezen:
- gegarandeerd - wordt toegewezen wanneer voor elke container in de pod een request en limit voor geheugen en cpu is ingesteld, en deze waarden moeten identiek zijn
- burstable - ten minste ƩƩn container in de pod heeft een request en limit, waarbij request < limit is
- beste inspanning - wanneer geen enkele container in de pod beperkt is in resources
Wanneer er echter een tekort aan resources (schijf, geheugen) op de node wordt waargenomen, begint kubelet met het rangschikken en uitzetten van pods volgens een bepaald algoritme, dat rekening houdt met de prioriteit van de pod en zijn QoS-klasse. Bijvoorbeeld, als het om RAM gaat, worden op basis van de QoS-klasse punten toegewezen volgens het volgende principe:
- Gegarandeerd: -998
- Beste inspanning: 1000
- Burstable: min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
Dus bij gelijke prioriteit zal kubelet in de eerste plaats pods met de QoS-klasse beste inspanning van de node zetten.
Uitslag: als je de kans wilt verkleinen dat een belangrijke pod van de node wordt gezet bij een tekort aan resources, is het naast de prioriteit ook noodzakelijk om zorgen voor het instellen van request/limit voor deze pod.
Mechanisme voor horizontale automatische schaling van toepassing pods (HPA)
Wanneer de taak bestaat om automatisch het aantal pods te verhogen of verlagen op basis van resourcegebruik (systeem - CPU / RAM of gebruiker - rps), kan een K8s-entiteit zoals HPA (Horizontal Pod Autoscaler) helpen. Het algoritme is als volgt:
- De huidige waardes van de te monitoren resource (currentMetricValue) worden bepaald.
- De gewenste waardes voor de resource (desiredMetricValue) worden ingesteld, die voor systeemresources worden opgegeven via request.
- Het huidige aantal replicas (currentReplicas) wordt vastgesteld.
- Volgens de volgende formule wordt het gewenste aantal replicas (desiredReplicas) berekend.
desiredReplicas = [ currentReplicas * ( currentMetricValue / desiredMetricValue )]
Er zal echter geen schaalvergroting plaatsvinden wanneer de ratio (currentMetricValue / desiredMetricValue) dicht bij 1 ligt (de toelaatbare afwijking kunnen we zelf instellen, standaard is dit 0.1).
Laten we het functioneren van hpa bekijken aan de hand van een voorbeeldapplicatie app-test (beschreven als Deployment), waar het aantal replicas moet worden gewijzigd op basis van CPU-verbruik:
Manifest van de applicatie
kind: Deployment apiVersion: apps/v1beta2 metadata: name: app-test spec: selector: matchLabels: app: app-test replicas: 2 template: metadata: labels: app: app-test spec: containers: - name: nginx image: registry.nixys.ru/generic-images/nginx imagePullPolicy: Always resources: requests: cpu: 60m ports: - name: http containerPort: 80 - name: nginx-exporter image: nginx/nginx-prometheus-exporter resources: requests: cpu: 30m ports: - name: nginx-exporter containerPort: 9113 args: - -nginx.scrape-uri - http://127.0.0.1:80/nginx-statusDat wil zeggen, we zien dat de pod met de applicatie aanvankelijk in twee exemplaren draait, waarvan elk twee containers heeft: nginx en nginx-exporter, waarvoor is ingesteld requests voor CPU.
Manifest voor HPA
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: app-test-hpa spec: maxReplicas: 10 minReplicas: 2 scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: app-test metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 30Dat wil zeggen, we hebben een hpa gecreƫerd die toezicht houdt op de Deployment app-test en het aantal pods met de applicatie reguleert op basis van de CPU-metrics (we verwachten dat de pod 30% van de aangevraagde CPU gebruikt), terwijl het aantal replicas tussen 2-10 ligt.
Laten we nu het werkmechanisme van hpa bekijken als we belasting op een van de pods leggen:
# kubectl top pod NAME CPU(cores) MEMORY(bytes) app-test-78559f8f44-pgs58 101m 243Mi app-test-78559f8f44-cj4jz 4m 240Mi
In totaal hebben we het volgende:
- De gewenste waarde (desiredMetricValue) is volgens de hpa-instellingen gelijk aan 30%
- De huidige waarde (currentMetricValue) wordt berekend door de controller-manager de gemiddelde waarde van het resourceverbruik in % te berekenen, dat wil zeggen dat het ongeveer het volgende doet:
- Ontvangt absolute waarden van de pods-metrics van de metric-server, dat wil zeggen 101m en 4m
- Berechnet het gemiddelde absolute waarde, dat wil zeggen (101m + 4m) / 2 = 53m
- Ontvangt de absolute waarde voor het gewenste resourceverbruik (hiervoor worden de requests van alle containers bij elkaar opgeteld) 60m + 30m = 90m
- Berechnet het gemiddelde percentage CPU-verbruik ten opzichte van de pod-request, dat wil zeggen 53m / 90m * 100% = 59%
Nu hebben we alles wat we nodig hebben om te bepalen of het aantal replicas moet worden gewijzigd. We berekenen de ratio:
ratio = 59% / 30% = 1.96
Dat wil zeggen, het aantal replicas moet met ~2 keer verhoogd worden en bedraagt [2 * 1.96] = 4.
Uitvoer: Zoals opgemerkt, is een noodzakelijke voorwaarde voor de werking van dit mechanisme ook de aanwezigheid van requests voor alle containers in de geobserveerde pod.
Mechanisme voor horizontale autoscaling van nodes (Cluster Autoscaler)
Om de negatieve impact op het systeem bij pieken in de belasting te verminderen, is het inregelen van hpa soms niet voldoende. Bijvoorbeeld, volgens de instellingen in hpa beslist de controller-manager dat het aantal replicas met 2 keer moet worden verhoogd, maar er zijn geen vrije resources op de nodes om zo veel pods te starten (dat wil zeggen dat de node de gevraagde resources van de pod niet kan leveren) en deze pods gaan in de status Pending.
In dit geval, als de provider de overeenkomstige IaaS/PaaS heeft (bijvoorbeeld GKE/GCE, AKS, EKS, enz.), kan een hulpmiddel zoals Node Autoscalerons helpen. Het stelt in staat om het maximale en minimale aantal nodes in de cluster in te stellen en automatisch het huidige aantal nodes te reguleren (door het API van de cloudprovider aan teroepen om een node te bestellen/verwijderen) wanneer er een tekort aan resources in de cluster is en pods niet kunnen worden gepland (in de status Pending zijn).
Uitvoer: Voor de mogelijkheid van autoscaling van nodes moeten requests in de container pods worden gedefinieerd, zodat k8s correct de belasting op de nodes kan inschatten en overeenkomstig kan melden dat er onvoldoende resources in de cluster zijn om de volgende pod te starten.
Conclusie
Het is belangrijk op te merken dat het instellen van resourcebeperkingen voor de container geen vereiste is voor het succesvol draaien van een applicatie, maar het is toch beter om dit te doen om de volgende redenen:
- Voor nauwkeurigere werking van de scheduler bij het balanceren van de belasting tussen k8s-nodes
- Om de kans op een 'pod eviction'-evenement te verkleinen
- Voor de werking van de horizontale autoscaling van applicatiepods (HPA)
- Voor de werking van de horizontale autoscaling van nodes (Cluster Autoscaling) bij cloudproviders
Lees ook andere artikelen op onze blog:
Bron: habr.com
