Node Pools в AKS

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет, Хабр!

В Kubernetes кластер состоит из множества узлов (nodes), которые представляют собой виртуальные или физические машины, на которых запущены приложения. Node Pools — это группы узлов с одинаковой конфигурацией, управляемые как единое целое.

С Node Pools можно иметь разные пулы для разных задач или приложений, оптимизировать стоимость, используя различные типы виртуальных машин, и применять разные ОС в рамках одного кластера.

Azure Kubernetes Service (AKS) — это управляемый сервис Kubernetes от Microsoft, предназначенный для упрощения развертывания, управления и масштабирования приложений на базе контейнеров. AKS автоматически управляет хостовыми инфраструктурами, снимая бремя настройки и мониторинга, позволяя сосредоточиться на разработке приложений.

Node Poole

Для работы с AKS можно юзать Azure CLI войдя в систему через команду az login.

Начнем с его создания кластера AKS. Юзаем следующую команду:

az aks create --resource-group myResourceGroup --name myAKSCluster --node-count 1 --enable-addons monitoring --generate-ssh-keys --location eastus

Здесь создали кластер AKS с именем myAKSCluster в ресурсной группе myResourceGroup с одним узлом. Мониторинг включен, ключи SSH генерируются автоматически, и кластер размещается в регионе eastus.

Для добавления нового Node Pool есть команда:

az aks nodepool add --resource-group myResourceGroup --cluster-name myAKSCluster --name myNodePool --node-count 3

Команда добавляет новый Node Pool с именем myNodePool в кластер myAKSCluster, который находится в ресурсной группе myResourceGroup. В этом Node Pool будет 3 узла.

Можно настроить Node Pool, указав дополнительные параметры, такие как размер виртуальной машины и тип диска. Например:

az aks nodepool add --resource-group myResourceGroup --cluster-name myAKSCluster --name myCustomNodePool --node-count 2 --vm-size Standard_DS2_v2 --os-type Linux

Добавляем Node Pool с именем myCustomNodePool в кластер myAKSCluster, который находится в ресурсной группе myResourceGroup. В этом Node Pool будет 2 узла, каждый из которых использует виртуальную машину размера Standard_DS2_v2 с ос линукс.

Azure Portal предоставляет графический интерфейс для управления ресурсами Azure:

Входим в Azure Portal. На панели навигации выбираем "Kubernetes services" и переходим к кластеру AKS.

Добавление Node Pool выглядит довольно просто:

  1. В меню кластера AKS выбираем Node pools.

  2. Нажимаем кнопку + Add node pool.

  3. В форме добавления Node Pool вводим имя, выбераем размер виртуальной машины, количество узлов и другие параметры

  4. После настройки параметров нажимаем Add для создания Node Pool.

После добавления Node Pool можно мониторить его состояние и управлять им через раздел Node pools вашего кластера AKS в Azure Portal. Здесь можно редактировать количество узлов, размер виртуальных машин и другие параметры.

Удалить узлы можно, уменьшив количество узлов в Node Pool с помощью Azure CLI или удалить весь Node Pool, если он больше не нужен:

Можно использовать команду az aks nodepool scale, указав меньшее количество узлов:

az aks nodepool scale --resource-group myResourceGroup --cluster-name myAKSCluster --name myNodePool --node-count 3

Это уменьшит количество узлов до 3 в Node Pool myNodePool.

Если Node Pool больше не нужен, его можно прост удалить:

az aks nodepool delete --resource-group myResourceGroup --cluster-name myAKSCluster --name myNodePool

Обновление узлов до новых версий позволяет внедрять последние функции, исправления безопасности и улучшения производительности. На практике обнова узлов обычно связана с обновлением версии Kubernetes для Node Pool. Делается это с помощью az aks nodepool upgradeи с проверкой доступных версий с помощью az aks get-versions:

az aks nodepool upgrade --resource-group myResourceGroup --cluster-name myAKSCluster --name myNodePool --kubernetes-version 1.29

AKS обновляет узлы в Node Pool по одному, чтобы минимизировать простои. Для каждого узла в Node Pool процесс включает такие шаги:

  1. AKS помечает узел как unschedulable, чтобы предотвратить размещение новых подов на нем.

  2. Существующие поды на узле перемещаются на другие узлы в кластере с использованием механизма эвакуации подов.

  3. Узел обновляется до новой версии Kubernetes.

  4. После успешного обновления узел возвращается в кластер как готовый к работе , и на нем снова могут быть запланированы поды.

Taints и Tolerations

Taints применяются к узлам и могут отталкивать поды, которые не имеют соответствующих tolerations. Это позволяет ограничить, какие поды могут быть запущены на определенных узлах. Taints состоят из ключа, значения и эффекта, который определяет, что происходит с подами, не имеющими соответствующего toleration. Эффекты могут быть следующими:

  • NoSchedule: под не будет запланирован на узел.

  • PreferNoSchedule: система будет стараться не планировать под на узел, но это не гарантировано.

  • NoExecute: под будет выгнан с узла, если он уже запущен и не имеет соответствующего toleration.

Предположим, есть узлы с высокопроизводительными GPU, которые нужно использовать только для задач ml. Можно добавить taint к этим узлам:

kubectl taint nodes gpu-node-1 gpu=true:NoSchedule

Это означает, что только поды с соответствующим toleration смогут быть запланированы на этот узел.

Пример toleration для пода:

apiVersion: v1
kind: Pod
metadata:
  name: ml-pod
spec:
  containers:
  - name: ml-container
    image: ml-image
  tolerations:
  - key: "gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"

Этот под сможет запускаться на узле gpu-node-1, так как имеет соответствующий toleration.

Labels и Selectors

Labels — это ключ/значение метки, которые можно прикрепить к объектам, таким как поды и узлы, и затем использовать selectors для выбора объектов на основе этих меток.

Можно пометить узлы в зависимости от их физического расположения:

kubectl label nodes node-1 location=europe
kubectl label nodes node-2 location=asia

Чтобы запустить под на узле в определенном регионе, можно использовать node selector в спецификации пода:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
  nodeSelector:
    location: europe

Этот под будет запланирован на узле с меткой location=europe.

Примеры

Stateless приложения не сохраняют информацию о состоянии пользовательских сессий на сервере. К примеру для веб-странички конфигурация Node Pool может выглядеть так:

az aks nodepool add \
  --resource-group myResourceGroup \
  --cluster-name myAKSCluster \
  --name statelessNodePool \
  --node-count 3 \
  --enable-cluster-autoscaler \
  --min-count 1 \
  --max-count 10 \
  --node-vm-size Standard_F8s_v2 \
  --labels app=stateless \
  --no-wait

Здесь включено автоматическое масштабирование с минимальным количеством узлов 1 и максимальным 10, и используются виртуальные машины размера Standard_F8s_v2.

Развернем с yaml-манифестом:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web-container
        image: nginx
        ports:
        - containerPort: 80

Stateful приложения требуют сохранения данных или состояния между сессиями или запросами. Развернем бд PostgreSQL в кластере AKS

Конфигурация Node Pool:

az aks nodepool add \
  --resource-group myResourceGroup \
  --cluster-name myAKSCluster \
  --name batchNodePool \
  --node-count 2 \
  --node-vm-size Standard_D16s_v3 \
  --labels app=batch \
  --no-wait

Используем узлы Standard_D16s_v3, которые в целом дают хорошую производительность CPU

Создадим PVC для PostgreSQL и развертывание StatefulSet:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:latest
        ports:
        - containerPort: 5432
        volumeMounts:
        - mountPath: "/var/lib/postgresql/data"
          name: postgres-storage
      volumes:
      - name: postgres-storage
        persistentVolumeClaim:
          claimName: postgres-pvc

Статья подготовлена в преддверии старта курса Data Engineer. Узнать о курсе подробнее и зарегистрироваться на бесплатный урок можно по ссылке.

Источник: https://habr.com/ru/companies/otus/articles/794570/


Интересные статьи

Интересные статьи

Всем привет! Это моя первая публикация на хабре, поэтому буду благодарен за любую обратную связь, которая поможет мне писать ещё лучше.В статье вас ждёт "сборка" очень простой связки из распознавания ...
Привет, друзья! Вам когда-нибудь хотелось узнать, как работают сборщики модулей (module bundlers) JavaScript типа Webpack или Parcel, что называется, под капотом. Если хотелось, тогда эта статья ...
Дорогие товарищи инженеры, сообщество Метархия представляет вашему вниманию современный курс по Node.js, который включает глубокий разбор всех возможностей и аспектов платформы. Основной упор д...
Это исчерпывающее руководство по обеспечению надёжности в JavaScript и Node.js. Здесь собраны десятки лучших постов, книг и инструментов. Сначала разберитесь с общепринятыми методиками тести...
Периодически, с целью переезда в ЦРС собеседуюсь в разных крупных компаниях, в основном питера и москвы на должность DevOps. Обратил внимание, что во многих компаниях (во многих хороших компаниях...