Поделиться через


Настройка политик отказоустойчивости узлов для узлов автоматической подготовки (NAP) в службе Azure Kubernetes (AKS)

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

NAP оптимизирует кластер по следующим компонентам:

  • Удаление или замена недоиспользуемых узлов.
  • Консолидация рабочих нагрузок для снижения затрат.
  • Уважая лимиты на прерывания и окна технического обслуживания.
  • Предоставление ручного управления при необходимости.

Перед тем как начать

Как происходит прерывание работы узлов NAP?

Karpenter задает финализатор Kubernetes на каждом узле и иске узла, которые он подготавливает. Финализатор блокирует удаление объекта узла, а контроллер завершения помечает и освобождает узел перед удалением запроса подлежащего узла.

Когда рабочие нагрузки на узлах уменьшаются, NAP использует правила безопасного изменения в спецификации пула узлов, чтобы решить, когда и как удалить эти узлы и потенциально перепланировать рабочие нагрузки для повышения эффективности.

Методы нарушения работы узла

NAP автоматически обнаруживает узлы, подходящие для прерывания работы, и при необходимости запускает замены. Вы можете инициировать сбой с помощью автоматизированных методов, таких как истечение срока действия, консолидация и дрейф, ручные методы или внешние системы.

Expiration

Срок действия позволяет задать максимальный возраст для узлов NAP. Узлы помечаются как истекшие и больше не функционирующие после достижения возраста, указанного для значения spec.disruption.expireAfter в пуле узлов.

Пример конфигурации срока действия

В следующем примере показано, как задать время окончания срока действия узлов NAP в 24 часа:

spec:
  disruption:
    expireAfter: 24h  # Expire nodes after 24 hours

Consolidation

NAP работает для активного снижения затрат на кластер, определяя, когда узлы могут быть удалены, так как они пустые или недоиспользуемые, или когда узлы могут быть заменены более дешевыми вариантами. Этот процесс называется консолидацией. NAP в основном использует консолидацию для удаления или замены узлов для оптимального размещения pod.

NAP выполняет следующие типы консолидации для оптимизации использования ресурсов:

  • Консолидация пустых узлов: удаляет все пустые узлы параллельно.
  • Консолидация с несколькими узлами: удаляет несколько узлов, возможно, запускает одну замену.
  • Консолидация с одним узлом: удаляет любой один узел, возможно, запускает замену.

Вы можете активировать консолидацию через поле spec.disruption.consolidationPolicy в спецификации пула узлов, используя настройки WhenEmpty или WhenEmptyOrUnderUtilized. Вы также можете задать consolidateAfter поле, представляющее собой условие, основанное на времени, которое определяет, как долго NAP ждет после обнаружения возможности консолидации перед прерыванием узла.

Пример конфигурации консолидации

В следующем примере показано, как настроить NAP для консолидации узлов, когда они пусты, и ждать 30 секунд после обнаружения возможности консолидации перед нарушением узла:

  disruption:
    # Describes which types of nodes NAP should consider for consolidation
    # `WhenEmptyOrUnderUtilized`: NAP considers all nodes for consolidation and attempts to remove or replace nodes when it discovers that the node is empty or underutilized and could be changed to reduce cost
    # `WhenEmpty`: NAP only considers nodes for consolidation that don't contain any workload pods
    
    consolidationPolicy: WhenEmpty

    # The amount of time NAP should wait after discovering a consolidation decision
    # Currently, you can only set this value when the consolidation policy is `WhenEmpty`
    # You can choose to disable consolidation entirely by setting the string value `Never`
    consolidateAfter: 30s

Дрейф

Дрейф обрабатывает изменения ресурсов NodePool/AKSNodeClass. Значения в нем NodeClaimTemplateSpec/AKSNodeClassSpec отражаются так же, как они заданы. Объект NodeClaim обнаруживается как дрейфованный, если значения в связанном NodePool/AKSNodeClass не соответствуют значениям в .NodeClaim deployment.spec.template Аналогично входящему отношению к pod'ам, Karpenter аннотирует связанный NodePool/AKSNodeClass с хэшом NodeClaimTemplateSpec для проверки отклонения. Карпентер удаляет Drifted условие состояния в следующих сценариях:

  • Шлюз Drift функций не включен, но NodeClaim сдвинут.
  • Он NodeClaim не отклоняется, но имеет статусное состояние.

Карпентер или интерфейс поставщика облачных служб может обнаруживать особые случаи, вызванные изменениямиNodeClaim/Instance/NodePool/AKSNodeClass.

Особые случаи смещения

В особых случаях смещение может соответствовать нескольким значениям и обрабатываться по-разному. Смещение по разрешенным полям может создавать случаи, когда смещение происходит без изменений в пользовательских определениях ресурсов (CRD) или в том случае, когда изменения CRD не приводят к смещению.

Например, если у NodeClaim есть node.kubernetes.io/instance-type: Standard_D2s_v3, а требования изменяются с node.kubernetes.io/instance-type In [Standard_D2s_v3] на node.kubernetes.io/instance-type In [Standard_D2s_v3, Standard_D4s_v3], NodeClaim не смещается, так как его значение по-прежнему совместимо с новыми требованиями. И наоборот, если используется NodeClaimNodeClaimimageFamily, но поле spec.imageFamily изменяется, Karpenter обнаруживает NodeClaim как отклонение и обновляет узел для соответствия этой спецификации.

Это важно

Karpenter отслеживает изменения конфигурации подсети и обнаруживает отклонение, когда vnetSubnetID изменяется в AKSNodeClass. Понимание этого поведения важно при управлении пользовательскими конфигурациями сети. Для получения дополнительной информации см. «Поведение дрейфа в подсети».

Для получения дополнительной информации см. Drift Design.

Льготный период прекращения

Вы можете задать льготный период завершения для узлов NAP с помощью spec.template.spec.terminationGracePeriod поля в спецификации пула узлов. Этот параметр позволяет настроить, сколько времени Карпентер будет ожидать плавного завершения подов. Этот параметр имеет приоритет над параметрами pod terminationGracePeriodSeconds, игнорирует PodDisruptionBudgets и аннотацию karpenter.sh/do-not-disrupt.

Пример конфигурации льготного периода завершения

В следующем примере показано, как задать период ожидания завершения в 30 секунд для NAP-узлов.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      terminationGracePeriod: 30s

Нарушения бюджета

Вы можете ограничить вмешательство Карпентера, изменив поле spec.disruption.budgets в спецификации пула узлов. Если этот параметр не определен, Карпентер по умолчанию использует один бюджет nodes: 10%. Бюджеты учитывают узлы, которые удаляются по любой причине, и они препятствуют Карпентеру совершать добровольные прерывания через истечение срока действия, смещение, пустоту и консолидацию.

Когда вычисляется, блокирует ли бюджет узлы для избежания сбоев, Карпентер подсчитывает общее количество узлов, принадлежащих пулу узлов, а затем вычитает узлы, которые удаляются, и узлы, которые NotReady. Если бюджет настроен с процентным значением, например 20%, Karpenter вычисляет количество разрешённых нарушений как allowed_disruptions = roundup(total * percentage) - total_deleting - total_notready. Для нескольких бюджетов в пуле узлов Карпентер принимает минимальное (самое строгое) значение каждого из бюджетов.

Поля расписания и длительности

При использовании бюджетов можно при необходимости задать schedule и duration поля для создания бюджетов на основе времени. Эти поля позволяют определять периоды обслуживания или определенные временные интервалы, когда ограничения нарушений являются более строгими.

  • Расписание использует синтаксис задания cron со специальными макросами, такими как @yearly, @monthly, @weekly, @daily. @hourly
  • Длительность разрешает составные длительности, например 10h5m, 30mили 160h. Длительность и расписание должны быть определены вместе.

Примеры расписания и длительности

Бюджет периода обслуживания

Предотвращение сбоев в рабочее время:

budgets:
- nodes: "0"
  schedule: "0 9 * * 1-5"  # 9 AM Monday-Friday
  duration: 8h             # For 8 hours
Прерывания только в выходные дни

Разрешать перебои только в выходные дни

budgets:
- nodes: "50%"
  schedule: "0 0 * * 6"    # Saturday midnight
  duration: 48h            # All weekend
- nodes: "0"               # Block all other times
Постепенный бюджет внедрения

Разрешить увеличение частоты нарушений:

budgets:
- nodes: "1"
  schedule: "0 2 * * *"    # 2 AM daily
  duration: 2h
- nodes: "3"
  schedule: "0 4 * * *"    # 4 AM daily
  duration: 4h

Примеры конфигурации бюджета

В следующей NodePool спецификации настроены три бюджета:

  • Первый бюджет позволяет одновременно нарушить работу 20% узлов, принадлежащих пулу узлов.
  • Второй бюджет является верхним пределом, который допускает только пять сбоев при наличии более 25 узлов.
  • Последний бюджет предотвращает сбои в течение первых 10 минут каждого дня.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    expireAfter: 720h # 30 * 24h = 720h
    budgets:
    - nodes: "20%"      # Allow 20% of nodes to be disrupted
    - nodes: "5"        # Cap at maximum 5 nodes
    - nodes: "0"        # Block all disruptions during maintenance window
      schedule: "@daily" # Scheduled daily
      duration: 10m # Duration of 10 minutes

Нарушение узла вручную

Вы можете вручную нарушить работу узлов NAP с помощью kubectl или удаления NodePool ресурсов.

Удаление узлов с помощью kubectl

Вы можете вручную удалить узлы с помощью kubectl delete node команды. Вы можете удалить определенные узлы, все управляемые NAP узлы или узлы из определенного пула узлов с помощью меток, например:

# Delete a specific node
kubectl delete node $NODE_NAME

# Delete all NAP-managed nodes
kubectl delete nodes -l karpenter.sh/nodepool

# Delete nodes from a specific nodepool
kubectl delete nodes -l karpenter.sh/nodepool=$NODEPOOL_NAME

Удалите NodePool ресурсы

NodePool владеет NodeClaims через ссылку на владельца. NAP аккуратно завершает работу узлов через каскадное удаление при удалении связанного объекта NodePool.

Управление нарушением работы с помощью заметок

Вы можете заблокировать или отключить прерывание для конкретных pod, узлов или целых пулов узлов с помощью аннотаций.

Элементы управления Pod

Запретить NAP от вмешательства в работу определенных podов, задав аннотацию karpenter.sh/do-not-disrupt: "true":

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

Эта аннотация предотвращает добровольные нарушения, связанные с истечением срока действия, консолидацией и дрейфом. Однако это не препятствует нарушению внешних систем или нарушению вручную через kubectl или NodePool удаление.

Элементы управления узлами

Блокировка NAP от нарушения работы определенных узлов:

apiVersion: v1
kind: Node
metadata:
  annotations:
    karpenter.sh/do-not-disrupt: "true"

Элементы управления пулом узлов

Отключение сбоев для всех узлов в NodePool.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

Дальнейшие шаги

Дополнительные сведения об автоматической подготовке узлов в AKS см. в следующих статьях: