- PVSM.RU - https://www.pvsm.ru -

В Asana мы используем Kubernetes для развертывания сервисов и управления ими независимо от монолитной инфраструктуры. Поначалу у нас были некоторые проблемы, и чтобы стандартизировать создание и обслуживание приложений Kubernetes, мы создали фреймворк с незамысловатым названием KubeApps. В последние два года наша команда по инфраструктурной платформе вносила улучшения в KubeApps, чтобы упростить развертывание сервисов в Asana. Здесь мы расскажем, какие проблемы мы хотели решить в Kubernetes и как мы это сделали с помощью фреймворка KubeApp.
Мы уже рассказывали о legacy-системе деплоймента [1] в Asana — наша основная инфраструктура организована как монолит инстансов AWS EC2 с кастомными скриптами конфигурации для каждого сервиса. Никакого масштабирования у нас не было: отправляешь новый код в монолит — переконфигурируй все хосты. Чтобы добавить новый сервис, нужен был новый набор кастомных скриптов конфигурации. Все это было сложно обслуживать, плюс был риск увеличить нестабильность деплоев в монолите.
Когда мы обдумывали инфраструктуру для Luna2 [2], решили использовать Kubernetes, чтобы деплоить сервисы и управлять ими независимо от монолита. Оркестрация контейнеров пошла хорошо, и остальные инженеры захотели использовать Kubernetes для других систем Asana. Мы доработали эти инструменты, чтобы и другие команды могли собирать и деплоить сервисы в контейнерах.
С Kubernetes управлять сервисами стало гораздо проще, ведь у нас есть четкие границы между процессами и окружениями, где они выполняются. В итоге разработчики приложений могут собирать и обновлять одни сервисы, не боясь навредить другим.
Расширять инфраструктуру за пределы монолита EC2 стало, конечно, проще, но Kubernetes пока не решал всех наших проблем (примечание: В Kubernetes есть Cloud Controller Manager [3], который управляет нодами, настраивает маршруты между контейнерами и интегрируется с компонентами облачной инфраструктуры).
Чтобы решить эти проблемы и стандартизировать создание и обслуживание приложений Kubernetes, мы создали фреймворк с незамысловатым названием KubeApps. Изначально мы задумали KubeApp для обработки всех аспектов развертывания — от сборки необходимых ресурсов до обновления DNS во время деплоя и плавного перехода между версиями кода. Каждый KubeApp определяется набором требований к «железу», определений подов и спецификаций сервиса.
Все конфигурации KubeApp существуют в виде Python-кода, поэтому поддерживают программно созданные конфигурации и обеспечивают согласованность с помощью общих библиотек. С этими конфигурациями мы можем объявлять и настраивать внешние ресурсы, необходимые для KubeApp.
На схеме показаны спецификации примера веб-приложения и способ его представления в системе конфигурации KubeApp. Деплоймент запрашивает оборудование, ELB и сборки образов. Мы предоставляем дефолтные спецификации для обработки конфигураций DNS и включаем определения подов для обработки метрик и логирования.
Код приложения пакуется в Docker-образы с помощью образов Bazel или традиционных Dockerfile. Наш KubeApps собирает и отправляет эти образы в рамках пайплайна CD, так что образы для любого сервиса доступны в нашем registry.
Для сборки зависимостей и управления ими в большинстве случаев мы используем Bazel [4]. Это особенно удобно с контейнеризованными приложениями, потому что таким образом мы объявляем зависимости и упаковываем сторонние библиотеки в исполняемые файлы. Так мы получаем детерминированные выходные данные при настройке контейнерных окружений для каждого приложения.
При использовании Kubernetes нужно решить, как делить сервисы между кластерами (примечание: некоторые соображения о компромиссах при выборе числа кластеров приводятся в этой статье на learnk8s.io: Проектирование кластеров Kubernetes: сколько их должно быть? [5]). Деплоить сервисы в один кластер Kubernetes — это экономично и удобно в плане администрирования, потому что сервисы используют одни ресурсы мастер-ноды, а такие операции, как апгрейд версий Kubernetes и деплойменты, нужно выполнять всего один раз. Но модель с одним кластером не особо хороша для мультитенантности, а кластер становится единой точкой отказа. Один кластер Kubernetes ограничен в плане масштабирования, так что при достижении определенного размера неплохо было бы его разделить.
В Asana каждый KubeApp деплоится в своем кластере Kubernetes через AWS EKS. Такой подход гарантирует безопасность и устойчивость приложения. Каждый кластер отвечает за один сервис, так что можно не волноваться о состязании за ресурсы между сервисами, а если кластер упадет, пострадает всего один сервис.
Управлять несколькими кластерами сложновато, потому что дефолтные инструменты Kubernetes могут взаимодействовать только с одним кластером за раз. Поэтому мы создали инструменты для управления несколькими кластерами одновременно в KubeApps. Еще мы обнаружили, что такая модель позволяет владельцам отдельных KubeApp независимо управлять кластером (апгрейдить ноды, масштабировать деплои и т. д.)

