В Kubernetes v1.37 появилась потоковая загрузка данных из etcd, которая снижает потребление памяти

Команда Kubernetes перевела поддержку etcd RangeStream в статус beta в версии Kubernetes v1.37. Новая возможность позволяет API-серверу получать большие наборы данных из etcd потоково, уменьшая пиковое потребление памяти и делая нагрузку на кластер более предсказуемой.

Проблема больших запросов к etcd

API-сервер Kubernetes активно использует кэш наблюдения (watch cache). При запуске или восстановлении этого кэша ему нужно получить полное состояние ресурсов из etcd. В больших кластерах такие операции могут быть ресурсоёмкими: например, когда в кластере много Pod’ов или других объектов.

Ранее Kubernetes уже использовал постраничную загрузку данных из etcd: вместо чтения всей коллекции сразу API-сервер запрашивал фиксированное количество ключей за раз. Однако такой подход не учитывал размер самих объектов. Страница с несколькими крупными объектами могла занимать значительно больше памяти, чем ожидалось.

Кроме того, стандартный вызов Range в etcd сначала полностью собирал ответ в памяти и только затем отправлял его клиенту. В результате одна и та же большая порция данных могла одновременно находиться в памяти etcd и API-сервера во время обработки.

Как работает RangeStream

В etcd версии 3.7 появился новый потоковый RPC-вызов RangeStream. Он использует тот же запрос RangeRequest, но вместо формирования полного ответа сразу разбивает данные на части и отправляет их постепенно.

Размер частей подбирается автоматически в зависимости от объёма возвращаемых данных. Благодаря этому нагрузка ограничивается не количеством ключей, а фактическим размером данных. Обработанные части освобождаются из памяти сразу после передачи, поэтому системе больше не нужно удерживать всю коллекцию целиком.

После включения функции API-сервер использует RangeStream во всех случаях, когда ему нужно получить полную коллекцию объектов из etcd. В первую очередь это касается инициализации кэша наблюдения, а также ситуаций, когда запрос списка (List) нельзя выполнить из кэша и приходится обращаться напрямую к etcd.

Теперь API-сервер декодирует данные по мере поступления очередной части и освобождает память перед загрузкой следующей. В результате ни etcd, ни API-сервер не держат в памяти весь набор объектов одновременно.

Требования и совместимость

Для использования RangeStream нужны:

  • Kubernetes версии 1.37 или новее;

  • etcd версии 3.7 или новее;

  • включённая возможность EtcdRangeStream в kube-apiserver.

В Kubernetes v1.37 эта возможность находится в статусе beta и включена по умолчанию. При необходимости её можно отключить параметром:

--feature-gates=EtcdRangeStream=false

API-сервер при запуске проверяет поддержку RangeStream в используемом экземпляре etcd. Если backend не поддерживает новый RPC-вызов, Kubernetes автоматически возвращается к прежнему механизму постраничного чтения через Range.

Как проверить использование RangeStream

Потоковые чтения отображаются в метриках etcd с отдельной меткой операции:

etcd_request_duration_seconds_count{operation="listStream"}

Если счётчик увеличивается, API-сервер использует новый механизм. Нулевое значение обычно означает, что используется старый вариант чтения через Range — например, из-за версии etcd ниже 3.7.

RangeStream стал частью улучшений Kubernetes v1.37, направленных на работу больших кластеров. Основной эффект от изменения — снижение пикового потребления памяти при операциях со значительными объёмами данных в control plane.

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

Источник: habr.com

0 0 голоса
Рейтинг новости
1
0
Подписаться
Уведомить о
0 комментариев