Привет, Хабр!
В 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 выглядит довольно просто:
В меню кластера AKS выбираем Node pools.
Нажимаем кнопку + Add node pool.
В форме добавления Node Pool вводим имя, выбераем размер виртуальной машины, количество узлов и другие параметры
После настройки параметров нажимаем 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 процесс включает такие шаги:
AKS помечает узел как unschedulable, чтобы предотвратить размещение новых подов на нем.
Существующие поды на узле перемещаются на другие узлы в кластере с использованием механизма эвакуации подов.
Узел обновляется до новой версии Kubernetes.
После успешного обновления узел возвращается в кластер как готовый к работе , и на нем снова могут быть запланированы поды.
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. Узнать о курсе подробнее и зарегистрироваться на бесплатный урок можно по ссылке.