Это перевод статьи Frank Denneman Scheduling vSphere Pods. Публикуется с разрешения автора.

В предыдущей статье “Первоначальное размещение vSphere Pod” было рассмотрено внутреннее устройство vSphere Pod, чтобы показать, что он представляет собой комбинацию специализированной виртуальной машины и группы контейнеров. Платформы Kubernetes и vSphere содержат богатый набор элементов управления, политик и функций управления ресурсами, которые контролируют и распределяют ресурсы между рабочими нагрузками. Обе системы управления используют похожие названия подсистем и это вызывает ложное ощущение унификации с точки зрения управления vSphere Pod. В этой серии статей рассматривается наложение различных подсистем управления и то, как новая платформа vSphere 7 позволяет разработчикам использовать знакомые средства управления Kubernetes, в то время как администраторам vSphere — продолжать использовать знакомые средства управления vSphere.

Workload Deployment Process

Разница между процессами развертывания контейнеров и виртуальных машин заключается в их размере. Виртуальная машина определяется ее виртуальным оборудованием, и эта конфигурация действует как граница для гостевой ОС и ее процессов (следовательно, виртуальная машина изолирована и не может выйти за пределы, выделенных ресурсов). Контейнер является контролируемым процессом и использует служебную ОС для управления распределением ресурсов, для этого процесса не может быть задана прямая аппаратная конфигурация. И это различие создает несколько интересных проблем, когда вы хотите запустить контейнер на гипервизоре. Гипервизору требуются понимание рабочих нагрузок для определения их аппаратной конфигурации. Чтобы его планировщик мог управлять рабочими нагрузками и управлять распределением ресурсов между ними. Как оценить рабочую нагрузку, которая не дает вам абсолютно никаких намеков на планируемое потребление ресурсов? Вы можете выбрать произвольную конфигурацию оборудования, но тогда вы можете поломать намерение разработчика, если он или она хочет, чтобы приложение могло “взорваться” и временно использовать больше ресурсов, чем это необходимо обычно. Вы же не хотите диктовать новую парадигму управления ресурсами разработчикам, чтобы им пришлось изменить свои текущие методы развертывания рабочих нагрузок, вы же хотите иметь возможность принимать новые рабочие нагрузки с наименьшим количеством ручного труда. Совместная работа двух Control plane — это не только процесс решения всех этих проблем, но еще и возможность улучшить пользовательский опыт потребителей ресурсов. В этой статье рассматривается различие в поведении планировщиков ресурсов и то, как Request, Limits и политики QoS Kubernetes влияют на размер vSphere Pod. Она начинается с представления конструкций Kubernetes и планировщика Kubernetes для предоставления достаточного количества вводной информации, чтобы потом разобраться, как это все влияет на размер vSphere Pod и его размещение.

Управление вычислительными ресурсами для контейнеров

Контейнер не разворачивается непосредственно на Worker node Kubernetes, он заключен в более высокоуровневую конструкцию называемую Pod. Причиной существования Pod является соображение, что каждый отдельный процесс должен запускаться в своем контейнере. А если приложение состоит из нескольких процессов, то было бы здорово если бы существовала бы группа контейнеров, вы же не хотите управлять процессами независимо, а хотите управлять самим приложением целиком, отсюда и вытекает существование Pod. Так и в чем же подвох? Несмотря на то, что вы развертываете Pod, вы должны задать необходимые ресурсы для каждого контейнера отдельно, а не для всего Pod. Поскольку Pod является атомарной единицей для планировщика, Request всех контейнеров внутри Pod суммируются, и результат используется для выбора Worker node. После размещения Pod планировщик ресурсов Worker node должен уже позаботиться о каждом Request контейнера и ограничить его индивидуально. Но это тема для будущей статьи. Давайте внимательнее посмотрим на Pod манифест.

Сайзинг контейнера versus сайзинг виртуальной машины

Планировщик Kubernetes

Как показано на диаграмме, планировщик должен разместить нагрузку на хосте B. Kubernetes Control plane проверяет все Worker node, выбирает хосты, подходящие для запуска Pod, а затем выбирает хост на основе сконфигурированной prioritization function. Наиболее часто используемой является опция “LeastRequestedPriority”, которая отдает предпочтение Worker node с меньшим количеством уже запрошенных ресурсов. Поскольку Worker node B имеет наименьшее количество зарезервированных ресурсов, планировщик считает этот узел наилучшим кандидатом для выполнения рабочей нагрузки.

Планировщик vSphere

Во время первоначального размещения DRS рассматривает сконфигурированный размер как фактическое потребление, что является наихудшим сценарием. Таким образом, виртуальная машина с 4 vCPU и 16 GB запрашивает до еще включения 4 vCPU и 16 GB плюс накладные расходы на работу виртуальной машины (VM overhead). Тем не менее, если Reservation 8 ГБ, то запрашивается 4 vCPU, 8 GB + VM overhead. На хосте должно быть не менее 8 GB (+ VM overhead) свободных ресурсов доступных для размещения рабочей нагрузки. Чем это отличается от Kubernetes? Ключевое — это принятие во внимание будущего состояния рабочей нагрузки. DRS понимает фактическое потребление ресурсов (и запрошенное) всех других активных рабочих нагрузок, работающих на разных хостах. И, таким образом, DRS имеет точное представление о способности (и возможности) рабочей нагрузки выполнять на каждом хосте. Запрос ресурсов указывает количество ресурсов, которые рабочая нагрузка имеет право использовать, но DRS также может и прогнозировать потребление рабочей нагрузки. Вы бы предпочли разместить новую нагрузку на “забито” рабочими нагрузками хосте или на менее загруженном?

В примере ниже имется три хоста, каждый с 100 GB памяти. На хосте A активна рабочая нагрузка, которая зарезервировала 60 GB памяти. 40 GB памяти не зарезервировано. Хост B и хост C имеют активные рабочие нагрузки, которые зарезервировали 40 GB памяти. 60 GB памяти не зарезервированы. Появляется новая рабочая нагрузка с зарезервированными 35 GB. Планировщик Kubernetes решил бы, что оба хоста одинаково хороши для размещения нагрузки. Однако DRS знает об реальном использовании ресурсов. На хосте B Active Usage 70 GB, а на хосте C — 45 GB. Поскольку использование ресурса хоста B приближается к его полной емкости, DRS выбирает хост C в качестве хоста назначения для первоначального размещения.

Учитывая активное использование ресурсов другими активными потребителями, будь то ВМ или контейнерами в vSphere Pod, получается создать платформу, лучше удовлетворяющую запросы в ресурсах для всех рабочих нагрузок. Если Pod сконфигурирован с Quality of Service, допускающим рост потребления ресурсов (Limit превышает Request), разработчик заявляет, что рабочая нагрузка должна быть в состоянии потреблять больше ресурсов, если доступно. При таком более интеллектуальном начальном размещении (учитывающем реальное потребление), вероятность того, что эта возможность будет реализована значительно увеличивается.

Управление вычислительными ресурсами для vSphere Pod

Классы QoS Kubernetes и их влияние на размер vSphere Pod

Существует три класса QoS, класс BestEffort, класс Burstable и класс Guaranteed. Если никакие Limits и Request не установлены для всех контейнеров в Pod манифесте назначается класс BestEffort. Это означает, что все контейнеры в этом Pod могут потреблять столько ресурсов, сколько они хотят, но они также являются первыми претендентами, которые будут “выселены”, если произойдет нехватка ресурсов. Если все контейнеры в Pod манифесте содержат Request и для CPU и для памяти и этот Request равен Limits, то Kubernetes назначит этому Pod Guaranteed класс QoS. Guaranteed pod — это последние кандидаты, которые будут “ущемлены” в ресурсах в случае нехватки ресурсов. Любая другая мыслимая комбинация Request и Limits процессора и памяти гарантирует, что Kubernetes назначит класс Burstable. Важно не нарушать ожидаемое поведение выдачи и возврата ресурсов, Request и Limits, указанные в Pod манифесте, используются в для определения размера vSphere Pod чтобы обеспечить ожидаемое поведение.

Если для контейнера не установлен Limits, как vSphere должна это интерпретировать чтобы определить размера vSphere Pod? Для предотвращения создания vSphere Pod размером в целый хост введен размер контейнера по умолчанию. Который устанавливается на каждый контейнер. Если быть точным, если создать самый простой Pod с одним контейнером и без параметров Request /Limits , то vSphere Pod получит 1 vCPU и 512 MB. По умолчанию контейнер получает 0.5 ядра, но если в Pod только один контейнер, то мы округляем до 1 vCPU. Почему размер выбирается не на основе Pod? Просто из соображений масштабируемости — размер Pod может увеличиваться в зависимости от количества BestEffort контейнеров внутри. Если задан Request или Limits, превышающее размер по умолчанию, этот показатель используется для определения размера контейнера. Если Pod манифест содержит несколько контейнеров, добавляется наибольшая из метрик каждого контейнера, и результат сложения используется в качестве размера vSphere Pod. Например, Pod содержит два контейнера, каждый с Request и Limits, превышающими размер контейнера по умолчанию. CPU Limits превышает размер CPU Request, в результате vSphere использует сумму обоих CPU Limits и добавляет небольшие запасы для компонентов, отвечающих за жизненный цикл Pod, конфигурацию Pod и взаимодействие vSpherelet. Аналогичный расчет будет сделан и для памяти.

Первоначальное размещение контейнеров в vSphere Pod на vSphere с Kubernetes

Освобождение ресурсов

Namespaces

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

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