- PVSM.RU - https://www.pvsm.ru -
В этой статье я опишу наш опыт миграции Preply в Kubernetes, как и почему мы это сделали, с какими трудностями столкнулись и какие преимущества приобрели.
Вокруг Kubernetes много хайпа и это неспроста. Многие люди говорят что он решит все проблемы, некоторые утверждают, что скорее всего, Kubernetes вам не нужен [1]. Истина конечно находится где-то посередине.
Однако все эти рассуждения о том где и когда нужен Kubernetes, достойны отдельной статьи. Сейчас же я расскажу немного о наших бизнес-требованиях и как Preply работал до миграции в Kubernetes:
stage-rc
, деплоились на стейдж. Команда QA тестировала это окружение, после тестирования ветка мержилась в мастер и мастер деплоился на прод. Вся процедура занимала порядка 3-4 часов и у нас получалось деплоиться от 0 до 2 раз в деньДля улучшения нашего продукта и процессов в компании мы хотели:
Для внедрения наших нововведений со Skullcandy flow нам нужно было создавать динамическое окружение для каждой ветки. В нашем подходе с конфигурацией приложения в Elastic Beanstalk сделать это было сложно и дорого. Нам хотелось создавать окружения которые бы:
Мы решили переехать на Trunk-Based Development. С его помощью, каждая фича имеет отдельную ветку, которая независимо от остальных может мержиться в мастер. Мастер-ветка может деплоиться в любое время.
git-flow и Trunk-Based Development [5]
Новый Trunk-Based процесс позволил нам быстрее доставлять нововведения в мастер-ветку одну за другой. Это существенно помогло нам в процессе поиска сломаного кода в проде и его откате. Однако, время деплоя все еще составляло 90 минут, а время отката — 45 минут, из-за этого мы не могли деплоиться чаще 4-5 раз в день.
Также мы столкнулись с трудностями при использовании сервисной архитектуры на Elastic Beanstalk. Наиболее очевидным решением являлось использование контейнеров и инструмента для их оркестрации. К тому же у нас уже был опыт использования Docker и docker-compose для локальной разработки.
Следующим нашим шагом было исследование популярных оркестраторов для контейнеров:
Мы решили остановиться на Kubernetes, и вот почему. Среди рассматриваемых оркестраторов каждый имел какой-то важный недостаток: ECS является вендорозависимым решение, Swarm уже уступил лавры Kubernetes, Apache Mesos выглядел для нас как космический корабль со своими Zookeeper'ами. Nomad показался интересным, однако полностью себя раскрывал себя только в интеграции с другими продуктами Hashicorp, также нас огорчило то, что неймспейсы в Nomad платные.
Несмотря на высокий порог вхождения, Kubernetes является стандартом де-факто в оркестрации контейнеров. Kubernetes as a Service доступен у большинства крупных облачных провайдеров. Оркестратор находится в активной разработке, имеет большое сообщество пользователей и разработчиков и неплохую документацию.
Мы ожидали мигрировать полностью нашу платформу в Kubernetes за 1 год. Два инженера платформы без опыта работы с Kubernetes занимались миграцией в режиме частичной загрузки.
Мы начали с proof of concept, создали тестовый кластер, подробно документировали все что мы делали. Решили использовать kops [7], так как в нашем регионе на то время все еще не был доступен EKS (в Ирландии его анонсировали в сентябре 2018 [8]).
В ходе работы с кластером тестировались cluster-autoscaler [9], cert-manager [10], Prometheus, интеграции с Hashicorp Vault, Jenkins и многое другое. Мы "игрались" с rolling-update стратегиями, столкнулись с несколькими сетевыми проблемами, в частности с DNS [11], укрепили знания в траблшутинге кластера.
Для оптимизации затрат на инфраструктуру использовали спот инстансы [12]. Для получения уведомлений о проблемах со спотам использовали kube-spot-termination-notice-handler [13], Spot Instance Advisor [14] может помочь вам при выборе типа спот-инстанса.
Мы начали миграцию со Skullcandy flow на Trunk-based development, где мы запускали динамический стейдж на каждый пулреквест, это позволило сократить время доставки новых фич с 4-6 до 1-2 часов.
Github-хук запускает создание динамического окружения для пулреквеста
Мы использовали тестовый кластер для этих динамических окружений, каждое окружение находилось в отдельном неймспейсе. Разработчики имели доступ к Kubernetes Dashboard для дебага своего кода.
Мы рады тому, что стали получать пользу от Kubernetes уже спустя 1-2 месяца с начала его использования.
Наши настройки стейдж и прод кластеров:
В ходе работы с кластерами мы столкнулись с несколькими проблемами. К примеру, версии Nginx Ingress и Datadog-агента отличались на кластерах, в связи с этим некоторые вещи работали на стейдж кластере, но не работали на проде. Поэтому мы решили сделать полное соответствие версий ПО на кластерах для избежания подобных случаев.
Стейдж и прод кластеры готовы, а мы готовы приступить к миграции. Мы используем монорепу с такой структурой:
.
├── 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
Корневой Jenkinsfile
содержит в себе таблицу соответствия имени микросервиса и директории в которой находится его код. Когда разработчик мержит пулреквест в мастер, создается тег в GitHub, этот тег деплоится на прод с помощью Jenkins в соответствии с Jenkinsfile'ом.
В каталоге helm/
располагаются HELM-чарты с двумя отдельными values-файлами для стейджа и прода. Мы используем Skaffold для деплоя множества HELM-чартов на стейдж. Пробовали использовать umbrella chart, но столкнулись с тем что его сложно масштабировать.
В соответствиии с twelve-factor app [18] каждый новый микросервис в проде пишет логи в stdout, читает секреты из Vault и имеет базовый набор алертов (проверка количества работающих подов, пятисотых ошибок и латенси на ингрессе).
В независимости от того, завозим ли мы новые фичи в микросервисы или нет, в нашем случае весь основной функционал находится в Django-монолите и этот монолит все еще работает на Elastic Beanstalk.
Разбиваем монолит на микросервисы // The Vigeland Park в Осло
Мы использовали AWS Cloudfront в качестве CDN и с его помощью мы использовали canary-деплой на протяжении нашей миграции. Мы начали мигрировать монолит на Kubernetes и тестировать его на некоторых языковых версиях и на внутренних страницах сайта (таких как админка). Подобный процесс миграции позволил нам отловить баги на проде и отполировать наши деплои всего за несколько итераций. На протяжении пары недель мы наблюдали за состоянием платформы, нагрузкой и мониторингом, в конце концов 100% трафика прода переключили в Kubernetes.
После этого мы полностью смогли отказаться от использования Elastic Beanstalk.
Полная миграция у нас заняла 11 месяцев, как я упоминал выше, планировали уложиться в 1 год.
Собственно результаты налицо:
Это был очень крутой опыт по миграции и мы все еще работаем над многими улучшениями платформы. Обязательно прочтите классную статью [19] про опыт работы с Kubernetes от Юры, он был одним из тех YAML-инженеров кто занимался внедрением Kubernetes в Preply.
Автор: Amet13
Источник [20]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/aws-2/328240
Ссылки в тексте:
[1] Kubernetes вам не нужен: https://news.ycombinator.com/item?id=19467067
[2] Skullcandy flow: https://www.endpoint.com/blog/2014/05/02/git-workflows-that-work
[3] Elastic Beanstalk: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html
[4] хостинга: https://www.reg.ru/?rlink=reflink-717
[5] git-flow и Trunk-Based Development: https://www.toptal.com/software/trunk-based-development-git-flow
[6] AWS ECS: https://aws.amazon.com/ecs/
[7] kops: https://github.com/kubernetes/kops
[8] в сентябре 2018: https://aws.amazon.com/about-aws/whats-new/2018/09/amazon-eks-available-in-ireland/
[9] cluster-autoscaler: https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
[10] cert-manager: https://github.com/jetstack/cert-manager
[11] DNS: https://github.com/kubernetes/kubernetes/issues/71411
[12] спот инстансы: https://medium.com/preply-engineering/why-and-how-do-we-run-kubernetes-on-the-spot-instances-c88d32fb9df3
[13] kube-spot-termination-notice-handler: https://github.com/kube-aws/kube-spot-termination-notice-handler
[14] Spot Instance Advisor: https://aws.amazon.com/ec2/spot/instance-advisor/
[15] Calico: https://docs.projectcalico.org/v3.8/introduction/
[16] Datadog-агент: https://github.com/helm/charts/tree/master/stable/datadog
[17] Dex+dex-k8s-authenticator: https://habr.com/en/post/436238/
[18] twelve-factor app: https://12factor.net/ru/
[19] классную статью: https://grem1.in/post/k8s-year/
[20] Источник: https://habr.com/ru/post/464465/?utm_campaign=464465&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.