Получить список объектов через Kubernetes API кажется безобидной операцией. Но в большом кластере один такой запрос может вернуть тысячи объектов и заметно увеличить пиковое потребление памяти.
Где возникает проблема?
API server разбивает большие ответы на страницы, но размер страницы ограничен количеством объектов, а не объёмом данных. Поэтому несколько крупных объектов вполне могут превратить одну страницу в большой объём памяти.
При чтении из etcd такая страница сначала собирается целиком, а затем передаётся API server для обработки:
etcd → API server → декодирование → клиентВ результате один и тот же объём данных на короткое время находится в памяти сразу с двух сторон. Если несколько больших запросов выполняются одновременно, API server может упереться в лимит памяти.
Что меняет RangeStream?
В Kubernetes 1.37 etcd RangeStream получил статус Beta. Вместо целой страницы данные передаются небольшими частями: API server обрабатывает их по мере поступления и освобождает память перед следующей частью.
Большой запрос всё равно остаётся большой операцией, но теперь его размер меньше влияет на пиковое потребление памяти.
Что это даёт на практике?
Особенно полезно помнить об этом при расследовании ситуаций, когда API server внезапно начинает потреблять много памяти. Если память растёт рывками, а явного изменения нагрузки нет, причиной может быть не количество запросов, а размер возвращаемых данных.
Например, оператор регулярно получает список крупного пользовательского ресурса, а несколько таких запросов одновременно создают высокий пик памяти.
В таком случае стоит посмотреть, кто выполняет большие запросы, сколько объектов возвращается и насколько велики сами объекты.
Использование
RangeStream можно проверить по метрике:etcd_request_duration_seconds_count{operation="listStream"}🌐 Подробно о проблеме и механике RangeStream — в разборе Kubernetes.
#kubernetes #devops #et
