Хабрахабр

[Перевод] Как и зачем мы мигрировали Preply в Kubernetes

В этой статье я опишу наш опыт миграции Preply в Kubernetes, как и почему мы это сделали, с какими трудностями столкнулись и какие преимущества приобрели.

Kubernetes ради Kubernetes? Нет, бизнес-требования!

Многие люди говорят что он решит все проблемы, некоторые утверждают, что скорее всего, Kubernetes вам не нужен. Вокруг Kubernetes много хайпа и это неспроста. Истина конечно находится где-то посередине.

Сейчас же я расскажу немного о наших бизнес-требованиях и как Preply работал до миграции в Kubernetes: Однако все эти рассуждения о том где и когда нужен Kubernetes, достойны отдельной статьи.

  • Когда мы использовали Skullcandy flow у нас было множество веток, все они мержились в общую ветку под названием stage-rc, деплоились на стейдж. Команда QA тестировала это окружение, после тестирования ветка мержилась в мастер и мастер деплоился на прод. Вся процедура занимала порядка 3-4 часов и у нас получалось деплоиться от 0 до 2 раз в день
  • Когда мы деплоили сломанный код на прод, нам приходилось откатывать все изменения вошедшие в последний релиз. Также было сложно найти, какое именно изменение сломало нам прод
  • Мы использовали AWS Elastic Beanstalk для хостинга нашего приложения. Каждый деплой Beanstalk в нашем случае занимал 45 минут (весь пайплайн вместе с тестами отрабатывал за 90 минут). Откат на предыдущую версию приложения занимал 45 минут

Для улучшения нашего продукта и процессов в компании мы хотели:

  • Разбить монолит на микросервисы
  • Деплоиться быстрее и чаще
  • Откатываться быстрее
  • Сменить наш процесс разработки, потому что мы его считали более не эффективным

Наши потребности

Изменяем процесс разработки

В нашем подходе с конфигурацией приложения в Elastic Beanstalk сделать это было сложно и дорого. Для внедрения наших нововведений со Skullcandy flow нам нужно было создавать динамическое окружение для каждой ветки. Нам хотелось создавать окружения которые бы:

  • Быстро и легко деплоились (желательно чтобы это были контейнеры)
  • Работали на спот-инстансах
  • Были максимально похожи на прод

С его помощью, каждая фича имеет отдельную ветку, которая независимо от остальных может мержиться в мастер. Мы решили переехать на Trunk-Based Development. Мастер-ветка может деплоиться в любое время.


git-flow и Trunk-Based Development

Деплоимся быстрее и чаще

Это существенно помогло нам в процессе поиска сломаного кода в проде и его откате. Новый Trunk-Based процесс позволил нам быстрее доставлять нововведения в мастер-ветку одну за другой. Однако, время деплоя все еще составляло 90 минут, а время отката — 45 минут, из-за этого мы не могли деплоиться чаще 4-5 раз в день.

Наиболее очевидным решением являлось использование контейнеров и инструмента для их оркестрации. Также мы столкнулись с трудностями при использовании сервисной архитектуры на Elastic Beanstalk. К тому же у нас уже был опыт использования Docker и docker-compose для локальной разработки.

Следующим нашим шагом было исследование популярных оркестраторов для контейнеров:

  • AWS ECS
  • Swarm
  • Apache Mesos
  • Nomad
  • Kubernetes

Среди рассматриваемых оркестраторов каждый имел какой-то важный недостаток: ECS является вендорозависимым решение, Swarm уже уступил лавры Kubernetes, Apache Mesos выглядел для нас как космический корабль со своими Zookeeper'ами. Мы решили остановиться на Kubernetes, и вот почему. Nomad показался интересным, однако полностью себя раскрывал себя только в интеграции с другими продуктами Hashicorp, также нас огорчило то, что неймспейсы в Nomad платные.

Kubernetes as a Service доступен у большинства крупных облачных провайдеров. Несмотря на высокий порог вхождения, Kubernetes является стандартом де-факто в оркестрации контейнеров. Оркестратор находится в активной разработке, имеет большое сообщество пользователей и разработчиков и неплохую документацию.

Два инженера платформы без опыта работы с Kubernetes занимались миграцией в режиме частичной загрузки. Мы ожидали мигрировать полностью нашу платформу в Kubernetes за 1 год.

Используем Kubernetes

Решили использовать kops, так как в нашем регионе на то время все еще не был доступен EKS (в Ирландии его анонсировали в сентябре 2018). Мы начали с proof of concept, создали тестовый кластер, подробно документировали все что мы делали.

Мы "игрались" с rolling-update стратегиями, столкнулись с несколькими сетевыми проблемами, в частности с DNS, укрепили знания в траблшутинге кластера. В ходе работы с кластером тестировались cluster-autoscaler, cert-manager, Prometheus, интеграции с Hashicorp Vault, Jenkins и многое другое.

Для получения уведомлений о проблемах со спотам использовали kube-spot-termination-notice-handler, Spot Instance Advisor может помочь вам при выборе типа спот-инстанса. Для оптимизации затрат на инфраструктуру использовали спот инстансы.