Для развертываний KubeApp мы используем центральный хаб управления, который мы назвали kubecontrol. Его можно настроить для обновления вручную или автоматически, через cron. Развертывание KubeApp включает несколько шагов:
Полное обновление KubeApps — это blue-green деплой, для которого нужно запустить и настроить новый кластер EKS в AWS. Убедившись, что новый KubeApp работает, мы переключаем нагрузку на новый кластер и сносим старый. В KubeApps можно делать rolling апдейт, при котором обновляются образы на запущенном кластере. Это позволяет быстро и незаметно переходить с одной версии кода на другую без запуска целого нового кластера.
До недавнего времени единственным способом прямого мониторинга или управления KubeApp было ssh-подключение к kubecontrol и взаимодействие с приложением через CLI. Искать информацию о деплоях было непросто, так что пользователям приходилось изучать логи, чтобы понять, когда в KubeApp была развернута определенная версия кода. Чтобы внести больше ясности, мы создали KubeApp Management Console (KMC), которая отвечает за запись информации о прошлых деплоях. Мы хотим использовать эту консоль как централизованный веб-интерфейс, в котором пользователи могут взаимодействовать с KubeApps.
Сейчас у нас больше 60 KubeApp в Asana, которые поддерживают самые разные рабочие нагрузки — от управления релизами [6] до распределенного кэширования [7]. Пока мы сохраняем монолит инстансов EC2, но уже переделываем эти сервисы в контейнеры в KubeApps.
Команда инфраструктурной платформы продолжает активную работу над KubeApps. В будущем мы планируем поддерживать больше архитектур (ARM64) и провайдеров инфраструктуры (AWS Fargate). Еще мы планируем создать инструменты для более удобной разработки в KubeApps, чтобы их можно было запускать в песочницах и локальных окружениях. Благодаря этим и другим изменениям фреймворк KubeApps можно будет приспособить для любой рабочей нагрузки, которая может нам понадобиться.
Автор: Polina_Averina
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/blog-kompanii-southbridge/363854
Ссылки в тексте:
[1] legacy-системе деплоймента: https://blog.asana.com/2017/06/asana-server-deployment-pragmatic-approach-maintaining-legacy-deployment-system/
[2] Luna2: https://blog.asana.com/2017/08/performance-asana-app-rewrite/
[3] Cloud Controller Manager: https://kubernetes.io/docs/concepts/architecture/cloud-controller/
[4] Bazel: https://bazel.build/
[5] Проектирование кластеров Kubernetes: сколько их должно быть?: https://learnk8s.io/how-many-clusters
[6] управления релизами: https://blog.asana.com/2021/01/asana-engineering-ships-web-application-releases/
[7] распределенного кэширования: https://blog.asana.com/2020/09/worldstore-distributed-caching-reactivity-part-1/#close
[8] Источник: https://habr.com/ru/post/555524/?utm_source=habrahabr&utm_medium=rss&utm_campaign=555524
Нажмите здесь для печати.