Блог Amazon Web Services
Разработка архитектуры для оптимизации затрат и устойчивости на базе EKS с использованием спотовых инстансов
Оригинал статьи: ссылка (Ben Peven и Chris Foote, Sr. EC2 Spot Specialist Solutions Architect)
Запуск Kubernetes и контейнеризированных рабочих нагрузок на спотовых инстансах Amazon EC2 — это отличный способ сократить расходы. Kubernetes — это популярная система управления контейнерами с открытым исходным кодом, которая позволяет развёртывать контейнеризированные приложения и управлять ими в больших масштабах. AWS облегчает запуск Kubernetes с помощью Amazon Elastic Kubernetes Service (EKS) — управляемого сервиса Kubernetes для запуска на AWS рабочих нагрузок, предназначенных для промышленной эксплуатации. Чтобы оптимизировать затраты на запуск таких рабочих нагрузок, запускайте их на спотовых инстансах. Спотовые инстансы доступны со скидками до 90% в сравнении с ценами на инстансы по требованию. Эти инстансы лучше всего подходят для различных отказоустойчивых приложений, не зависящих от типов инстансов. Спотовые инстансы и контейнеры являются отличной комбинацией, так как контейнеризированные приложения часто не имеют состояния и не зависят от типов инстансов.
В этой статье я покажу лучшие практики использования спотовых инстансов, такие, как диверсификация, автоматическая обработка спотовых прерываний и использование Amazon EC2 Auto Scaling для получения вычислительных ресурсов. Затем вы адаптируете эти лучшие практики использования спотовых инстансов к EKS для оптимизации затрат и повышения устойчивости контейнеризированных рабочих нагрузок.
Обзор спотовых инстансов
Спотовые инстансы — это неиспользуемые вычислительные ресурсы Amazon EC2, которые позволяют клиентам экономить до 90% в сравнении с ценами на инстансы по требованию. Спотовые инстансы разделены на спотовые группы, определяемые типом инстанса, зоной доступности (Availability Zone, AZ) и регионом AWS. Цены на спотовые инстансы постепенно корректируются в зависимости от долгосрочных тенденций спроса и предложения на спотовые инстансы определенной спотовой группы, как показано ниже:
Когда сервис EC2 нуждается в ресурсах, служба спотовых инстансов посылает уведомления о прерывании работы произвольным инстансам, входящих в соответствующую спотовую группу. Эти уведомления о прерывании становятся доступными в EC2-метаданных инстанса, а также отправляются в Amazon Eventbridge. Через две минуты после уведомления о прерывании спотовый инстанс завершает работу. Вы можете настроить свою инфраструктуру на автоматизацию ответа на это двухминутное уведомление. Примерами могут служить безопасный перенос контейнеров на другие рабочие узлы, безопасный разрыв соединений балансировщика нагрузки или постобработка.
Независимость от типов инстансов важна при использовании лучших практик использования спотовых инстансов, поскольку позволяет использовать спотовые инстансы из различных спотовых групп. Использование нескольких спотовых групп помогает снизить количество прерываний в зависимости от выбранной стратегии распределения спотовых инстансов и уменьшить общее время, потраченное на запуск инстансов. Использование нескольких спотовых групп с разными типами инстансов в нескольких зонах доступности также позволяет достичь желаемого масштаба — даже для приложений, требующих 500 тысяч одновременных процессорных ядер:
Количество спотовых групп = (количество зон доступности) * (количество типов инстансов)
Если ваше приложение развернуто в двух зонах доступности и использует только один тип инстансов c5.4xlarge, то вам доступны (2 * 1 = 2) две спотовые группы. Следуя лучшим практикам использования спотовых инстансов, лучше использовать шесть зон доступности и разрешить вашему приложению использовать типы инстансов c5.4xlarge, c5d.4xlarge, c5n.4xlarge, и c4.4xlarge. Это даёт нам (6 * 4 = 24) 24 спотовых группы, что значительно повышает стабильность и устойчивость вашего приложения.
EC2 Auto Scaling поддерживает развёртывание приложений с использованием нескольких типов инстансов и автоматически заменяет инстансы в случае сбоя в работе или завершения работы из-за спотового прерывания. Чтобы снизить вероятность прерывания, используйте стратегию распределения спотовых инстансов, оптимизированную для использования наиболее свободных групп. Эта стратегия автоматически запускает спотовые инстансы в наиболее свободных спотовых группах, отслеживая данные об их загрузке в режиме реального времени и определяя, какие из них являются наиболее свободными.
Теперь, когда я рассказал о лучших практиках использования спотовых инстансов, вы можете применить их для разработки архитектуры для EKS на спотовых инстансах.
Архитектура решения
Цели этой архитектуры таковы:
- Автоматическое масштабирование рабочих узлов кластеров Kubernetes для соответствия потребностям приложения.
- Использование спотовых инстансов для оптимизации затрат на запуск рабочих нагрузок на Kubernetes.
- Адаптация лучших практик использования спотовых инстансов (например, диверсификации) к EKS и Cluster Autoscaler.
Вы достигнете этих целей с помощью следующих компонентов:
Компонент | Роль | Детали | Метод развёртывания |
Cluster Autoscaler | Автоматически масштабирует EC2 инстансы в соответствии с требованиями приложений, запущенных в кластере | Открытый код | Deployment на инстансах по требованию |
Группа EC2 Auto Scaling | Запускает и поддерживает необходимое количество EC2 инстансов | AWS | CloudFormation через eksctl |
AWS Node Termination Handler | Обнаруживает спотовые прерывания и автоматически безопасно завершает работу узлов | Открытый код | DaemonSet через Helm на спотовых инстансах |
Эта архитектура разворачивает рабочие узлы EKS в трех зонах доступности и использует три группы EC2 Auto Scaling — две для спотовых инстансов и одну для инстансов по требованию. Kubernetes Cluster Autoscaler развёртывается на рабочих узлах на инстансах по требованию, а AWS Node Termination Handler — на всех рабочих узлах.
Дополнительная информация о взаимодействии Kubernetes с группами EC2 Auto Scaling:
- Cluster Autoscaler управляет масштабированием рабочих узлов путём изменения параметра DesiredCapacity у групп EC2 Auto Scaling, а так же принудительно завершая работу инстансов. Группы EC2 Auto Scaling используются для получения ресурсов, и автоматической замены инстансов в случае сбоя в работе или завершения работы из-за спотового прерывания.
- Cluster Autoscaler развёртывается как deployment одного pod на одном из инстансов в группе EC2 Auto Scaling на инстансах по требованию. Предыдущая диаграмма для примера показывает Cluster Autoscaler в зоне доступности AZ1.
- Каждая группа узлов соответствует одной группе EC2 Auto Scaling. Однако, Cluster Autoscaler требует, чтобы все инстансы в группе рабочих узлов имели одинаковое количество vCPU и одинаковый объем оперативной памяти. Чтобы придерживаться лучших практик использования спотовых инстансов и максимизировать диверсификацию, используйте несколько групп рабочих узлов. Каждая из этих групп рабочих узлов представляет собой группу EC2 Auto Scaling для инстансов различных типов с настроенной стратегией распределения спотовых инстансов, оптимизированной для использования наиболее свободных групп.
Автоматическое масштабирование кластера Kubernetes
Существует два стандартных способа масштабирования кластеров Kubernetes:
- Horizontal Pod Autoscaler (HPA) масштабирует pods в Deployment или ReplicaSet в соответствии с требованиями приложения. Правила масштабирования зависят от загрузки процессора или других пользовательских метрик.
- Cluster Autoscaler (CA) — отдельная программа, которая изменяет размер кластера Kubernetes в зависимости от текущих требований ресурсов. Она увеличивает размер кластера при наличии pods, которые не смогли запуститься ни на одном из текущих рабочих узлов из-за нехватки ресурсов. Она также пытается удалить низко загруженные узлы, когда pods, запущенные на этих узлах, могут быть перенесены на другие узлы.
Когда pod не может быть запущен из-за нехватки доступных ресурсов, Cluster Autoscaler определяет, что необходимо увеличить размер кластера и после этого увеличивает размер группы рабочих узлов. Когда используется несколько групп рабочих узлов, Cluster Autoscaler выбирает одну из них, основываясь на конфигурации Expander. В настоящее время поддерживаются следующие стратегии: random, most-pods, least-waste и priority.
В этом примере вы используете random стратегию для Cluster Autoscaler. Это — стратегия по умолчанию, и она произвольно выбирает группу рабочих узлов, когда кластер должен масштабироваться. Random стратегия максимизирует возможность использования несколько спотовых групп. Однако, вы можете попробовать и другие стратегии, одна из них может оказаться более подходящей для вашей рабочей нагрузки.
Atlassian Escalator:
Escalator — это альтернатива Cluster Autoscaler для пакетных рабочих нагрузок. Escalator предназначен для больших блоков вычислений или рабочих нагрузок, которые не могут быть остановлены или прерваны для перемещения на другие рабочие узлы, когда необходимо уменьшить размер кластера.
Группы EC2 Auto Scaling
Следование лучшим практикам использования спотовых инстансов означает развертывание инстансов различных типов и размеров в нескольких зонах доступности. EC2 Auto Scaling является одним из лучших механизмов для достижения этой цели. Группы EC2 Auto Scaling автоматически заменяют спотовые инстансы, которые были остановлены из-за прерывания, на инстанс из другой спотовой группы.
Группы EC2 Auto Scaling поддерживают запуск инстансов разных типов и размеров в одной группе. Для примера, в этой статье было выбрано соотношение 1:4 vCPU к памяти для всех типов инстансов, но у вашего приложения могут быть другие требования. Ниже приведены типы инстансов, выбранные для двух групп EC2 Auto Scaling:
- Группа 4vCPU / 16GB: m5.xlarge, m5d.xlarge, m5n.xlarge, m5dn.xlarge, m5a.xlarge, m4.xlarge
- Группа 8vCPU / 32GB: m5.2xlarge, m5d.2xlarge, m5n.2xlarge, m5dn.2xlarge, m5a.2xlarge, m4.2xlarge
В этом примере я использую в общей сложности 12 различных типов инстансов и три разных зоны доступности, что даёт мне (12 * 3 = 36) 36 различных спотовых группы. Группа EC2 Auto Scaling выбирает, какие типы инстансов будут запущены на основе стратегии распределения спотовых инстансов. Чтобы снизить вероятность прерывания, я использую стратегию распределения спотовых инстансов, оптимизированную для использования наиболее свободных групп. Эта стратегия автоматически запускает спотовые инстансы в наиболее свободных спотовых группах, отслеживая данные об их загрузке в режиме реального времени и определяя, какие из них являются наиболее свободными.
Для Cluster Autoscaler и других административных приложений, а также рабочих нагрузок с сохранением состояния, запускаемых на рабочих узлах EKS, создается третья группа EC2 Auto Scaling с использованием инстансов по требованию. Это гарантирует, что Cluster Autoscaler не будет зависеть от спотовых прерываний. В Kubernetes, labels и nodeSelectors могут использоваться для управления размещением pods. Используйте nodeSelector для размещения Cluster Autoscaler на рабочем узле из группы EC2 Auto Scaling с использованием инстансов по требованию.
Примечание: Группы EC2 Auto Scaling постоянно пытаются сбалансировать количество инстансов во всех зонах доступности, в которых они развернуты. Это может привести к остановке инстансов, если во время масштабирования группы EC2 Auto Scaling она оказалась несбалансированной между зонами доступности. Эту функцию можно отключить, приостановив процесс AZRebalance, но это может привести к тому, что группа EC2 Auto Scaling станет несбалансированной. Другой возможностью является использование инструмента для безопасного завершения работы инстансов при масштабировании группы EC2 Auto Scaling, например, EKS Node Drainer. EKS Node Drainer — это функция AWS Lambda, которая интегрируется как EC2 Auto Scaling Lifecycle Hook. При вызове эта функция Lambda вызывает Kubernetes API для блокировки остановки инстанса и переноса всех pods с останавливаемого узла на другие рабочие узлы кластера. Затем она ждет окончания переноса всех pods с останавливаемого узла на другие рабочие узлы кластера, и снимает блокировку, чтобы группа EC2 Auto Scaling могла завершить остановку инстанса.
Обработка прерываний спотовых инстансов
Чтобы минимизировать последствия возможных прерываний спотовых инстансов, используйте обработчик остановки узлов (AWS Node Termination Handler). При его развёртывании, DaemonSet запускает pod с обработчиком для обнаружения уведомления о спотовом прерывании на каждом спотовом инстансе, что позволяет как безопасно остановить работу pods, работавших на этом узле, так и исключить его из балансировщиков нагрузки и позволить Kubernetes перенести pods на другие рабочие узлы кластера.
Процесс можно обобщить следующим образом:
- Обнаружение уведомления об остановке спотового инстанса через два минуты.
- Использование двухминутного интервала для подготовки рабочего узла к остановке.
- Маркировка узла для предотвращения запуска на нём новых pods.
- Исключение рабочего узла из кластера.
В результате:
- Контроллеры, которые управляют объектами K8s, такими как Deployments и ReplicaSet, обнаружат, что один или несколько pods недоступны, и запустят их на других узлах.
- Cluster Autoscaler и группа EC2 Auto Scaling при необходимости запустят новые инстансы.
Пошаговое руководство
Запуск EKS
В первую очередь, используйте eksctl для создания кластера EKS с именем spotcluster-eksctl
в сочетании с группой управляемых узлов. Группа управляемых узлов будет состоять из двух инстансов по требованию типа t3.medium и создастся с метками lifeecycle=OnDemand
и intent=control-apps
. Обязательно замените <YOUR REGION>
на регион, в который вы запускаете свой кластер.
Это займёт примерно 15 минут. Как только создание кластера будет завершено, проверьте подключенные рабочие узлы:
Создание рабочих узлов
Используйте eksctl create nodegroup и конфигурационные файлы eksctl для добавления новых рабочих узлов в кластер. Сначала создайте файл конфигурации spot_nodegroups.yml
. Затем вставьте этот код и замените <YOUR REGION>
на регион, в котором вы запустили кластер EKS.
Данный конфигурационный файл добавляет две диверсифицированные группы рабочих узлов на спотовых инстансах типов 4vCPU/16GB и 8vCPU/32GB. Эти группы узлов используют стратегию распределения спотовых инстансов, оптимизированную для использования наиболее свободных групп, как описано выше. Наконец, все узлы помечаются жизненным циклом инстансов (lifecycle) «Ec2Spot», что в дальнейшем позволит развёртывать приложения на этих узлах, используя фильтр nodeSelectors. Чтобы создать обе группы узлов, запустите:
Это займёт примерно три минуты. После этого проверьте, что узлы были добавлены в кластер:
Развёртывание обработчика остановки узлов
Вы можете установить .yaml файл из официального репозитория GitHub командой:
Это устанавливает обработчик установки узлов как на рабочие узлы на спотовых инстансах, так и на рабочие узлы на инстансах по требованию, что полезно, так как обработчик реагирует как на события обслуживания EC2, так и на спотовые прерывания. Однако, если вы заинтересованы в развертывания обработчика только на узлах на спотовых инстансах, в репозитории есть инструкции для выполнения этой задачи.
Убедитесь, что обработчик остановки узлов запущен:
Развёртывание Cluster Autoscaler
Подробную информацию можно найти на странице EKS здесь. Выполните экспорт конфигурации Cluster Autoscaler в файл следующей командой:
Откройте созданный файл и отредактируйте команду развёртывания контейнера cluster-autoscaler
, заменив <YOUR CLUSTER NAME>
на имя вашего кластера, а также добавьте следующие опции:
Также необходимо изменить конфигурацию Expander. Найдите - --expander=
и замените least-waste
на random
.
Пример:
Сохраните файл, а затем установите Cluster Autoscaler командой:
Далее добавьте аннотацию cluster-autoscaler.kubernetes.io/safe-to-evict
к установленному Cluster Autoscaler следующей командой:
Откройте страницу с релизами Cluster Autoscaler в веб-браузере и найдите последнюю версию Cluster Autoscaler, которая соответствует основной и второстепенной версии Kubernetes вашего кластера. Например, если версия Kubernetes вашего кластера 1.16, найдите последнюю версию Cluster Autoscaler, которая начинается с 1.16.
Установите тег образа Cluster Autoscaler на эту версию, используя следующую команду, заменив 1.15.n
на значение найденной версии. Вы также можете заменить us
на asia
или eu
:
Чтобы просмотреть логи Cluster Autoscaler, используйте следующую команду:
Развёртывание макета приложения
Создайте файл web-app.yaml
, вставьте в него следующую спецификацию и сохраните файл:
Эта спецификация развёртывает три копии приложения «web-stateless», которые размещаются в одной из групп рабочих узлов на спотовых инстансах так, как nodeSelector
выбирает узлы, помеченные lifecycle: Ec2Spot
. Приложение «web-stateful» не является отказоустойчивыми и поэтому не подходит для развертывания на узлах на спотовых инстансах, поэтому для него снова используется nodeSelector
и выбираются узлы, помеченные lifecycle: OnDemand
. Архитектура, в которой вы размещаете на спотовых инстансах приложения, способные переживать прерывания, а на инстансах по требованию — остальные приложения, также может быть использована и для создания многопользовательских (multi-tenant) кластеров.
Разверните приложения следующей командой:
Убедитесь, что оба приложения запущены:
Теперь, отмасштабируйте «web-stateless» приложение до 30 копий:
Убедитесь, что не все копии приложения смогли запуститься. Подождите примерно 5 минут и проверьте, что все копии запустились:
Удаление использованных ресурсов
Удалите обработчик остановки узлов:
Удалите две группы EC2 Auto Scaling на спотовых инстансах, которые были развернуты ранее:
Если вы создали новый кластер, а не использовали существующий, удалите кластер EKS:
eksctl немедленно подтверждает удаление стека CloudFormation, но само удаление может занять до 15 минут. Вы можете отследить удаление в консоли CloudFormation.
Выводы
Следуя лучшим практикам, рабочие нагрузки Kubernetes могут быть развернуты на спотовых инстансах, обеспечивая как отказоустойчивость, так и оптимизацию затрат. Независимость приложений от типов инстансов и зон доступности является краеугольным камнем для использования нескольких спотовых групп и обеспечения необходимого масштаба развёртывания приложения. Кроме того, существуют заранее созданные инструменты для обработки прерываний спотовых инстансов, если таковые происходят. EKS облегчает поддержку подобных сценариев, снижая эксплуатационные затраты, предлагая масштабируемую и высокодоступную плоскость управления и управляемые группы рабочих узлов. Теперь вы готовы приступить к использованию спотовых инстансов для кластеров Kubernetes, чтобы снизить затраты на свои рабочие нагрузки и обеспечить необходимый масштаб развёртывания приложений.