Мы начали миграцию со Skullcandy flow на Trunk-based development, где мы запускали динамический стейдж на каждый пулреквест, это позволило сократить время доставки новых фич с 4-6 до 1-2 часов.


Github-хук запускает создание динамического окружения для пулреквеста

Разработчики имели доступ к Kubernetes Dashboard для дебага своего кода. Мы использовали тестовый кластер для этих динамических окружений, каждое окружение находилось в отдельном неймспейсе.

Мы рады тому, что стали получать пользу от Kubernetes уже спустя 1-2 месяца с начала его использования.

Кластеры для стейджа и прода

Наши настройки стейдж и прод кластеров:

  • kops и Kubernetes 1.11 (самая свежая версия на момент создания кластеров)
  • Три мастер ноды в разных зонах доступности
  • Приватная топология сети с выделенным бастионом, Calico CNI
  • Prometheus для сбора метрик, задеплоен в том же кластере с PVC (стоит учесть что мы не храним метрики долго)
  • Datadog-агент для APM
  • Dex+dex-k8s-authenticator для предоставления доступа к кластеру разработчикам
  • Ноды для стейдж кластера работают на спот-инстансах

К примеру, версии Nginx Ingress и Datadog-агента отличались на кластерах, в связи с этим некоторые вещи работали на стейдж кластере, но не работали на проде. В ходе работы с кластерами мы столкнулись с несколькими проблемами. Поэтому мы решили сделать полное соответствие версий ПО на кластерах для избежания подобных случаев.

Мигрируем прод в Kubernetes

Мы используем монорепу с такой структурой: Стейдж и прод кластеры готовы, а мы готовы приступить к миграции.

.
├── microservice1
│ ├── Dockerfile
│ ├── Jenkinsfile
│ └── ...
├── microservice2
│ ├── Dockerfile
│ ├── Jenkinsfile
│ └── ...
├── microserviceN
│ ├── Dockerfile
│ ├── Jenkinsfile
│ └── ...
├── helm
│ ├── microservice1
│ │ ├── Chart.yaml
│ │ ├── ...
│ │ ├── values.prod.yaml
│ │ └── values.stage.yaml
│ ├── microservice2
│ │ ├── Chart.yaml
│ │ ├── ...
│ │ ├── values.prod.yaml
│ │ └── values.stage.yaml
│ ├── microserviceN
│ │ ├── Chart.yaml
│ │ ├── ...
│ │ ├── values.prod.yaml
│ │ └── values.stage.yaml
└── Jenkinsfile

Когда разработчик мержит пулреквест в мастер, создается тег в GitHub, этот тег деплоится на прод с помощью Jenkins в соответствии с Jenkinsfile'ом. Корневой Jenkinsfile содержит в себе таблицу соответствия имени микросервиса и директории в которой находится его код.

Мы используем Skaffold для деплоя множества HELM-чартов на стейдж. В каталоге helm/ располагаются HELM-чарты с двумя отдельными values-файлами для стейджа и прода. Пробовали использовать umbrella chart, но столкнулись с тем что его сложно масштабировать.

В соответствиии с twelve-factor app каждый новый микросервис в проде пишет логи в stdout, читает секреты из Vault и имеет базовый набор алертов (проверка количества работающих подов, пятисотых ошибок и латенси на ингрессе).

В независимости от того, завозим ли мы новые фичи в микросервисы или нет, в нашем случае весь основной функционал находится в Django-монолите и этот монолит все еще работает на Elastic Beanstalk.


Разбиваем монолит на микросервисы // The Vigeland Park в Осло

Мы начали мигрировать монолит на Kubernetes и тестировать его на некоторых языковых версиях и на внутренних страницах сайта (таких как админка). Мы использовали AWS Cloudfront в качестве CDN и с его помощью мы использовали canary-деплой на протяжении нашей миграции. На протяжении пары недель мы наблюдали за состоянием платформы, нагрузкой и мониторингом, в конце концов 100% трафика прода переключили в Kubernetes. Подобный процесс миграции позволил нам отловить баги на проде и отполировать наши деплои всего за несколько итераций.

После этого мы полностью смогли отказаться от использования Elastic Beanstalk.

Итоги

Полная миграция у нас заняла 11 месяцев, как я упоминал выше, планировали уложиться в 1 год.

Собственно результаты налицо:

  • Время деплоя уменьшилось с 90 мин до 40 мин
  • Количество деплоев увеличилось с 0-2 до 10-15 в день (и все еще растет!)
  • Время отката уменьшилось с 45 до 1-2 мин
  • Мы можем легко доставлять новые микросервисы в прод
  • Мы привели в порядок наш мониторинг, логгинг, управление секретами, централизовали их и описали как код

Обязательно прочтите классную статью про опыт работы с Kubernetes от Юры, он был одним из тех YAML-инженеров кто занимался внедрением Kubernetes в Preply. Это был очень крутой опыт по миграции и мы все еще работаем над многими улучшениями платформы.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть