Metodtips för avancerade scheduler-funktioner i Azure Kubernetes Service (AKS) med kube-scheduler

Bästa praxis för AKS avancerade schemaläggningsfunktioner omfattar att använda taints och toleranser för att reservera noder, nodselektorer och nodtillhörighet för att styra placeringen av poddar samt tillhörighet och anti-tillhörighet mellan poddar för att hantera fördelningen av arbetsbelastningar i klustret. När du hanterar kluster i Azure Kubernetes Service (AKS) måste du ofta isolera team och arbetsbelastningar. Med avancerade funktioner som tillhandahålls av Kubernetes-schemaläggaren kan du styra:

  • Vilka poddar kan schemaläggas på bestämda noder.
  • Hur program med flera poddar kan distribueras korrekt i klustret.

Den här artikeln om metodtips fokuserar på avancerade Kubernetes-schemaläggningsfunktioner för klusteroperatorer. I den här artikeln kan du se hur du:

  • Använd taints och toleranser för att begränsa vilka poddar som kan schemaläggas på noder.
  • Ge poddar företräde att köra på vissa noder med nodväljare eller nodtillhörighet.
  • Dela upp eller gruppera pods med affinitet mellan poddar eller anti-affinitet.
  • Begränsa schemaläggning av arbetsbelastningar som endast kräver GPU:er på noder med schemabara GPU:er.

Om ytterligare funktioner eller ML-ramverk behövs för att schemalägga och köa batcharbetsbelastningar kan du installera och konfigurera Kueue på AKS för att säkerställa effektiv, principdriven schemaläggning i AKS-kluster.

Om detaljerad schemaläggningskonfiguration krävs för att optimera hur poddar och jobb prioriterar specifika noder, lagringsresurser, topologi med mera, kan du konfigurera en schemaläggare på AKS.

Jämförelse av schemaläggningsfunktioner

Feature Användningsfall Schemaläggningsbeteende När du ska välja
Störningar och toleranser Dedikera noder för specifika arbetsbelastningar (t.ex. GPU-noder) Hård begränsning: poddar utan matchande tolerans kan inte schemaläggas på fördärvade noder När du behöver strikt nodisolering och vill förhindra obehöriga arbetsbelastningar
Nodväljare Enkel etikettstyrd placering av poddar Mjuk begränsning: poddar måste ha matchande etiketter, men omärkta poddar kan fortfarande schemaläggas på etiketterade noder När du behöver grundläggande schemaläggningskontroll med enkel etikettmatchning
Nodtillhörighet Flexibel nodinriktning med reservalternativ Konfigurerbar: stöder både obligatoriska (hårda) och önskade (mjuka) matchningsregler När du behöver avancerade uttryck eller vill schemalägga inställningar med reservbeteende
Pod-till-pod-affinitet/anti-affinitet Samplacerar eller separerar poddar baserat på befintlig poddplacering Styr podddistribution i förhållande till andra poddar på noder När relationer mellan poddar spelar roll (t.ex. att samlokalisera app och cache eller sprida repliker)

Vad är taints och tolerations?

Taints och tolerations är en Kubernetes-mekanism som gör att noder kan stöta bort poddar, såvida inte dessa poddar uttryckligen tolererar nodens taint, vilket ger strikt isolering för dedikerade arbetsbelastningar.

Bästa praxis: Använda taints och toleranser för att dedikera GPU-noder Begränsa åtkomsten för resursintensiva program, till exempel ingresskontrollanter, till specifika noder. Behåll nodresurser tillgängliga för arbetsbelastningar som kräver dem och tillåt inte schemaläggning av andra arbetsbelastningar på noderna.

När du skapar ditt AKS-kluster kan du distribuera noder med GPU-stöd eller ett stort antal kraftfulla processorer. Mer information finns i Använda GPU:er på AKS. Du kan använda dessa noder för stora databearbetningsarbetsbelastningar som maskininlärning (ML) eller artificiell intelligens (AI).

Eftersom den här nodresursmaskinvaran vanligtvis är dyr att distribuera begränsar du de arbetsbelastningar som kan schemaläggas på dessa noder. Ägna i stället vissa noder i klustret åt att köra inkommande tjänster och förhindra andra arbetsbelastningar.

Det här stödet för olika noder tillhandahålls med hjälp av flera nodpooler. Ett AKS-kluster stöder en eller flera nodpooler.

Kubernetes-schemaläggaren använder taints och tolerations för att begränsa vilka arbetsbelastningar som kan köras på noder.

  • Använd en taint på en nod för att ange att endast specifika poddar kan schemaläggas på dem.
  • Applicera sedan en tolerans på en podd så att den kan tolerera en nods taint.

När du distribuerar en podd till ett AKS-kluster schemalägger Kubernetes endast poddar på noder vars taint överensstämmer med toleransen. Taints och toleranser fungerar tillsammans för att säkerställa att poddar inte schemaläggs till olämpliga noder. En eller flera toleranser tillämpas på en nod, vilket markerar noden så att den inte accepterar några poddar som inte tolererar dessa toleranser.

Hur implementerar jag taints och toleranser i AKS?

Anta till exempel att du har lagt till en nodpool i AKS-klustret för noder med GPU-stöd. Du definierar namn, till exempel gpu, och sedan ett värde för schemaläggning. Om det här värdet anges till NoSchedule begränsas Kubernetes-schemaläggaren från att schemalägga poddar med odefinierad tolerans på noden.

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name taintnp \
    --node-taints sku=gpu:NoSchedule \
    --no-wait

Med en taint applicerad på noder i nodpoolen definierar du en tolerering i poddspecifikationen som möjliggör schemaläggning på dessa noder. I följande exempel definieras sku: gpu och effect: NoSchedule för att tolerera den taint som tillämpades på nodpoolen i föregående steg:

kind: Pod
apiVersion: v1
metadata:
  name: app
spec:
  containers:
  - name: app
    image: <your-workload>:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  tolerations:
  - key: "sku"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

När denna pod distribueras med kubectl apply -f gpu-toleration.yaml, kan Kubernetes framgångsrikt schemalägga podden på noderna med den tillämpade tainten. Med den här logiska isoleringen kan du styra åtkomsten till resurser i ett kluster.

Dedikera nodpooler till flera program

Om du vill dedikera separata noder till olika program skapar du en nodpool för varje program med en unik taint och matchande etikett. Tainten förhindrar att andra poddar schemaläggs på nodpoolen, medan etiketten gör att du kan kräva att en applikation endast körs på sin dedikerade nodpool.

I följande exempel skapas separata nodpooler för klientdels- och serverdelsprogram:

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name frontpool \
    --node-count 1 \
    --labels workload=frontend \
    --node-taints workload=frontend:NoSchedule

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name backpool \
    --node-count 1 \
    --labels workload=backend \
    --node-taints workload=backend:NoSchedule

Skapa en fil med namnet dedicated-apps.yaml och lägg till följande podddefinitioner. Varje podd har en tolerans som matchar nodpoolens taint och en nodeSelector som kräver motsvarande nodpooletikett:

apiVersion: v1
kind: Pod
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  nodeSelector:
    workload: frontend
  tolerations:
  - key: "workload"
    operator: "Equal"
    value: "frontend"
    effect: "NoSchedule"
  containers:
  - name: frontend
    image: mcr.microsoft.com/oss/nginx/nginx:1.25.5
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi
---
apiVersion: v1
kind: Pod
metadata:
  name: backend
  labels:
    app: backend
spec:
  nodeSelector:
    workload: backend
  tolerations:
  - key: "workload"
    operator: "Equal"
    value: "backend"
    effect: "NoSchedule"
  containers:
  - name: backend
    image: mcr.microsoft.com/oss/nginx/nginx:1.25.5
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 250m
        memory: 256Mi

Använd manifestet:

kubectl apply -f dedicated-apps.yaml

Kontrollera att varje podd körs på en nod med den förväntade arbetsbelastningsetiketten:

kubectl get pods -o wide
kubectl get nodes -L workload

frontend-podden är schemalagd på en nod med etiketten workload=frontend, och backend-podden är schemalagd på en nod med etiketten workload=backend. Enbart en tolerans gör att en podd kan använda en fläckad nod men kräver inte placering på den noden. nodeSelector uppfyller det kravet.

Ta bort exempelresurserna när du inte längre behöver dem:

kubectl delete -f dedicated-apps.yaml

az aks nodepool delete \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name frontpool

az aks nodepool delete \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name backpool

När du använder taints kan du samarbeta med programutvecklare och ägare så att de kan definiera nödvändiga toleranser i sina distributioner.

Mer information om hur du använder flera nodpooler i AKS finns i Skapa flera nodpooler för ett kluster i AKS.

Funktion för taints och toleranser i AKS

När du uppgraderar en nodpool i AKS följer taints och toleranser ett angivet mönster när de tillämpas på nya noder:

Standardkluster som använder Skalningsuppsättningar för virtuella Azure-datorer

Du kan märka en nodpool från AKS-API:et så att nyligen utskalade noder får nodtaints som specificeras av API:et.

Vi antar att:

  1. Du börjar med ett kluster med två noder: node1 och node2.
  2. Du uppgraderar nodpoolen.
  3. Två andra noder skapas: node3 och node4.
  4. Tainterna skickas vidare var för sig.
  5. Den ursprungliga node1 och node2 tas bort.

Kluster utan stöd för VM-skalningsuppsättningar

Låt oss återigen anta:

  1. Du har ett kluster med två noder: node1 och node2.
  2. Du uppgraderar nodpoolen.
  3. En extra nod skapas: node3.
  4. Tainterna från node1 tillämpas på node3.
  5. node1 tas bort.
  6. En ny nod1 skapas för att ersätta den ursprungliga noden1.
  7. Nod2-tainterna tillämpas på den nya noden1.
  8. node2 tas bort.

I huvudsak blir node1node3, och node2 blir den nya node1.

När du skalar en nodpool i AKS överförs inte taint och toleranser avsiktligt.

Vad är nodväljare och nodtillhörighet?

Nodväljare och nodtillhörighet är Kubernetes-funktioner som gör att poddar kan ange inställningar för vilka noder de ska köras på, baserat på nodetiketter.

