Привет, хочу снова посоветоваться с сообществом, в этот раз про CI/CD для микросервиов && Kubernetes. А именно меня интересует устройство тестовых сред.
Пререквизит к вопросу:
Система состоит из микросервисов, весь продакшен задеплоен в один кубернетес-кластер.
Дальше описание проблемы:
В процессе разработки команды хотят как-то тестировать свой код до того, как он попадёт в мастер, откуда он улетит в Canary и дальше в Prod (либо наоборот из мастера в релизный бранч — не суть важно).
При этом чтобы потестировать, сервисы часто нужно задеплоить — из-за зависимостей от других сервисов и от всяких там баз данных. Т.е. можно всё замокать и тестировать локально, но это обычно сложно и к этому нужно долго идти. Естественная реакция на эту задачу — поднять каждой команде по кубернетес-кластеру и пусть туда деплоят и тестируют. Но мне кажется, что это не очень хороший способ, который плохо скейлится — команд со временем становится много, сервисов тоже много, и деплоить полную копию всего продакшена из N сервисов ради теста одного — не звучит как оптимальное решение, плюс мейнтенс кучи кубер-кластеров будет отнимать ресурсы.
В целом у меня в голове такая картинка: есть один тестовый кластер, куда задеплоены все сервисы со всей нужной инфраструктурой (версии допустим аналогичной продакшену). И дальше есть возможность для любого сервиса один из инстансов задеплоить другой версии (например, из бранча) и как-то принудительно пустить трафик через эту “тестовую версию”. Т.е. если ничего не делать, то на запрос ответит продакшен-версия, но если передать какой-нибудь заголовок типа “service_name=test”, то весь запрос обработается тестовым инстансом.
Наверняка есть какой-нибудь способ организовать всё это:
1. Из buzzword-ов я слышал service mesh, но как ни начну туда копать — всё сложно получается.
2. Ещё можно как-то поднимать девелопмент/тестовые версии в Minikube, но всё равно не понятно как через эти версии траффик пускать.
3. Ещё я видел вариант, когда под бранч создаётся короткоживущий кубернетес-кластер, на котором всё тестируется и он тушится — тут возникает масса вопросов от “какие версии сервисов деплоить в этот кластер” до того, что разворачивание кластера с базами под PR может быть долгим и сложным.
Скажите, есть ли у кого-нибудь опыт организации чего-нибудь похожего, или я хочу странного и всё можно организовать как-то иначе?
Блеск и нищета SOA архитектуры. Ваша задача легко решается, если заменить термин microservice на external service и представить как бы выгледело тестирование в таком случае.
Приложение которому нужен Stripe не может для своих тестов задеплоить Stripe определенной версии. Поэтому downstream использует тот upstream, который доступен и не может требовать ничего больше.
Самый простой способ это поднять dev staging environment к которому вы относитесь так же как к вашем production. В этом окружении живут сервисы из ветки main которые можно использовать для нужд разработки и тестирования.
У каждой команды есть свое CI окружение которое использует сервисы из dev staging. Если они хотят что-то протестировать то льют в свой CI, но возможности деплоить другие версии upstream микросервисов у них нет, потому что каждый микросервис живет своей жизнью и зависимый компонент ничего не знает о жизненном цикле своей зависимости.
Далее для юнит тестов мокаем - здесь нет альтернатив, потому что тесты обязаны быть быстрыми, для интеграционных тестов поднимаем docker compose где это возможно, а для всех остальных тестов используем сервисы из dev staging.