Najlepsze rozwiązania dotyczące zaawansowanych funkcji harmonogramu w usłudze Azure Kubernetes Service (AKS) przy użyciu narzędzia kube-scheduler

Najlepsze praktyki dotyczące zaawansowanych funkcji planisty w AKS obejmują używanie taintów i tolerancji do wydzielania węzłów, selektorów węzłów i afiniczności węzłów do kontrolowania rozmieszczenia podów oraz afiniczności i antyafiniczności między podami do zarządzania rozkładem obciążeń w całym klastrze. Podczas zarządzania klastrami w usłudze Azure Kubernetes Service (AKS) często trzeba odizolować zespoły i obciążenia. Zaawansowane funkcje udostępniane przez harmonogram kubernetes umożliwiają sterowanie:

  • Które zasobniki można zaplanować na niektórych węzłach.
  • Sposób, w jaki aplikacje z wieloma zasobnikami mogą być odpowiednio rozmieszczane w klastrze.

Ten artykuł dotyczący najlepszych rozwiązań koncentruje się na zaawansowanych funkcjach planowania platformy Kubernetes dla operatorów klastra. W tym artykule omówiono sposób wykonywania następujących zadań:

  • Użyj skażeń i tolerancji, aby ograniczyć, które zasobniki mogą być planowane na węzłach.
  • Preferowanie uruchamiania zasobników na określonych węzłach przy użyciu selektorów węzłów lub preferencji węzłów.
  • Podziel zasobniki lub grupuj razem z koligacją między zasobnikami lub anty-koligacją.
  • Ogranicz planowanie obciążeń, które wymagają procesorów GPU tylko w węzłach z schedulowalnymi procesorami GPU.

Jeśli do planowania i kolejek obciążeń wsadowych potrzebne są dodatkowe możliwości lub frameworky uczenia maszynowego, można zainstalować i skonfigurować Kueue na AKS, aby zapewnić wydajne planowanie oparte na zasadach w klastrach AKS.

Jeśli potrzebna jest dokładna konfiguracja harmonogramu, aby zoptymalizować priorytetyzację podów i zadań względem określonych węzłów, zasobów pamięci, topologii i innych czynników, można skonfigurować harmonogram w usłudze AKS.

Porównanie funkcji planowania

Feature Przypadek użycia Zachowanie planowania Kiedy wybrać
Skażenia i tolerancje Przypisz węzły do określonych obciążeń (np. węzły GPU) Twarde ograniczenie: zasobniki bez dopasowania tolerancji nie mogą być zaplanowane na skażonych węzłach Gdy potrzebujesz ścisłej izolacji węzłów i chcesz zapobiec nieautoryzowanym obciążeniom
Selektory węzłów Proste rozmieszczanie podów na podstawie etykiet Ograniczenie miękkie: zasobniki wymagają pasujących etykiet, ale zasobniki bez etykiet nadal mogą być zaplanowane na węzłach oznaczonych etykietami Gdy potrzebujesz podstawowej kontrolki planowania z prostym dopasowaniem etykiet
Koligacja węzła Elastyczne określanie wartości docelowej węzła z opcjami rezerwowymi Konfigurowalne: obsługuje zarówno wymagane (twarde) i preferowane (miękkie) reguły dopasowywania Gdy potrzebujesz zaawansowanych wyrażeń lub chcesz określić preferencje planowania z mechanizmem awaryjnym
Kolokacja/antykolokacja między podami Umieszczaj razem lub rozdzielaj zasobniki na podstawie istniejącego rozmieszczenia zasobników Określa dystrybucję zasobników względem innych zasobników na węzłach Gdy relacje między podami mają znaczenie (np. umieszczanie aplikacji i pamięci podręcznej razem lub rozmieszczanie replik)

Czym są skażenia i tolerancje?

Defekty i tolerancje to mechanizm Kubernetes, który umożliwia węzłom odpychanie zasobników, chyba że te zasobniki jawnie tolerowają defekt węzła, zapewniając twardą izolację dla dedykowanych obciążeń.