Bästa praxis: Använd nodväljare och tillhörighet för att styra poddplacering efter maskinvarutyp Kontrollera schemaläggningen av poddar på noder med hjälp av nodväljare, nodtillhörighet eller tillhörighet mellan poddar. Med de här inställningarna kan Kubernetes-schemaläggaren logiskt isolera arbetsbelastningar, till exempel efter maskinvara i noden.

Taints och toleranser isolerar logiskt resurser med en hård brytpunkt. Om podden inte tolererar en nodens taint, schemaläggs den inte på noden.

Du kan också använda nodväljare. Du kan till exempel märka noder för att ange lokalt ansluten SSD-lagring eller en stor mängd minne och sedan definiera en nodväljare i poddspecifikationen. Kubernetes schemalägger poddarna på en matchande nod.

Till skillnad från toleranser kan poddar utan matchande nodväljare fortfarande schemaläggas på etiketterade noder. Det här beteendet gör att oanvända resurser på noderna kan användas, men prioriterar poddar som definierar den matchande nodväljaren.

Nu ska vi titta på ett exempel på noder med hög mängd minne. Dessa noder prioriterar poddar som begär en hög mängd minne. För att säkerställa att resurserna inte är inaktiva tillåter de också andra poddar att köra. Följande exempelkommando lägger till en nodpool med etiketten hardware=highmem till myAKSCluster i myResourceGroup. Alla noder i nodpoolen har den här etiketten.

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name labelnp \
    --node-count 1 \
    --labels hardware=highmem \
    --no-wait

En poddspecifikation lägger nodeSelector sedan till egenskapen för att definiera en nodväljare som matchar etiketten som angetts på en nod:

kind: Pod
apiVersion: v1
metadata:
  name: app
spec:
  containers:
  - name: app
    image: <your-workload>:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  nodeSelector:
      hardware: highmem

När du använder dessa alternativ för schemaläggaren kan du samarbeta med programutvecklare och ägare så att de kan definiera sina poddspecifikationer korrekt.

Mer information om hur du använder nodväljare finns i Tilldela poddar till noder.

Vad är nodaffinitet?

En nodväljare är en grundläggande lösning för att tilldela poddar till en viss nod. Nodtillhörighet ger större flexibilitet så att du kan definiera vad som händer om podden inte kan matchas med en nod. Du kan:

  • Kräv att Kubernetes-schemaläggaren matchar en podd med en märkt värd. Eller:
  • Föredrar en matchning men tillåter att podden schemaläggs på en annan värd om ingen matchning är tillgänglig.

I följande exempel anges nodtillhörigheten till requiredDuringSchedulingIgnoredDuringExecution. Den här tillhörigheten kräver att Kubernetes-schemaläggaren använder en nod med en matchande etikett. Om ingen nod är tillgänglig måste podden vänta tills schemaläggningen fortsätter. Om du vill tillåta att podden schemaläggs på en annan nod kan du i stället ange värdet till preferredDuringSchedulingIgnoreDuringExecution:

kind: Pod
apiVersion: v1
metadata:
  name: app
spec:
  containers:
  - name: app
    image: <your-workload>:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: hardware
            operator: In
            values:
            - highmem

Delen IgnoredDuringExecution i inställningen anger att podden inte ska tas bort från noden om nodetiketterna ändras. Kubernetes-schemaläggaren använder endast de uppdaterade nodetiketterna för nya poddar som schemaläggs, inte poddar som redan schemalagts på noderna.

Mer information finns i Tillhörighet och antitillhörighet.

Vad är affinitet och anti-affinitet mellan poddar?

En sista metod för Kubernetes-schemaläggaren att logiskt isolera arbetsbelastningar är att använda samhörighet eller anti-samhörighet mellan poddar. De här inställningarna definierar att poddar antingen inte ska eller ska schemaläggas på en nod som har en befintlig matchande podd. Som standard försöker Kubernetes-schemaläggaren schemalägga flera poddar i en replikuppsättning mellan noder. Du kan definiera mer specifika regler kring det här beteendet.

Du har till exempel ett webbprogram som också använder en Azure Managed Redis-resurs.

  • Du använder regler för pod-anti-affinitet för att begära att Kubernetes-schemaläggaren fördelar repliker över noder.
  • Du använder tillhörighetsregler för att se till att varje webbappkomponent schemaläggs på samma värd som en motsvarande cache.

Fördelningen av poddar mellan noder ser ut som i följande exempel:

Nod 1 Nod 2 Nod 3
webapp-1 webapp-2 webapp-3
cache-1 cache-2 cache-3

Tillhörighet mellan poddar och antitillhörighet ger en mer komplex distribution än nodväljare eller nodtillhörighet. Med distributionen isolerar du resurser logiskt och styr hur Kubernetes schemalägger poddar på noder.

Ett fullständigt exempel på det här webbprogrammet med Azure Managed Redis finns i Hitta poddar på samma nod.

Nästa steg

Den här artikeln fokuserar på avancerade Funktioner för Kubernetes Scheduler. Mer information om klusteråtgärder i AKS finns i följande metodtips: