EKS prefix delegation: больше подов на узел в AWS

В Amazon Web Services каждый тип инстанса имеет свой предел по количеству подов (Pods), которые он может запускать. Например, инстанс m5.large вмещает не более 29 подов, тогда как m5.4xlarge — до 234. Причина кроется в ограниченном количестве IP-адресов, которые можно назначить одному EC2-инстансу.

Интерфейс контейнерных сетей (Container Network Interface, CNI) использует эти адреса и назначает их подам. Однако данное ограничение снимается, если применять делегирование префиксов EC2 (EC2 prefix delegation) через AWS-CNI или любой другой CNI с поддержкой этой функции (например, Cilium).

Плагин VPC CNI напрямую интегрируется с сетевой подсистемой EC2 и обеспечивает высокопроизводительную сеть с низкой задержкой для Kubernetes-кластеров на AWS. Плагин назначает каждому поду IP-адрес из VPC кластера. По умолчанию количество доступных для подов адресов определяется максимальным числом эластичных сетевых интерфейсов (Elastic Network Interfaces, ENI) и вторичных IP-адресов на интерфейс для данного типа инстанса. Каждому узлу требуется один IP-адрес на каждый сетевой интерфейс; все остальные доступные адреса можно назначать подам.

В режиме назначения префиксов максимальное число ENI на тип инстанса остаётся прежним, но теперь Amazon VPC CNI можно настроить так, чтобы он назначал сетевым интерфейсам IPv4-префиксы /28 (по 16 IP-адресов), а не отдельные IPv4-адреса. Поды при этом получают IPv4-адрес из префикса, назначенного ENI.

Примечание

Amazon VPC CNI разворачивается на рабочих узлах в виде Kubernetes DaemonSet с именем aws-node. Плагин состоит из двух основных компонентов: локального управления IP-адресами (Local IP Address Management, L-IPAM) и собственно бинарного файла CNI.

— Демон L-IPAM (IPAMD) — отвечает за создание и подключение сетевых интерфейсов к рабочим узлам, назначение префиксов этим интерфейсам и поддержание «тёплого» пула (warm pool) IP-префиксов на каждом узле для последующего назначения подам по мере их планирования.

— Бинарный файл CNI (/opt/cni/bin/aws-cni) — вызывается kubelet при добавлении нового пода на узел или удалении существующего. После этого бинарник CNI обращается к ipamd по протоколу gRPC с запросом IP-адреса для нового пода.

Как рассчитать максимальное число подов на узле

При использовании VPC CNI максимальное число подов на узле зависит от настроек VPC CNI. В рамках соответствующего релиза команда AWS обновила управляемые группы узлов EKS (EKS managed node groups): теперь они автоматически вычисляют и устанавливают рекомендуемое значение максимального числа подов исходя из типа инстанса и параметров конфигурации VPC CNI — при условии использования как минимум указанной версии VPC CNI.

Значение max pods будет установлено для любых вновь созданных управляемых групп узлов, а также для групп, обновлённых до более новой версии AMI. Это полезно как для сценариев с назначением префиксов, так и для пользовательских сетевых настроек CNI, где раньше приходилось вручную задавать пониженное значение max pods.

Важно

Управляемые группы узлов ищут плагин VPC CNI, установленный в пространстве имён kube-system, с DaemonSet-именем aws-node и именем контейнера aws-node. Если вы изменили установку VPC CNI и он работает в другом месте, автоматический расчёт max pods для управляемых групп узлов будет пропущен, и останется значение по умолчанию, встроенное в EKS-оптимизированный AMI.

Если вы используете самоуправляемые группы узлов или управляемую группу с пользовательским AMI ID, рекомендуемое значение max pods необходимо вычислить вручную.

Для этого добавьте следующий скрипт в поле User data:

#!/bin/bash
/etc/eks/bootstrap.sh my-cluster \
 -- use-max-pods false \
 -- kubelet-extra-args '-- max-pods=20'

Примечание: замените 20 на рассчитанное вами значение max-pods.

Рассмотрим, как вычисляется значение max pods в режиме назначения префиксов.

Обратите внимание, что суммарное количество префиксов и приватных IP-адресов ограничено числом приватных IP, допустимых для данного инстанса. Например, ENI инстанса m5.large имеют лимит в 10 слотов, один из которых занят основным IP-адресом ENI, — таким образом, для префиксов /28 остаётся 9 слотов.

❇️ Формула для определения максимального числа подов на инстанс, когда режим назначения IP-префиксов отключён:

N * (M-1) + 2

Где:
— N — количество эластичных сетевых интерфейсов (ENI) для данного типа инстанса;
— M — количество IP-адресов одного ENI.

Значения N и M для каждого типа инстанса приведены в этом документе.

Кроме того, можно воспользоваться командой ниже, указав нужный тип инстанса:

aws ec2 describe-instance-types --filters "Name=instance-type,Values=m5.*" \
 --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
 --output table

---------------------------------------
|        DescribeInstanceTypes        |
+----------+----------+---------------+
| IPv4addr | MaxENI   |     Type      |
+----------+----------+---------------+
|  30      |  8       |  m5.8xlarge   |
|  50      |  15      |  m5.24xlarge  |
|  15      |  4       |  m5.xlarge    |
|  30      |  8       |  m5.12xlarge  |
|  10      |  3       |  m5.large     |
|  15      |  4       |  m5.2xlarge   |
|  50      |  15      |  m5.metal     |
|  30      |  8       |  m5.4xlarge   |
|  50      |  15      |  m5.16xlarge  |
+----------+----------+---------------+

Таким образом, для m5.large расчёт выглядит так: 3 × (10 − 1) + 2 = 29.

❇️ Формула для определения максимального числа подов на инстанс, когда режим назначения IP-префиксов включён:

(N × (количество слотов на сетевой интерфейс "M" - 1) * 16)

Например, для m5.large есть 3 ENI с 10 слотами (или IP-адресами) каждый. Поскольку один IP зарезервирован для ENI, остаётся 9 слотов. Каждый слот — это 16 IP-адресов, значит 9 × 16 = 144 IP. При трёх ENI получаем 144 × 3 = 432 IP.
Таким образом, теперь можно запустить до 432 подов (против 29 ранее).

❇️ Ещё один способ вычислить максимальное число подов на инстанс

  1. Скачайте скрипт для расчёта максимального числа подов на каждый тип инстанса:

    curl -O https://raw.githubusercontent.com/awslabs/amazon-eks-ami/master/templates/al2/runtime/max-pods-calculator.sh
  2. Сделайте скрипт исполняемым:

    chmod +x max-pods-calculator.sh
  3. Запустите скрипт, заменив m5.large на нужный тип инстанса, а 1.9.0-eksbuild.1 — на вашу версию дополнения Amazon VPC CNI:

    ./max-pods-calculator.sh --instance-type m5.large --cni-version 1.9.0-eksbuild.1
    
    # вывод: 29

Текущую версию плагина VPC CNI можно узнать следующей командой:

kubectl describe ds aws-node -n kube-system | grep Image | cut -d "/" -f 2

К скрипту можно добавить дополнительные флаги, чтобы узнать максимальное число подов при использовании опциональных возможностей.

--cni-custom-networking-enabled — используйте этот флаг, если хотите назначать IP-адреса из подсети, отличной от той, что используется инстансом. Подробнее — в документации по пользовательским сетевым настройкам для подов. При добавлении этого флага к предыдущей команде с теми же значениями результат составит 20:

./max-pods-calculator.sh --instance-type m5.large --cni-version 1.9.0-eksbuild.1 --cni-custom-networking-enabled

# вывод: 20

# при включении пользовательских сетевых настроек CNI допустимое число подов меньше,
# потому что IP-адреса, назначенные первичному сетевому интерфейсу, не используются для подов.
# Подам назначаются только адреса с вторичных сетевых интерфейсов.

--cni-prefix-delegation-enabled — используйте этот флаг для режима назначения IP-префиксов. При добавлении к предыдущей команде с теми же значениями результат составит 110:

./max-pods-calculator.sh --instance-type m5.large --cni-version 1.9.0-eksbuild.1 --cni-prefix-delegation-enabled --cni-custom-networking-enabled

# вывод: 110
Примечание

AWS-CNI поддерживает слоты и ограничивает максимальное число подов значением 110 или 250 — запустить 432 пода на m5.large не получится. Из соображений обратной совместимости значение max pods по умолчанию для каждого типа инстанса в EKS-оптимизированном Amazon Linux AMI не меняется. При использовании назначения префиксов с небольшими типами инстансов, такими как m5.large, ресурсы CPU и памяти инстанса, скорее всего, будут исчерпаны значительно раньше, чем закончатся IP-адреса.

Если у вашего типа инстанса более 30 виртуальных ЦП (vCPU), лимит возрастает до 250 — это значение основано на результатах нагрузочного тестирования внутренней команды EKS по масштабируемости.

Включение режима назначения IP-префиксов

При создании кластера версии 1.21 и выше вместе с ним разворачивается плагин Amazon VPC CNI для Kubernetes версии 1.10.1 и выше. Если кластер был создан с семейством адресов IPv6, этот параметр по умолчанию равен true. Если кластер создан с семейством IPv4 — по умолчанию false.

kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true

Как уже говорилось, плагин Amazon VPC CNI для Kubernetes поддерживает два режима выделения адресов: режим делегирования префиксов (prefix delegation mode) и режим вторичных IP (secondary IP mode).

Их поведение настраивается с помощью переменных конфигурации: WARM_IP_TARGET, WARM_PREFIX_TARGET и MINIMUM_IP_TARGET — они управляют тем, сколько IP-адресов или префиксов плагин держит «тёплыми» — заранее выделенными и готовыми к мгновенному назначению подам.

При ENABLE_PREFIX_DELEGATION=true IPAMD выделяет ENI префиксы /28 (по 16 IP каждый). В режиме префиксов рекомендуется задать WARM_PREFIX_TARGET=1 — это позволяет держать на каждом узле один дополнительный неиспользуемый префикс для ускорения создания подов.

Задать это значение вручную можно следующей командой, если оно ещё не указано в манифесте:

kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1

При настройке по умолчанию WARM_PREFIX_TARGET выделяет один дополнительный полный префикс (/28), даже если существующий префикс занят всего одним подом. Если ENI не хватает места для нового префикса, создаётся новый ENI. При создании нового ENI IPAMD определяет, сколько префиксов нужно для поддержания заданного WARM_PREFIX_TARGET, и выделяет их. Новые ENI будут подключаться только после того, как все префиксы на существующих ENI будут исчерпаны.

Когда режим назначения IP-префиксов включён, устанавливать WARM_PREFIX_TARGET или одновременно WARM_IP_TARGET и MINIMUM_IP_TARGET в ноль не поддерживается. Это лишит IPAMD возможности поддерживать тёплый пул префиксов и приведёт к значительным задержкам при назначении IP-адресов подам. Задержки становятся особенно заметными, если IPAMD приходится выделять и подключать новый ENI — и ждать синхронизации с IMDS — перед тем как назначить IP подам.

Если заданы WARM_IP_TARGET и/или MINIMUM_IP_TARGET, они имеют приоритет над WARM_PREFIX_TARGET.

Но это ещё не всё.

Даже при включённом делегировании префиксов и WARM_PREFIX_TARGET=1 остаются некоторые проблемы: фрагментация IP и исчерпание IP-адресов.

Исчерпание IP-адресов

Это происходит, когда в кластере заканчиваются доступные IP-адреса. Представьте деплой из трёх реплик пода, распределённых по трём узлам. Каждый узел получает от VPC CNI плагина префикс /28 (16 IP), но каждый под потребляет лишь один адрес. В результате на узлах остаются неиспользованными 45 IP-адресов (15 × 3) — IP-пространство VPC расходуется неэффективно.

Фрагментация

Фрагментация возникает, когда префиксы часто подключаются и отключаются от узлов, порождая разрозненные, частично используемые IP-диапазоны. Например, узел начинает работу с двумя префиксами (32 IP). После планирования 25 подов IPAMD задействует оба префикса. Затем 10 подов из первого префикса завершаются, но IPAMD не может освободить этот префикс, поскольку часть IP всё ещё используется. При создании новых подов IPAMD выделяет третий префикс — в итоге IP-адреса распределяются неэффективно.

Способы снижения рисков

Для снижения этих рисков можно назначить дополнительный блок CIDR (secondary CIDR block) для VPC или подсетей, используемых EKS. Это расширяет пул доступных IP-адресов и снижает вероятность их исчерпания на уровне подсети. Однако полностью предотвратить фрагментацию, происходящую внутри узлов, это не позволяет. Важную роль также играет правильное масштабирование узлов и грамотное распределение нагрузки.

Заключение

Включение делегирования префиксов и настройка «тёплых» целевых значений (например, WARM_PREFIX_TARGET=1) позволяют существенно снизить задержку при запуске подов и повысить эффективность использования IP-адресов в Amazon EKS. Делегирование префиксов сокращает задержки при вызовах API и улучшает масштабируемость, однако для долгосрочной эффективности кластера — особенно в крупных динамически масштабируемых окружениях — необходимо постоянно отслеживать использование IP-адресов и характер фрагментации.

© 2026 meganuke