Najlepsze rozwiązanie: używanie defektów i tolerancji do dedykowania węzłów procesora GPU Ogranicz dostęp do aplikacji intensywnie korzystających z zasobów, takich jak kontrolery ruchu przychodzącego, do określonych węzłów. Zachowaj dostępne zasoby węzłów dla obciążeń, które ich wymagają, i nie zezwalaj na planowanie innych obciążeń w węzłach.

Podczas tworzenia klastra usługi AKS można wdrażać węzły z obsługą GPU lub dużą liczbą wydajnych CPU. Aby uzyskać więcej informacji, zobacz Używanie procesorów GPU w usłudze AKS. Tych węzłów można używać do obsługi dużych obciążeń przetwarzania danych, takich jak uczenie maszynowe (ML) lub sztuczna inteligencja (AI).

Ponieważ ten sprzęt zasobów węzła jest zwykle kosztowny do wdrożenia, ogranicz obciążenia, które można zaplanować w tych węzłach. Zamiast tego, dedykuj niektóre węzły w klastrze do uruchamiania usług wejściowych i uniemożliwiania realizacji innych zadań.

Ta obsługa różnych węzłów jest zapewniana przy użyciu wielu pul węzłów. Klaster usługi AKS obsługuje co najmniej jedną pulę węzłów.

Harmonogram platformy Kubernetes używa plam i tolerancji, aby ograniczyć obciążenia, które mogą być uruchamiane na węzłach.

  • Zastosuj skazę do węzła, aby wskazać, że na nim można zaplanować tylko określone zasobniki.
  • Następnie zastosuj tolerancję do poda, co pozwoli mu tolerować skażenie węzła.

Podczas wdrażania zasobnika w klastrze usługi AKS platforma Kubernetes planuje tylko zasobniki w węzłach, których defekt jest zgodny z tolerancją. Tainty i tolerancje współpracują ze sobą, aby zapewnić, że zasobniki nie są przypisywane do nieodpowiednich węzłów. Co najmniej jedno skażenie jest stosowane do węzła, oznaczając go w ten sposób, że nie akceptuje żadnych podów, które nie tolerują skażeń.

Jak zaimplementować defekty i tolerancje w usłudze AKS?

Załóżmy na przykład, że dodałeś pulę węzłów w klastrze usługi AKS dla węzłów z obsługą GPU. Należy zdefiniować nazwę, taką jak gpu, a następnie wartość planowania. Ustawienie tej wartości na NoSchedule ogranicza harmonogram Kubernetes, uniemożliwiając przydzielanie podów z niezdefiniowaną tolerancją na węźle.

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

Po zastosowaniu zakazu do węzłów w puli węzłów, należy zdefiniować tolerancję w specyfikacji poda, która umożliwia harmonogramowanie na węzłach. W poniższym przykładzie zdefiniowano elementy sku: gpu i effect: NoSchedule w celu tolerowania defektu zastosowanego do puli węzłów w poprzednim kroku:

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"

Po wdrożeniu tego zasobnika przy użyciu narzędzia kubectl apply -f gpu-toleration.yamlplatforma Kubernetes może pomyślnie zaplanować zasobnik w węzłach z zastosowanym defektem. Ta izolacja logiczna umożliwia kontrolowanie dostępu do zasobów w klastrze.

Przypisz pule węzłów do wielu aplikacji

Aby przypisać osobne węzły do różnych aplikacji, utwórz pulę węzłów dla każdej aplikacji z unikalnym skażeniem i odpowiadającą mu etykietą. Skażenie uniemożliwia przypisywanie innych zasobników do puli węzłów, a etykieta pozwala określić, że aplikacja ma być uruchamiana wyłącznie w dedykowanej puli węzłów.

Poniższy przykład tworzy oddzielne pule węzłów dla aplikacji frontendowych i backendowych:

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

Utwórz plik o nazwie dedicated-apps.yaml i dodaj następujące definicje podów. Każdy zasobnik ma tolerancję zgodną ze skażeniem swojej puli węzłów oraz nodeSelector, które wymaga odpowiedniej etykiety puli węzłów:

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

Zastosuj manifest:

kubectl apply -f dedicated-apps.yaml

Sprawdź, czy każdy zasobnik jest uruchomiony w węźle z oczekiwaną etykietą obciążenia:

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

Pod frontend jest zaplanowany na węźle oznaczonym etykietą workload=frontend, a pod backend jest zaplanowany na węźle oznaczonym etykietą workload=backend. Tolerancja pozwala zasobnikowi używać skażonego węzła, ale nie wymaga umieszczania w tym węźle. nodeSelector zapewnia to wymaganie.

Usuń przykładowe zasoby, gdy nie są już potrzebne:

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

Kiedy zastosujesz skażenia, współpracuj z deweloperami aplikacji i właścicielami, aby umożliwić im zdefiniowanie wymaganych tolerancji we wdrożeniach.

Aby uzyskać więcej informacji na temat używania wielu pul węzłów w usłudze AKS, zobacz Tworzenie wielu pul węzłów dla klastra w usłudze AKS.

Zachowanie defektów i tolerancji w usłudze AKS

Podczas uaktualniania puli węzłów w usłudze AKS anomalie i tolerancje są zgodne z ustalonym wzorcem, ponieważ są one stosowane do nowych węzłów.

Domyślne klastry korzystające z zestawów skalowania maszyn wirtualnych platformy Azure

Można przypisać zanieczyszczenia nodów dla puli węzłów z interfejsu API usługi AKS, aby nowo skalowane węzły otrzymywały zdefiniowane przez interfejs API zanieczyszczenia nodów.

Załóżmy:

  1. Zaczynasz od klastra z dwoma węzłami: node1 i node2.
  2. Uaktualniasz pulę węzłów.
  3. Tworzone są dwa inne węzły: node3 i node4.
  4. Te skazy są przekazywane odpowiednio.
  5. Oryginalny węzeł1 i węzeł2 zostaną usunięte.

Klastry bez wsparcia dla zestawów skalowania maszyn wirtualnych

Ponownie załóżmy, że:

  1. Masz klaster z dwoma węzłami: node1 i node2.
  2. Uaktualniasz pulę węzłów.
  3. Zostanie utworzony dodatkowy węzeł: node3.
  4. Defekty z węzła Node1 są stosowane do węzła3.
  5. Węzeł1 jest usuwany.
  6. Zostanie utworzony nowy węzeł1 w celu zastąpienia oryginalnego węzła1.
  7. Węzły2są stosowane do nowego węzła1.
  8. Węzeł2 jest usuwany.

W istocie węzeł Node1 staje się węzłem3, a węzeł2 staje się nowym węzłem1.

Kiedy skalujesz pulę węzłów w usłudze AKS, taints i tolerances nie są przenoszone zgodnie z założeniami projektowymi.

Co to są selektory węzłów i koligacja węzłów?

Selektory węzłów i afinity węzłów to funkcje Kubernetes, które umożliwiają podom określanie preferencji dotyczących tego, na których węzłach powinny być uruchamiane, na podstawie etykiet węzłów.

Dobra praktyka: używaj selektorów węzłów i afinity do sterowania rozmieszczaniem zasobników według typu sprzętu Steruj planowaniem zasobników na węzłach za pomocą selektorów węzłów, afinity węzłów lub afinity między zasobnikami. Te ustawienia umożliwiają harmonogramowi Kubernetes logiczne izolowanie obciążeń, na przykład poprzez wykorzystanie zasobów sprzętowych w węźle.

Taints i tolerancje logicznie izolują zasoby z twardym odcięciem. Jeśli zasobnik nie toleruje defektu węzła, nie jest on zaplanowany w węźle.

Alternatywnie można użyć selektorów węzłów. Na przykład nadajesz etykiety węzłom, aby wskazać lokalnie dołączoną pamięć SSD lub dużą ilość pamięci, a następnie definiujesz selektor węzła w specyfikacji podu. Platforma Kubernetes planuje te pody na pasującym węźle.

W odróżnieniu od tolerancji, zasobniki bez odpowiadającego selektora węzłów mogą być nadal przypisywane do węzłów oznaczonych etykietami. To zachowanie umożliwia wykorzystanie nieużywanych zasobów w węzłach, ale priorytetyzuje zasobniki definiujące pasujący selektor węzła.

