У нас есть простой трехузловой кластер Kubernetes в службе Azure Kubernetes (AKS). В большинстве случаев с точки зрения инфраструктуры этого более чем достаточно, но иногда нам нужно масштабировать на пару часов до 50 экземпляров службы, а затем снова масштабировать.
Объединение AKS с экземплярами контейнеров Azure (ACI) через Virtual Kubelet кажется идеальным решением для этого сценария.
С точки зрения управления затратами мы предпочли бы, чтобы все работало на наш ВМ, если есть доступная емкость. Мы уже платим за них, так что нет смысла платить и за инстансы ACI.
Вопрос 1
Если мы масштабируем через Virtual Kubelet с помощью ACI, как Kubernetes выбирает, какие поды масштабировать? назад позже? Согласуется ли его подход с нашим требованием к управлению затратами - т.е. предпочтительны «настоящие» узлы - или его можно сделать согласованным?
вопрос 2
Сценарий: мы запускаем два приложения - «App1» и «App2» - в Kubernetes. Приложение1 тот, который вызывает необходимость масштабирования до 50 экземпляров через ACI; Приложение 2 работает на «настоящих» узлах.
Скажем, мы используем Helm для обновления Приложение 2. Когда он перезапускается, я предполагаю, что Kubernetes мог поместите его в экземпляр ACI, так как в этот момент мы масштабируемся.
Позже потребность в 50 экземплярах Приложение1 уходит, и мы снова уменьшаемся.
Приложение 2 будет по-прежнему работать на экземплярах ACI, хотя мы бы предпочли, чтобы они вернулись на настоящие узлы на этом этапе.
Сможет ли Kubernetes справиться с этим в соответствии с нашими требованиями к управлению затратами или потребуется дополнительное руководство?
Отвечая на свой вопрос - а PreferNoSchedule
заражение Virtual Kubelet предотвратит включение модулей в более дорогие ресурсы при масштабировании. вверх, но планировщик не участвует в масштабировании вниз.
«Жертва» выбирается в результате следующих тестов:
Видеть:
Короче говоря, нет реального способа контролировать жертв в сценарии уменьшения масштаба, не прибегая к хакерским подходам и условиям гонки.
В конце концов, мы пошли другим путем: два разных развертывания одного и того же приложения и испорченный Virtual Kubelet:
Одно развертывание, которое не допускает заражения Virtual Kubelet - минимальное количество реплик равно 1, а максимальное количество реплик - 5.
Другое развертывание, допускающее заражение Virtual Kubelet, а также nodeSelector для него. Количество реплик по умолчанию равно 0, но мы, очевидно, можем масштабировать это при необходимости.
Помимо этого, у нас работает собственная микрослужба, которая отслеживает длину очереди служебной шины Azure и принимает решения о масштабировании для двух развертываний.
Не так элегантно, как мы хотели бы, но дает нам полный контроль над тем, что живет в нашем кластере.
Надеюсь, это кому-то поможет!