Вопрос или проблема
У меня есть кластер с двумя типами узлов: x86 и arm. Ядра arm немного слабее, поэтому я хочу дать подам на узлах arm 1,5 от того объема CPU, который я выделяю на узлах x86.
Я мог бы создать два развертывания, но это усложняет мой авто-масштабатор Keda. Предположим, что я масштабируюсь в зависимости от очереди, я не нашел способа установить ScaledObject для двух развертываний одновременно.
Существует ли способ задать контейнеру разные ограничения ресурсов в зависимости от пятна/аффинности узла?
В Kubernetes вы можете управлять выделением ресурсов для подов на основе характеристик узлов, используя комбинацию аффинности узла и ограничений запросов ресурсов. Однако поскольку мы не можем напрямую устанавливать разные ограничения ресурсов для контейнеров в зависимости от типа узла, мы можем попробовать сделать это следующим способом.
Аффинность узла: Вы можете использовать аффинность узла, чтобы контролировать, где будут запланированы ваши поды. Например, вы можете пометить ваши узлы (например, arch=x86 и arch=arm), а затем установить правила аффинности в ваших спецификациях подов.
Смотрите пример ниже:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoreDuring
Execution:
nodeSelectorTerms:
-matchExpressions:
- key:arch
operator:In
Values:
-arm
Если вам обязательно нужны развертывания для KEDA, вы можете использовать масштабируемый объект KEDA для нацеливания на несколько развертываний.
Ответ или решение
Для организации развертывания приложений в Kubernetes с учетом различных ресурсов для различных типов узлов, таких как x86 и ARM, вы можете использовать комбинацию нодовой аффинности и лимитов ресурсов. Данная практика позволит эффективно управлять ресурсами подов при их размещении на узлах с различной архитектурой.
1. Нодовая аффинность
Нодовая аффинность (node affinity) — это механизм, который позволяет вам указывать, на каких узлах должны быть развернуты ваши поды. Вам необходимо сначала добавить метки на узлы. Например, метки можно задать следующим образом:
kubectl label nodes <имя-узла-x86> arch=x86
kubectl label nodes <имя-узла-arm> arch=arm
После этого в спецификации ваших подов или развертываний можно установить нодовую аффинность:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: arch
operator: In
values:
- arm
Партия подов, которая будет запущена на ARM-узлах, теперь легко управляется с использованием данной конструкции.
2. Установка лимитов ресурсов
Однако Kubernetes не позволяет устанавливать различные лимиты ресурсов для одних и тех же развертываний, в зависимости от типа узла. Поэтому рекомендуется использовать конфигурацию, которая позволяет создавать один экземпляр развертывания, но с различными лимитами ресурсов, зависящими от архитектуры узла.
Из-за этого вы можете настроить шаблон развертывания с использованием переменных среды или условий для определения, на каком узле он развернут, и соответственно настраивать лимиты ресурсов программно через конфигурируемые параметры или инструменты CI/CD.
3. Использование KEDA для масштабирования развертываний
Если у вас есть необходимость в автоматическом масштабировании с помощью KEDA (Kubernetes Event-driven Autoscaling), вы можете воспользоваться возможностью создания нескольких scaledObject
, каждый из которых будет отслеживать соответствующее развертывание. KEDA может работать с несколькими развертываниями, если они имеют разные метрики или источники событий, которые могут быть связаны с именно вашим приложением.
Пример ScaledObject
для каждого развертывания может выглядеть так:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: my-app-scaler
spec:
scaleTargetRef:
name: my-app-deployment
...
triggers:
- type: queue
metadata:
queueName: my-queue
targetQueueLength: '5'
В случае если вам требуется масштабировать несколько развертываний в зависимости от нагрузки на очередь, вы можете настроить логику таким образом, чтобы каждая ScaledObject
или триггер относился к своему уникальному развертыванию, тем самым избегая усложнения и увеличивая гибкость настройки и управления.
Заключение
Использование нодовой аффинности и адекватных лимитов ресурсов в рамках одного развертывания, а также поддержка KEDA для автоматического масштабирования обеспечит надлежащую оптимизацию работы ваших приложений в кластере Kubernetes. Данная архитектура позволит вам избежать дублирования развертываний и значительно упростит процессы управления и мониторинга подов.