Przyjrzyjmy się przykładowi węzłów o dużej ilości pamięci. Te węzły ustalają priorytety zasobników, które żądają dużej ilości pamięci. Aby upewnić się, że zasoby nie są bezczynne, umożliwiają również uruchamianie innych podów. Poniższe przykładowe polecenie dodaje pulę węzłów z etykietą hardware=highmem do myAKSCluster w myResourceGroup. Wszystkie węzły w tej puli węzłów mają tę etykietę.

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

Następnie specyfikacja modułu dodaje właściwość nodeSelector, aby określić selektor węzła zgodny z etykietą ustawioną na węźle:

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

Korzystając z tych opcji harmonogramu, współpracuj z deweloperami aplikacji i ich właścicielami, aby umożliwić im poprawne zdefiniowanie specyfikacji podu.

Aby uzyskać więcej informacji na temat używania selektorów węzłów, zobacz Przypisywanie zasobników do węzłów.

Co to jest koligacja węzłów?

Selektor węzłów to podstawowe rozwiązanie do przypisywania zasobników do danego węzła. Powiązanie węzła zapewnia większą elastyczność, umożliwiając określenie, co się stanie, jeśli pod nie może być skojarzony z węzłem. Masz następujące możliwości:

  • Wymagaj, aby harmonogram Kubernetes dopasowywał zasobnik z hostem oznaczonym etykietą. Lub:
  • Preferuj dopasowanie, ale zezwalaj na zaplanowanie zasobnika na innym hoście, jeśli dopasowanie nie jest dostępne.

W poniższym przykładzie ustawiono powiązanie węzła na requiredDuringSchedulingIgnoredDuringExecution. Ta koligacja wymaga, aby harmonogram Kubernetes używał węzła z pasującą etykietą. Jeśli węzeł nie jest dostępny, zasobnik musi czekać na kontynuowanie planowania. Aby umożliwić zaplanowanie zasobnika na innym węźle, możesz zamiast tego ustawić wartość 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

Część IgnoredDuringExecution ustawienia wskazuje, że zasobnik nie powinien być eksmitowany z węzła w przypadku zmiany etykiet węzła. Harmonogram platformy Kubernetes używa tylko zaktualizowanych etykiet węzłów dla zaplanowanych nowych zasobników, a nie zasobników zaplanowanych już w węzłach.

Aby uzyskać więcej informacji, zobacz Koligacja i antykoligacja.

Czym jest afiniczność i antyafiniczność między podami?

Jednym z ostatecznych podejść do harmonogramu Kubernetes w celu logicznego izolowania obciążeń jest użycie koligacji między zasobnikami lub koligacji anty-pod. Te ustawienia definiują, że zasobniki nie powinny być zaplanowane lub powinny być zaplanowane na węźle, który ma istniejący pasujący zasobnik. Domyślnie harmonogram Kubernetes próbuje rozmieścić wiele zasobników w ReplicaSet na węzłach. Można zdefiniować bardziej szczegółowe reguły dotyczące tego zachowania.

Na przykład masz aplikację internetową, która używa również zasobu Azure Managed Redis.

  • Reguły anty-koligacji zasobników umożliwiają żądanie, aby harmonogram Kubernetes rozmieszczał repliki między węzłami.
  • Używasz reguł koligacji, aby zapewnić, że każdy składnik aplikacji internetowej jest zaplanowany na tym samym hoście, co odpowiednia pamięć podręczna.

Rozkład podów między węzłami wygląda jak w poniższym przykładzie:

Węzeł 1 Węzeł 2 Węzeł 3
webapp-1 aplikacja-webowa-2 webapp-3
cache-1 cache-2 cache-3

Koligacja między zasobnikami i koligacja przeciw koligacji zapewniają bardziej złożone wdrożenie niż selektory węzłów lub koligację węzłów. Wdrożenie pozwala logicznie izolować zasoby i kontrolować sposób planowania zasobników na węzłach przez platformę Kubernetes.

Pełny przykład tej aplikacji internetowej z usługą Azure Managed Redis znajduje się w temacie Lokalizowanie zasobników w tym samym węźle.

Następne kroki

Ten artykuł koncentruje się na zaawansowanych funkcjach harmonogramu Kubernetes. Aby uzyskać więcej informacji na temat operacji klastra w usłudze AKS, zapoznaj się z poniższymi najlepszymi praktykami: