Как удержать Kubernetes на 2500 нодах и не сломать API-сервер
На тысячах нод узкими местами становятся не поды, а etcd, DNS и API-сервер. Разбираем, что тюнить, какие лимиты помнить и где кластер начинает трещать.

Официальный порог поддержки Kubernetes — 5000 нод, 150 000 подов и 300 000 контейнеров в одном кластере. На бумаге цифра большая, но на практике кластер начинает вести себя странно гораздо раньше: где-то на 1000–2000 нод растёт задержка API-сервера, etcd упирается в лимит хранилища, а kube-dns не успевает отвечать. Ниже — что именно ломается при масштабировании к 2500 нодам и какие параметры стоит трогать в первую очередь.
Где кластер упирается в потолок
Проблема масштаба в Kubernetes почти никогда не в самих нодах. Нода — это kubelet, который держит поды и шлёт статусы. Проблема в control plane: одном или нескольких API-серверах, за которыми стоит etcd, и в сетевых сервисах, которые обслуживают весь этот трафик.
Три компонента ломаются раньше остальных:
- etcd — распределённое хранилище, куда пишется всё состояние кластера. По умолчанию у него лимит базы 2 ГБ (флаг
--quota-backend-bytes), и на больших кластерах его поднимают до 8 ГБ. Выше 8 ГБ разработчики etcd не рекомендуют идти: растёт время компакции и восстановления. - kube-apiserver — точка входа для всех запросов. При тысячах kubelet-ов, контроллеров и watch-подписок он захлёбывается на сериализации ответов и на watch-каналах.
- DNS — CoreDNS или её предшественники. Каждый под по умолчанию резолвит имена сервисов через кластерный DNS, и на масштабе это десятки тысяч запросов в секунду.
Масштабирование Kubernetes — это не про то, как запустить больше подов. Это про то, как не дать одному etcd-кластеру из трёх нод стать точкой отказа для 150 000 подов.
etcd: главный ограничитель
etcd — это Raft-кластер*, обычно из трёх или пяти нод. Он линейно масштабируется по чтению (через реплики), но запись всегда идёт через один лидер, и её пропускная способность ограничена скоростью диска и сети между членами кластера.
Что помогает на больших кластерах:
- Быстрые диски. etcd крайне чувствителен к latency диска: fsync каждой записи в WAL блокирует консенсус. NVMe SSD вместо сетевого хранилища — не роскошь, а условие стабильности. Держите
wal_fsync_duration_secondsпод наблюдением: 99-й перцентиль выше 10 мс — тревожный знак. - Разделение событий. Kubernetes умеет писать Events в отдельный etcd-кластер через флаг
--etcd-servers-overrides. События генерируются потоком и засоряют основное хранилище — вынесите их отдельно. - Регулярная компакция и дефрагментация. Историю ревизий нужно подчищать, иначе база пухнет и упирается в квоту. Компакция настраивается через
--auto-compaction-retention.
Почему нельзя просто добавить нод в etcd
Кажется логичным: больше членов кластера — больше надёжности. На деле каждая новая нода в Raft увеличивает объём координации при записи. Пять членов дают отказоустойчивость к двум сбоям, но пишут медленнее трёх. Семь и больше — почти всегда ошибка: запись деградирует, а выигрыш в надёжности минимален.
API-сервер: watch, кэш и приоритеты
Каждый kubelet, каждый контроллер и каждый оператор держит watch-соединения к API-серверу, чтобы получать изменения объектов в реальном времени. На 2500 нодах это десятки тысяч одновременных watch-каналов.
Ключевые рычаги:
- Watch cache. API-сервер держит кэш объектов в памяти и отдаёт watch-события из него, не долбя etcd на каждый запрос. Под большой кластер серверу нужно много RAM — десятки гигабайт под кэш реальны.
- Несколько реплик API-сервера за балансировщиком. Запись всё равно уйдёт в etcd через один лидер, но чтение и watch распределятся.
- API Priority and Fairness (APF). Механизм, который делит запросы на потоки и не даёт одному шумному клиенту выесть все ресурсы сервера. На больших кластерах APF — обязательная настройка, а не опция: без неё один взбесившийся контроллер кладёт control plane.
Регулируйте частоту опроса
Многие контроллеры и внешние операторы поллят API-сервер вместо watch либо делают list-запросы по всем объектам. Один LIST pods без селектора на кластере со 150 000 подов — это мегабайты трафика и заметная нагрузка на сериализацию. Проверяйте --kube-api-qps и --kube-api-burst у своих компонентов и заменяйте list-циклы на informer-ы с кэшем.
DNS и сеть
CoreDNS по умолчанию отвечает на резолвы имён сервисов. Стандартная конфигурация glibc с ndots:5 порождает несколько лишних запросов на каждое разрешение внешнего имени — под ищет example.com.svc.cluster.local, потом example.com.cluster.local и так далее. На масштабе это лавина.
Что делают:
- Разворачивают NodeLocal DNSCache — локальный кэширующий агент на каждой ноде, чтобы резолвы не бегали к центральным CoreDNS через сеть.
- Правят
dnsConfigу подов, снижаяndots, где это уместно. - Следят за conntrack-таблицей на нодах: kube-proxy в режиме iptables создаёт множество правил, и на больших кластерах переход на IPVS или на eBPF-датаплейн (Cilium) снимает часть нагрузки.
Ориентиры и лимиты
Точные пороги зависят от нагрузки, но официальная документация Kubernetes даёт верхние границы, за которые не стоит выходить в одном кластере.
| Параметр | Рекомендованный потолок | Комментарий |
|---|---|---|
| Ноды в кластере | до 5000 | Выше — федерация из нескольких кластеров |
| Поды всего | до 150 000 | Ограничено etcd и watch cache |
| Контейнеры всего | до 300 000 | |
| Поды на одну ноду | до 110 | Дефолтный лимит kubelet, тюнингуется |
| Размер базы etcd | до 8 ГБ | Практический предел, не хардлимит |
Эти цифры — верхняя граница поддерживаемой конфигурации, а не рекомендация к достижению. Актуальные значения сверяйте в разделе документации по большим кластерам, они меняются от версии к версии.
Порядок действий при росте
- Соберите метрики control plane: latency API-сервера по перцентилям,
etcd_disk_wal_fsync_duration_seconds, размер базы etcd, QPS к DNS. - Вынесите Events в отдельный etcd через
--etcd-servers-overrides. - Поставьте etcd на локальные NVMe, отделите его сеть от прикладного трафика.
- Включите и настройте APF, ограничьте QPS шумных клиентов.
- Разверните NodeLocal DNSCache и оцените переход kube-proxy на IPVS/eBPF.
- Если упираетесь в потолок — не растите один кластер, а режьте нагрузку на несколько кластеров.
* Raft — алгоритм консенсуса, при котором группа нод согласует единое состояние через выбранного лидера. Запись считается зафиксированной, когда её подтвердило большинство членов кластера.
Prompt-инженер: Идеальные запросы для Midjourney, ChatGPT и других моделей.
Спросить за 15 ₽Источники: Kubernetes: Considerations for large clusters, etcd: Frequently Asked Questions
Частые вопросы
Обязательно ли делать несколько кластеров вместо одного большого?
Сколько нод должно быть в etcd-кластере?
Почему API-сервер тормозит, хотя ноды не перегружены?
Какой диск нужен под etcd?
Что делать с DNS-лавиной на большом кластере?
Насколько цифры лимитов в статье актуальны?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.