Многоликий controller-manager и бесчисленные api-server’ы

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Что делать, когда кластер превращается в тыкву? На этот вопросы мы начали отвечать в предыдущей статье. Сегодня продолжим разбирать способы построения кластеров большого объема.

Первым шагом dBrain.cloud на пути к построению кластеров большого объема стало разделение etcd. Далее мы взялись за controller-manager.

Как не тратить время на сбор мусора?

У controller-manager’ов есть флажок “controllers”. Внутри находится много контроллеров, каждый из которых отвечает за свои объекты: репликасеты, поды и др. При запуске controller-manager горизонтально не скейлится. Пример: есть три реплики controller-manager’ов, они между собой выбирают мастера - и в итоге работает только один.

Какие функции выполняет controller-manager? Он сверяет состояние кластера с эталонным. Controller-manager постоянно ходит по кластеру и сличает текущее состояние с тем, которое записано в etcd, Kubernetes и т.д. Controller-manager проверяет все описания объектов в Kubernetes и ищет, где остались объекты без владельца, то есть динамически созданные Kubernetes, а не пользователями. На одном из наших высоконагруженных проектов с более чем 100 тысячами подов, мы столкнулись с тем, что controller-manager 90 процентов времени тратил на garbage collection. У него просто не было времени заниматься своей непосредственной работой: проверять количество подов, реплики деплойментов, сервисы, записывать адреса и т.д.

Благодаря флажку “controllers” мы разделили controller-manager на три кластера. Вышло как с etcd: три кластера по три controller-manager в каждом, при этом один из них - мастер. Таким образом, у нас получилось три параллельно работающих и выполняющих разные задачи инстанса controller-manager.

Теперь схема работы controller-manager’ов выглядит так: первый взял на себя всю рабочую нагрузку: ReplicaSet, Services, Deployments, StatefulSet и др., второй - garbage collection, просчет ttl и т.д., третий - все остальное: node, pv, pvc, certs и т.д.

Так мы повысили отзывчивость кластера на различные изменения. Garbage collection происходит в отдельном controller-manager, процесс может идти непрерывно, теперь это не влияет на работу кластера.

HPA для регулировки нагрузки и envoy

В dBrain, как и везде, api-серверы находятся в статик-подах и используются сейчас как бутстрапные для того, чтобы запустились кластеры, оверлейная сеть и основные api-серверы - в деплойменте. Их сертификаты мы поместили в секреты Kubernetes, теперь api-серверы могут шедулиться по всему кластеру, а не находиться статически на каких-то нодах. Благодаря таким манипуляциям появляются все плюсы Kubernetes в виде фенси автоскейлинга и отказоустойчивости. Сейчас на api-серверах в dBrain мы настроили HPA (Horizontal Pod Autoscaler), они автоматически скейлятся в зависимости от утилизации. Надеемся, вам будет полезен наш лайфхак :)

В dBrain есть envoy (L4-L7-прокси), который живет на каждом хосте. Он работает как прокси на статик-поды api-серверов и на api-серверы в деплойментах и реализует доступность kube api на всех хостах кластера, чтобы kubelet’ы, controller-manager-ы и scheduler могли работать. И здесь встает извечный вопрос: чтобы было раньше - курица или яйцо? Кластер должен подняться, а для этого нужны работающие api-серверы. Если api-серверы в деплойменте, то кластер не поднимется. Поэтому в envoy реализованы приоритеты по хелсчекам, если api-серверы в гибко скейлящемся горизонтально деплойменте доступны - весь траффик идет на них, в противном случае - на api-серверы в статик-подах.

В платформе более ранних версий у нас был envoy, через который системные компоненты Kubernetes ходили на api-серверы в статик-подах. Раньше api-серверы в деплойментах обрабатывали запросы исключительно изнутри кластера (с сервиса kubernetes.default.svc), также к ним подключались пользователи, которые работают с кластером. Системные же компоненты работали исключительно с api-серверами в статик-подах.

Что касается scheduler, то его, в отличие от controller-manager, скейлить не надо. Scheduler в одном экземпляре, это компонент, который не испытывает постоянной нагрузки и работает около событийно. Например, на больших кластерах он не выгребает все хосты, в попытках что-то куда-то зашедулить. Он берет по дефолту около 10 процентов хостов и пытается зашедулить поды на них, если не получилось, берет следующие 10 процентов и так далее.

Подведем итог: с помощью разделения etcd и controller-manager мы можем работать с большими кластерами так же быстро как с маленькими. Благодаря двум действиям мы смогли устранить проблемы, которые при росте объема кластера приводили к его неадекватной работе и другим побочным действиям.

Теперь у нас кластер любого размера гораздо отзывчивее: его части перестали влиять друг на друга. При администрировании кластера через kubectl компонент не лагает вне зависимости от размера кластера. Сервисы, завязанные на ресурсы самого Kubernetes, стали отрабатывать мгновенно. Идем к 200 тысячам подов в кластере, не переключайтесь ;)

Если вы нашли нашу статью полезной, поделитесь ей со своими коллегами или друзьями - вовлечение и прочтение материалов заряжают нас энтузиазмом для поиска и раскрытия новых интересных тем для вас.

Источник: https://habr.com/ru/companies/dbraincloud/articles/799573/


Интересные статьи

Интересные статьи

В этот раз у DotNext непривычный формат: сначала два дня в онлайне, а позже офлайн-день в Петербурге (первая за два года возможность встретиться на DotNext очно!) Для тех, кто не может добраться до Пи...
Постоянные читатели моих обзоров уже привыкли, что каждая статья посвящена одному девайсу, реже участвуют отличающиеся комплектацией устройства одной модели. Сегодня я нарушу эту традицию и расскажу...
Принцип единственности отвественности? Что именно вы имеете ввиду? Читать далее
Создать приложение для резервного копирования, работающее на любом дистрибутиве — задачка не простая. Чтобы обеспечить работу Veeam Agent for Linux на дистрибутивах от Red Hat 6 и Debian 6, д...
В 1985 году Алексей Пажитнов и Вадим Герасимов выпустили в свет Tetris. Эта увлекательная и вызывающая сильное привыкание игра требовала от игроков соединять фигуры, появлявшиеся в случайном по...