# CI/CD, стратегии ветвления Git и варианты деплоя

_длительность: 58 мин_

**[2:04]** Сейчас подождем еще людей и начнем.

**[6:22]** Давайте потихоньку начинать. Пока я шарю экран, можете вопросы позадавать, если надо. Если есть смыслы.

**[7:37]** Во-первых, по лабам. Получается, сегодня-завтра я скину оставшиеся две, чтобы вы их могли доделывать. И еще важный момент. Я в чате продублирую. Следующее занятие мы пропускаем. 4 мая, которое придется его пропустить. Но наверстаем его потом. Какой-нибудь из этих подольше посидим. Или еще что-нибудь придумаем. Так. Значит...

**[8:08]** сегодня у нас про доставку нашего кода. То есть мы до этого с вами поговорили в целом про концепции в Deops, которые есть, про контейнеризацию. И мы еще даже вводили с вами такое понятие, как артефакт. И, в общем-то, один из самых главных процессов, это как нам этот артефакт собрать и доставить в продакшн. Собственно, для этого

**[8:35]** специальная штука которая так и называется CICD. Дайте мне секунду, я проверю. Мне кажется пару слайдов пропало и это не те.

**[9:46]** извиняюсь, все нормально, один свайти, все только пропал. То есть, что у нас есть? У нас есть наш девелопмент, то есть среда, где мы, условно говоря, разрабатываемся и как итог собираем наш артефакт. У нас есть тестирование этого артефакта на момент сборки, на момент после сборки и прочее, на разных стендах и так далее. То есть, стандартная процедура. И уже потом это попадает в общем в продакшн. И вот как раз за это отвечает процесс CICD. То есть,

**[10:16]** Если мы говорим о ранних этапах разработки, в смысле, ранние времена, так это назовем, когда еще этих концепций особо не было, что имели? Любой выкат на про – это простой всегда было. Это и сейчас у многих есть такая проблема, потому что это зависит от разных вещей. Это была проблема особенно тогда, что вам надо поставить какую-нибудь заглушку или просто объявить технические работы,

**[10:44]** Потому что одновременно обновлять и пускать пользователей физической возможности, технической часто не было. Сам процесс был долгий, то есть это ручные сборки артефактов какие-то, ручные доставки, скопировать, куда-то ставить и так далее. Множество людей в этом плане участвовало еще и с кучей рутины. То есть если более кратко сказать, не было какой-то автоматизации этого, а соответственно и скорости.

**[11:15]** Ну и конечно риск, потому что не так покрыто это все было тестированием на разных каких-то стендах тестовых и так далее. То есть то, что везде, чаще всего прямо на проде и проверяем. Соответственно, когда появился CICT, стало полегче. Мы частично с вами уже затрагивали этот термин, кажется. То есть расшифровывается как Continuous Integration и Continuous Delivery или Deployment. Сейчас посмотрим, в чем разница.

**[11:45]** То есть integration – это у нас интеграция нашего разработки по интеграции в нашу инфру. То есть все, что мы делаем с точки зрения, что автоматическая сборка, тестирование какого-то образа, первичная его куда-то отправка, за это отвечает как раз первая половина CI. Соответственно, CD у нас отвечает за непосредственную доставку уже готового и частично протестированного артефакта.

**[12:14]** на разные другие стенды. В первую очередь, конечно, на Prod. Такую схему мы уже с вами видели. Соответственно, в чем удобство? Сильно, конечно, сказано, что не допустят ошибки до Prod, но как минимум из-за повторяемости на множестве разных стендов мы, скорее всего, какие-то вещи отловим. И, соответственно, и качество кода нашего улучшим и так далее. Также повысим скорость, потому что...

**[12:44]** В общем-то, у нас большая часть автоматизирована. И просто собрать новый артефакт и отправить уже в протоптанные дорожки гораздо быстрее. Соответственно, никаких проблем с тем, что работает локально или нет. У нас есть продакшн, у нас есть условные копии продакшна, которые другие тестовые стенды, где можно это проверить и примерно предсказать поведение, как это поведет себя на реальном продакшне. Ну и, соответственно, гибко их можно менять. То есть добавлять, убавлять стенды, гибко их как-то настраивать и так далее.

**[13:14]** что для нас удобно. С точки зрения термина непрерывной интеграции это у нас сборка и первичное тестирование. Причем иногда их несколько, потому что мы, например, можем тестировать либо на уязвимости, пока мы собираем код, и потом уже собранный образ мы можем еще отдельно тестировать тоже на какие-то уязвимости или на то, как он собрался и так далее. Вот.

**[13:44]** Соответственно, Continuous Delivery это у нас, когда мы берем результат нашего CI и везем его куда-нибудь. Довольно важный момент, что CD может расшифроваться как Continuous Delivery и Continuous Deployment. И это разные вещи. Continuous Delivery предполагает только ручной деплой на продакшн. То есть мы автоматизируем все, что можно, ровно до последнего этапа. То есть Continuous Delivery не предполагает, что у нас весь путь от сборки артефакта до выкатки на прод пройдет автоматически. То есть

**[14:14]** грубо говоря, до самого последнего минус 1. И когда уже все будет готово, надо прийти и человеку нажать кнопку, что задеплой, все нормально. Будет то релиз инженера или просто разработчик, не важно. Соответственно, для сравнения Continuous Deployment, это как раз про то, что у нас и выкатка в прод тоже автоматизирована. Я думаю, очевидно, чем более крупная и высококритичная система, тем менее возможен

**[14:44]** когда мы используем continuous deployment потому что дело все-таки опасно когда мы настолько полностью это все автоматизируем в том числе и выкатку в про то есть когда это какие-то мелкие не знаю проекты там которые не сильно плохо если сломаются в моменте который быстро починить нормально но если это бизнес критикал то конечно континент дипломит никто использован скорее всего не будет

**[15:09]** Собственно, если вот так вот смотреть по схемкам, выглядят они практически одинаково. То есть есть у нас билд, там мы тестируем, можно еще до билда потестировать. Деплоим в какие-то среды, где тестируем промежуточные варианты, там на стейджинг. Соответственно, здесь множество разных тестов, accept and tense, интеграционные тесты какие-то и прочее. Потому что если у нас несколько сервисов выкатывается, нам надо же еще проверить, что интеграция между ними не сломалась и прочее.

**[15:34]** Потом уже Deployed Production ручной или не ручной, в зависимости от того, что мы используем. И дальше последние тесты, где мы проверяем распространенности нашего условного релиза. В таком еще упрощенном виде это может выглядеть. Это с сайта GitLab схема. Есть у нас код, соответственно мы его коммитим.

**[16:00]** Потом начинаем его билдить. Здесь у нас как минимум юнит-тесты прогоняются, которые мы сами написали. Интеграционные тесты тоже и все такое прочее. На этом наш этап CI заканчивается. И на этапе CD мы уже это стейджем и везем в разные среды, в том числе и в продакшн. Конкретно про то, как это реализовано в GitLab у нас будет следующая лекция. Пока вот просто пример, как выглядит, например, в GitLab простой CI-CD. Как видите, те же самые этапы. Что мы что-то протестировали.

**[16:31]** Потом сбилдили и затеплоили сразу в дев, потом тоже сбилдили и затеплоили в плод. Потом еще отдельно есть джабаш, чтобы настроить, как-то мониторить на это дело. Почему нет? Но это, разумеется, пример самого простейшего CI-сети. Бывают и, к сожалению, вот такие. То есть это тоже реальный скрин, так сказать, с работы. Что у нас тут все-таки есть одно из преимуществ, как я сказал, это гибкая настройка какая-то.

**[16:59]** там параметризация и так далее вот она может быть такой это много каких-то нюансов много сред и так далее вот ну бог с таким вы вряд ли прям столкнетесь но тем не менее вот и только вот эта картинка мне очень нравится какой у нас flow есть с CICD то есть мы что-то потестили сбью дели задеплоили на dev поняли что ну что-то там

**[17:22]** упало, потому что забыли, не знаю, переменную там неправильно написали, где-то опечатались в одной букве. Прямо на стенде руками поправили, все четко, все отлично работает, и разумеется, забыли это закоммитить. Это дальше поехало, соответственно, на какой-нибудь стейджинг этап. Там это тоже сломалось все-таки, блин, точно, тут же были ручные вмешательства, снова их сделали. И дальше все как-то это повезли, и на проде, разумеется, это тоже

**[17:53]** Дальше звонок на 50 тысяч человек, множество каких-то ручных операций, чтобы это все починить. Более-менее восстановили, чтобы хоть как-то работало и все. И потом в себе мы добавляем траблшутинг, автоматизация, профессионалы и так далее. В общем-то крайне жизненно, о чем могу сказать. Как пример, подробно мы не будем останавливаться, у вас вроде отдельная дисциплина, но я думаю понятно, что вот этот весь процесс,

**[18:21]** пайплайнов довольно удобен и поэтому многие области стали себе это перенимать и по сути когда вы встречаете какое-то там понятие плюс ops это обычно предполагает что мы используем базовые девопс концепции и накладываем их на какую-то конкретную специфику например и мэллипс то есть по сути чем отличается если в обычном девопсе мы просто

**[18:41]** собираем артефакты, везем его, то почему бы нам не применить это к моделям. То есть мы можем также циклически, например, обучать эти модели и потом также их автоматически деплоить куда-то. И также модели держать в виде артефактов. То есть это один из таких южкейсов, как это используется. Обученные какие-то датасеты и прочее, они сохраняются либо в виде образов, которые можно подтянуть, либо в виде волюмов, которые можно примонтировать и так далее. То есть это часть обычного

**[19:11]** процесса, который в то же время, конечно, тоже цикличен. Грубо говоря, мы там что-то накодили, потренировали, упаковали, соответственно, задеплоили, посмотрели, как этот, потом вернулись. В этом плане никакой разницы нет. Ну или вот чуть более сложная история, то есть мы, грубо говоря, можем разделить, например, на две разные репы. В одной хранить только код, в другой там только данные с моделями.

**[19:37]** И так далее. И вот, соответственно, пример одного из пайплайнов, как это может работать. То есть, если там до этого мы собирали артефакт и тестили, здесь то же самое. Мы берем нашу модель, тренируем, проверяем, все с ней ок, потом уже упаковываем, деплоим и, в общем-то, так далее. Вот. Примерно так. Далее немножко про гид. Потому что

**[20:07]** Ну, очевидно, есть некоторые нюансы в том плане, что мы обычно, эта история неразвитно связана с Git-ом. Как минимум по двум причинам. То есть, во-первых, у нас где-то хранится наш код, который нам надо собрать вот этим нашим CI. И обычно CI реализуется на стороне хранилки этого кода. То есть, чаще всего, если это GitLab, то прямо GitLab CI это все и собирается. Поэтому это тоже довольно важно, потому что у Git-а есть какие-то свои сущности, которые надо учитывать при этих...

**[20:37]** Плюс сами пайплайны. Я опять-таки не помню, у нас с вами в этот курс попадает или нет инфраструкция из-за кода. Но смысл-то в чем? Что у нас все эти пайплайны и прочее, это же тоже описано кодом. Есть где-то репозитория с кодом, где описывается, как артефакт проходит весь этот путь, как где запустить тесты и прочее. Это ведь тоже все код. Поэтому использование ГИТА и главная стратегия ветвления довольно...

**[21:07]** важная вещь. То есть если вот мы берем, например, какие-то негативные практики, которые мы используем в GTE, то есть это когда мы пушим просто в один мейн и прочее. Если у вас какой-то мелкий проект, какой-то там, не знаю, pet project вы дома делаете, конечно, ничего страшного в этом нет. Но мы говорим про нормальную среду, типа команды и так далее. Соответственно, когда у нас один человек все это пишет, тоже такой большой риск.

**[21:35]** такая точка отказа потенциальная.

**[22:00]** наоборот у меня была ситуация когда был разработчик который писал просто огромные коммиты на русском зачем-то там прям таки было что вот типа согласно задачи вот это и переобразовал вот такую-то функцию которая делала вот это и прочее просто там прямо полотно этого текста в один комик месседж то есть но это как странно искать конечно золотую середину вот в то же время хорошей практике у нас то есть то есть

**[22:30]** такие общие советы. Понятно, это всего лишь совет, это не какая-то там единая точка истины. То есть, во-первых, мы стараемся коммитить более часто и более мелкими. То есть, вот эти вот коммиты, когда один большой, который вы писали весь день, в мёрзживаются ветку, и там просто миллиард изменений на тысячи строк. То есть, это вот не очень хорошо, потому что это плохо читабельно, и это плохо откатываемо. А у нас всё-таки в наших

**[22:58]** с ACD процессом важно откатывать состояние обратно. Поэтому лучше уж побольше мелких коммитов, чем один большой. Какие-то name convention для имен коммитов по-хорошему. Gitignore, то есть как мы с вами, я не помню, в прошлой лекции мы упоминали, что есть Dockerignore, чтобы мы хотели собрать артефакт, и туда не попало ничего лишнего. Gitignore то же самое.

**[23:26]** записать чтобы нас не попало туда что-то лишнее например секреты потому что тоже в чем минус гита вернее это его плюс но в данном случае минус что гид все помнит есть история если это хотя бы раз там попадутся секреты куда вы закоммитите случайно логин и пароль это они уже навсегда станции в этой истории и все довольно будет печально вот код ревью то есть понятно раз есть технология где мы можем вмерживать код и

**[23:53]** И вообще делиться на ветки, условно говоря, и сравнивать наши дифы, делать ревью этого, что разработчикам, что инженерам. Это довольно полезно, тоже не стоит этим пренебрегать. Ну и не забывать делать rebase, условно говоря, потому что если вы отвели ветку от какой-то ветки, и пока вы там в ней работали, основная ветка, от которой вы отвелись, уже довольно вперед далеко убежала, то всегда хорошим тоном считается rebase, чтобы всегда было актуальное состояние перед мерчингом.

**[24:24]** Собственно, про ветки. Зачем это нужно и какие бывают. Раз уж мы используем все преимущества ГИТа, то основное его преимущество это как раз ветвление. Чтобы нам было удобнее разрабатываться. Это и называется стратегия ветвления. Как мы разрабатываем наше ПО. Это и для разработки подходит, и для инженеров. Все то же самое.

**[24:49]** Потому что это все регламентирует не только правила, как мы пушим, но и в целом интеллируемся в доставку нашего кода. Вот пример двух схем, как это может быть и как может быть по-другому. И то, и то в принципе рабочее, но как будто бы это выглядит более удобнее и читаем. Про стратегии обетвления. Какие они у нас бывают. Самая простая.

**[25:31]** Самое простое, которое есть, это OneBranchFlow. Если по-простому, это тот случай, который я сказал, что это просто какой-то у вас BadProject, который вы что-то там делаете. В этом плане не особо важно, какую ветку мы используем.

**[25:49]** Бот какой-нибудь у меня есть, который я написал для телеграммчика, какую-то фигню делать. Но я постоянно туда прямо в мастер могу что-то запушить и пофиг, что там будет. То есть тут чистота истории кода нам не сильно нужна. Поэтому мы и пушим в одну и ту же ветку, и деплоим из нее. То есть ничего такого, вполне нормальная история. GitFlow. Одно из самых популярных решений на рынке, но с сомнительной эффективностью, честно говоря.

**[26:20]** как минимум из-за скорости и огромного количества сущностей. То есть какая тут идея? Вот у нас есть ветка main, которая содержит самый актуальный код из возможных. Но тем не менее этот main мы никак не используем вообще. То есть он просто хранит код в максимально stable состоянии. Активная ветка у нас develop, которая отводится от этого main. Вот у нас есть develop. Вот.

**[26:49]** дальше происходит мы соответственно в этот девелоп от этого девелопа отводим ветки которые называем фича это все префиксы то есть если мы не девелоп это имя то дальше уже префиксы то здесь мы отводим префиксы фича и в ней что-нибудь делаем буквально какую-то одну фичу можно даже к джири привязать какую-нибудь что там сделали и прочее вмерзли в дерево и так вот несколько раз вот до какого-то момента времени когда

**[27:19]** соответственно происходит такая вещь как релиз то есть тут уже стоит задуматься что если в вашей вашем так сказать цикле разработки нет такого понятия как регулярный листу нужен ли вам этот вообще гид флот вот но представим что здесь такая ситуация есть и мы соответственно берем какой-то релиз вот на момент когда у нас станут ветка девелок максимально стабильной мы в межели в нее все фичи которые мы хотели мы отводим

**[27:48]** ветку релиза от девелопа вот соответственно именно эта релизная ветка с префексом релиз уже выкатывается на продакшен ну грубо говоря даже не так она вливается в мэйн вот полноценный мэйн тега это стабильной версии из мэйна уже раскатывается продакшен вот если все ок и никаких там обновлений не надо то в между делом песене то ну тут что-то поправим и

**[28:15]** то есть в самой релизной, и это вмерзивается в DL, и дальше все начинается по-новому. Такой вот не самый быстрый, честно говоря, процесс, не мой любимый, но тем не менее вполне популярный. Единственная еще разница, что есть такая сущность, как Hotfix, когда мы видим, что прям какое-то супер мелкое изменение. Не знаю, увидели, что какой-то сервис не очень хорошо работает, и до следующего релиза можно бы отключить какую-то часть функционала. И так слышу, что у этого релиза есть, например,

**[28:45]** какой-нибудь флаг, переменная, enable что-то там. И по сути, чтобы все починить, текущее состояние, надо просто сделать disable этого ключа и все. То есть отдельно весь этот путь проходить ради того, чтобы поменять значение одной переменной, смысла нет. Рукавина вроде менять их тоже, конечно, не стоит. Разумеется, я все время так делаю, но делать так не надо. В таких случаях как раз существует сущность hotfix. Она отводится прямо от мейна. Вы меняете какую-то микроскопическую часть,

**[29:14]** и в межруйте сразу обратно. Вот и все. Примерно такая логика. GitHub Flow сильно проще в этом плане. То есть у нас есть просто main, грубо говоря, и фиша ветки. То есть согласитесь, гораздо проще звучит, что у нас куча веток отводится, что-то разработали, и есть стабильный всегда актуальный main. Из минусов, конечно, что если что-то пропустилось в фиша ветках, и в main это попало, то обратно откатывать уже

**[29:44]** но чуть сложнее. А для сравнения GitLab Flow примерно то же самое, только у них чуть сложнее. У них что-то между Git Flow и GitHub Flow. То есть у них также есть main, условно говоря, есть отдельные ветки, которые мы вмершиваем в этот main. И когда мы, соответственно, также готовимся к релизу, мы отводим ветку для production. То есть main у нас содержит актуальный код, но он не выкатывается в production, потому что

**[30:14]** мы сначала все эти ветки собрали, что у нас все ок, может даже задеплоили их отдельно, проверили, что они нормальные, влили их в мастер и уже из мастера отводим ветку предпродакшн, проверяем, что с ней все ок, и уже из предпродакшна мы отводим ветку продакшн и ее деплоим. Вот такая многоуровневая система. Разница в том, что вот эти ветки потом не используются никак, они просто остаются в истории, что когда-то был такой релиз. То есть если сравнивать с GitFlow, это примерно как здесь мы затегали,

**[30:45]** что такое было. Здесь вместо тегов отдельные ветки. И, соответственно, всегда можно вернуться в эти ветки и посмотреть, что там было. Потом на следующем релизе будут новые ветки отводиться от мейна. Ну и мой любимый Trunk-Based. Еще раз, извините. А можете подсказать по GitLab Flow? Получается, на какой-то стабильной версии мы отпочковываемся новой веткой, чтобы что?

**[31:13]** есть что конкретно в этих ветках просто там сборка происходит и все или не с тобой изменения трекались условно во первых трекались просто я говорю в чем разница вот здесь когда мы отвели какую-то ветку релизную прочее из нее за тепло или так далее это потом исчезнет то есть вот эта ветка пропадет она вольется в девелок и все что останется у нас в истории что когда-то был такой релиз это вот этот тег причем буквально гиттег даже не ветка и

**[31:43]** То есть это Google API репозитория, у него есть ветка, и у ветки есть тег какой-то. То есть, по сути, все, что мы будем уметь, это конкретный коммит. И все. Это все, что у нас будет в истории с точки зрения релиза. В этом же плане мы, соответственно, что-то вот тут разрабатываем в ветках. Когда ветки плюс-минус готовы и стабильные, мы вмерзнем это в мастер, и в какой-то момент времени понимаем, что наш текущий мастер готов для нового релиза. И да, в таком случае мы отводим именно ветку,

**[32:13]** релизную. То есть тут их две, по сути можно одну. Мы, например, одну отводим. Соответственно, дальше все, что будет касаться этого релиза, будет происходить в ней. То есть мы отвели релиз, начали деплойить, проверять на препроде и заметили, например, что там нет какой-нибудь интеграции с PassGrow или что-то забыли. Мы прямо в этой релизной это все меняем и

**[32:36]** проверяем если все ок типа на припроде то итоговую вот эту версию на припроде которая заработала мы диплом на проб его потом собственно задним числом эти изменения добавляем в мастер и дальше вот снова в этой точке начинаем и все то есть вот это то что осталось мы про это забыли разница в том что во первых это существует виде веток во вторых мы в этих ветках еще какие-то комиты делали мы можем посмотреть какие и

**[33:04]** Это удобно, например, когда у вас много сервисов, и вы можете буквально вернуться и задеплоить всю ветку. И тогда все, что в ней закомичено, соответственно, будет выключено. То есть в случае с GitFlow это чуть сложнее. Понятно примерно? Да, понятно, спасибо. А тогда это буквально для истории. То есть посмотреть, какие, когда, что релизы были. Это суперудобно.

**[33:33]** чтобы смотреть, например, не потерялось ли чего. То есть, грубо говоря, пока вы разрабатывали новый релиз, в прошлом вы что-то хотфиксанули. И важно же, чтобы эта штука попала сюда, условно говоря, в новый релиз, потому что вы ее задеплоили в прошлом релизе, вот в этой ветке, а в новую забыли. Поэтому эти вещи важны помнить, чтобы можно было сравнить релизы друг с другом. Примерно такая вещь.

**[34:03]** вот ну и моя любимая тренд бейст тоже не все команды могут себе позволить просто потому что это нужно так сказать скилл чтобы быть уверенным что ты ничего не сломаешь потому что ты берешь одну ветку какую-то главную то есть ну редко это мэн чаще всего она как-то отдельно называется вот и разрабатываешься прямо в ней то есть вы отводите какие-то временные фичи ветки и

**[34:29]** что-то там не делайте и сразу соответственно в нее вкатываетесь и из нее вот причем редкие короткоживущие с какими-то супер мелкими этими вот соответственно здесь мы стараемся избежать качестве большого количества веток но добавляем множественные ключи чтобы мы могли включать выключать нужные фичи вот

**[34:52]** Это нам позволяет супер быстро тестировать наш код, потому что мы не тратим время на огромное количество ревью, вливаний, проверок других веток и прочее. Близко к базовой разработке в одной ветке для своего педпроекта, но более осознанно и серьезно. У меня в команде фронтедеры используют трендбейс. Они берут релизную ветку, называют ее так.

**[35:19]** релиз номер 100. Они что-то там сделали, его выкатили, и потом из релиза номер 100 они создают релиз 101. И, соответственно, в нем уже что-то разрабатывают и прочее. Потом, когда все завершилось, отведут ветку из 101-го, 102-го релиза и так далее. То есть, по сути, ветки создают новые, но по факту это одна большая длинная ветка получается. В сравнении, например, с бэкэндерами, которые предпочитают разрабатываться в девелопе, чтобы в девелопе был самый актуальный код, и в нужный момент отводить релизную ветку.

**[35:49]** Кому как удобнее это на откуп разработчикам обычно, но тем не менее часто приходится как-то договариваться с опсами, потому что если у них все процессы подстроены под GitOps, то довольно сложно trunk-base в этом плане использовать, потому что они ждут от тебя релизную ветку все время какую-то отдельную. Примерно так. И fork-in-flow это по сути то, что вы видели в GitHub,

**[36:18]** То есть если вы замечали какие-то публичные GitHub репозитории какого-то там open source решения, вы не можете прямо себе его скачать, отвести ветку и кинуть MMR. Правильно? То есть поскольку это такая все-таки серьезная вещь, они предлагают обычно форкать целый репозиторий и кидать MMR на уровне репозитория. Примерно такая. То есть это тоже pull request, но между двумя репами. То есть это как раз модель, которая используется в GitHub. Примерно так.

**[36:50]** По стратегиям ветвления все. Что у нас имеется? Мы поговорили про процесс доставки нашего кода на сервер. Мы поговорили, что такое CI-CD, что в этом CI, что в этом CD. Зачем это надо? Аккуратность при работе с нашим ГИТом, то есть различные стратегии ветвления.

**[37:11]** Так, сейчас я посмотрю, это все, что я вам хотел сегодня рассказать, или на следующий надо еще будет. Так, секунду, можете пока вопросы позадавать, если есть. Так, сейчас я прикину, что там в следующий раз.

**[37:43]** Да, знаете, тут пару слайдов сейчас я открою с другой презентации и дорассказываю еще важную вещь, которую, кажется, забыл добавить. А можете подсказать, какую из стратегий стоит использовать в рабочих проектах, если с нуля все это делать? Чтобы она была оптимальной по сложности и по количеству, так скажем, не знаю...

**[38:15]** Мне кажется, GitHub Flow самый простой. То есть у вас есть основная ветка, вы отводите какие-то фичи, в ней разрабатываете и в нее вмерживаете. И все. Как будто бы самое простое решение, плюс-минус элегантное, и из него потом можно вывести, перейти на другие Flow не сильно сложно. Чем наоборот, вы будете начинать с Git Flow и потом обратно перескакивать. Вот. Понял.

**[38:45]** Сейчас я тут пошарю.

**[39:30]** Последнюю часть, которую я бы хотел рассказать, мы с вами чуть-чуть это упомянули. Когда я сказал вначале, что раньше нужен был простой, а потом у нас появился CACD, и мы могли как-то динамически обновлять наш продакшн, чтобы одновременно пользователи этим не задеть. Но по факту это ведь не просто CACD это все делает. CACD это просто пайплайн, условно говоря, конвейер, который катит наши артефакты.

**[39:57]** Но подходы, как и с гитом, то есть если у нас есть стратегия ветвления, как делать CI, то есть и стратегия, как делать диплой. И от этого, собственно, это довольно важный момент, чтобы у нас не было вот этих простоев, потому что полностью от них избавиться довольно сложно. И, соответственно, какие они бывают. То есть самый простой диплой, который существует, это, в общем-то, я даже не знаю, как его правильно назвать, это просто диплой. То есть это вот...

**[40:25]** похожий на тот, который у нас был до CI-CD. То есть мы просто потихоньку обновляем нашу новую версию. Вот у нас был набор сервисов. Мы, допустим, катим релиз, и все сервисы обновились до версии 2. И, соответственно, довольно быстренько, одновременно, плюс-минус, они обновились. И

**[40:49]** Либо они все взлетели, либо не взлетели. Поэтому есть некоторый риск, потому что здесь нет вообще никакой защиты от сбоя. Мы выкатили и выкатили. И если что-то сломается, мы узнаем уже, когда выкатим. А еще не всегда можно откатить что-то обратно. Особенно если это бэкэнт и прочее. Поэтому такой диплой мы используем в основном на какие-то некритичные сервисы и так далее. То есть как ваши лабораторные в...

**[41:14]** домашних работах. У вас есть Docker Compose, вы же, если какие-то изменения внесли, вы что делаете? Вы выключаете Compose и включаете обратно. Вот вам типичный простой, и это вот, собственно, как раз про обычный самый деплой. Вот. Соответственно, частично эти вещи можно решить с помощью как это назвать? Частичного обновления. То есть, если у вас несколько сервисов, которые между собой связаны, допустим, как у вас дома есть Airflow и есть Spark,

**[41:44]** Вы можете весь выключить Compose и весь включить обратно, а можете сначала обновить Airflow, потом обновить Spark. Это чуть лучше, чем Basic, но в то же время не менее рискованная история. Здесь мы просто решаем проблему зависимости, потому что мало того, что когда мы выкатываем все целиком, у нас просто может сломаться, у нас еще и зависимости могут сломаться.

**[42:08]** Поэтому здесь, в общем-то, хоть и выкатиться быстро, но откатываться обратно все так же не быстро. И вот эта дополнительная абстракция в виде зависимости сервиса друг от друга, конечно, усложняет дело. Но это базовые, конечно, такие способы, как это деплой. То есть на нормальных, хороших продакшенах есть более крутые. Вот они слева направо, что называется. Первое это Blue Green Deploy.

**[42:34]** То есть у нас есть две идентичные среды, а ниже два плеча, так называемых, между которыми, которые, соответственно, могут принять на себя трафик. То есть идея в чем? Вторая у нас обычно среда, второе плечо, второе нода, как хотите, она простаивает и просто ждет. И, соответственно, вы как делаете? Вы обновляете вот эту ноду, которая простаивает, на которой...

**[43:03]** трафика нет. Вот это вот плечо вы обновляете новым релизом, на нем проверяете, что все взлетело и прочее, и потом вот резко, собственно, на этом этапе переключаете трафик на вот это плечо.

**[43:37]** Это быстро, удобно и, главное, очень хорошо тестируется. Но минусы в чем? Очевидно, дорого, потому что мы, по сути, держим две копии прода полноценные, и одна из которых просто простаивает все время. Плюс вот это переключение, оно, к сожалению, не мгновенное. То есть оно быстрое, но не мгновенное, и поэтому если в данный момент какой-то тяжелый запрос выполняется, он может что-то там сломать. К сожалению, это неизбежно.

**[44:04]** Примерно так. Так что в критичных инфрах часто используют Blue Green довольно популярный диплой. Не менее популярный диплой канарейчный. Идея в чем? Так, сейчас, секунду.

**[45:00]** Извиняюсь. На чем мы тут? А, канаричный деплой. Тут идея в чем? Что у нас тут необязательно иметь дополнительное плечо. Нам достаточно иметь вторую версию сервиса, которую мы можем поднять. То есть для этого целое плечо необязательно. Мы можем просто поднять рядом вторую версию сервиса и переключать трафик. То есть вот мы подняли вторую версию, которая новее. И, например,

**[45:25]** направили 25 процентов пользователей на вот эту новую версию, а 75 оставили на старой. И проверяем, смотрим, что 25 процентов нормально на новой версии живут, ничего не упало и прочее. Мы потихоньку увеличиваем, пока весь этот процент пользователей не перекатим на новую версию. То есть это удобнее, это дешевле, чем Blue Green, это быстро откатить обратно. Что супер приятно, тестируется на реальных пользователях.

**[45:51]** но в то же время в малом количестве, то есть не все это столкнутся. Поэтому это наименее рискованная стратегия и очень классная. Очевидно, ее минус это капец сложно, потому что тут, что у вас, две по сути точки входа, две копии в этом блюгрине, и вы просто выбираете, куда задеплоиться. Здесь вот эта вот деплойная штука, которая все делает, она должна быть чуть поумнее настроена, чтобы, соответственно, уметь перераспределять трафик, например. Что типа мы можем туда и туда,

**[46:21]** прочее. То есть если брать Docker Compose, например, то это бы выглядело как? В Docker Compose версии 2 есть, например, такой параметр как реплики. И вы можете поднять один и тот же сервис в двух разных контейнеров и в одном указать количество реплик 2 из 10, в другом 8 из 10. И в итоге балансировка будет между этими 10 репликами, но

**[46:50]** в 8 из 10 случаев они будут попадать на старую реплику и в 2 на новую. То есть такой искусственно созданный канареечный деплой. Так что да, это чуть-чуть сложнее реализовывать. Это фактически тест на реальных пользователях в Prode, что конечно приятно с одной стороны, что с другой не очень безопасно. Ну и понятно, это надо обкладывать хорошим количеством мониторинга и метрик, чтобы это все прям хорошо отслеживать. Такая вот история. АП-тестирование.

**[47:20]** это в общем да да пока далеко не ушли два вопроса есть первый вот про плечо в blue green я думаю плечо вы имеете ввиду и так просто другой инстанс в чем разница тогда между плечом и другим инстансом то есть мы же тоже можем его поднять она просто будет ну да где-то существовать и мы просто туда трафик не будем гонять и

**[47:48]** По сути так и есть. Смотри, то есть просто в случае с плечами у нас полные копии, и если это нескольких сервисов, то это полные копии. То есть это копия стенда, а не сервиса. Если супер упрощать, это два кубера. То есть два кубера, у каждого есть свои балансировщики, и ты буквально трафик пользователей перегоняешься с одного кубера в другой. Здесь же чаще всего это на уровне сервисов делается. Это во-первых. Во-вторых,

**[48:18]** технически за вопрос закономерный и что нам мешает вместо сервисов тоже здесь делать куберы так тоже можно тут разница в динамическом разделении потому что в blue green есть возможность только переключить трафик а вот если есть техническая возможность реализовать разделение этого трафика на чуть-чуть тогда это будет уже кэнери но по сути да они очень похожи между собой и здесь и здесь могут быть два плеча используешь ли ты их оба балансировки или нет вот примерно так

**[48:49]** Понял. А вот второй вопрос. Вы говорили в Docker Composer про реплика сеты, условно, и способ с помощью них трафик раскидывать. А вот это же, я так понимаю, просто с балансировщиком тоже можешь делать? Да, абсолютно. В Docker Composer уже встроили свой балансировщик, и он умеет сам это делать. Но ничего тебе не мешает внешне самому настроить какой-нибудь хапрокси.

**[49:19]** и прочее. Понял. Спасибо. Вот. АВ-тестирование. Как говорит мой коллега один, вот это вот АВ-тестирование и фич и флаг, с одной стороны, не совсем правильно считать полноценными стратегиями деплоя, потому что здесь это больше про на уровне бизнеса работает, на уровне фич, а не на уровне техники. Но, тем не менее, их обычно включают. Вот.

**[49:48]** Здесь какая идея, что похоже немножко на Canary. Здесь у нас изначально тоже две ноды, два плеча, две версии сервиса, без разницы как мы хотим, которые обе работают, и мы выкатываем какие-то мелкие изменения только на одну. То есть разница в том, что здесь у нас есть разделение трафика,

**[50:13]** То есть частичное. Здесь оно полное. И, соответственно, кто-то может попасть на ноду, где новая фича уже включена, а кто-то может попасть, где нет. То есть, по сути, это чуть-чуть похоже на Canary с шансом 50% трафика. Примерно так это выглядит. То есть, это про экспериментирование больше, чем про именно...

**[50:36]** deployment. И это чаще всего используют для тех случаев, когда мы не просто выкатываем новую фичу и проверяем, как она будет работать дальше. Это мы берем обычно для тех случаев, когда нам надо проверить, хотим ли мы вообще эту фичу. То есть, условно говоря, если брать конкретные примеры, вот здесь на первом и втором этапе мы включаем TLS на Postgres. И проверяем, что все у нас сервисы умеют по секьюрному каналу подсоединяться к Postgres.

**[51:06]** А вот здесь мы включаем какой-то функционал в приложении и смотрим, насколько он вообще себя показывает, насколько им пользуются и прочее. И если что, потом вообще убрать его и больше не использовать. То есть это вот именно про экспериментирование на уровне кода. Поэтому диплой здесь супер-то, в общем-то, и не важен. Просто технически надо уметь реализовать выкатку только на какую-то одну конкретную часть. Ну, это такая же сложность, как в Кеннери примерно. И более точечный вариант этого же решения – это фича флаг.

**[51:35]** Это когда у нас нет нескольких вариантов, то есть физически, например, финансовой возможности нет, иметь две копии, какие-то плечи и прочее. И мы, по сути, выкатываем один и тот же код, но внутри кода реализуем фича флаги. То есть вот та же интеграция с другим сервисом. Мы, грубо говоря, выкатываем тот же код, но включаем, например, интеграцию с RevitMQ false. И потом в моменте прямо на проде мы можем, соответственно, включить эту штуку.

**[52:02]** и проверить, как это будет работать. И потом обратно выключить. Примерно так это выглядит. Ну и стандартный rolling update, примерно как это в том же кубере работает. То есть, когда у нас сервисы состоят из нескольких реплик, мы их обновляем постепенно. То есть, допустим, сервис из трех реплик, мы один...

**[52:30]** одну реплику обновляем, две остальные старые, и они все еще принимают на себя трафик. Потом вторая реплика обновляется, мы проверяем, что все нормально. И потом, только когда все три реплики обновились на новую версию, мы пускаем трафик на это. То есть, в общем-то, в каком-то смысле более простая версия Blue Green Deploy. То есть, например, Кубер имеет такое из коробки.

**[52:54]** Ну и, соответственно, да, тут из минусов надо понимать, что приложения должны быть полностью стейтлесс, и вот эти две вещи должны существовать вместе, старое и новое. И это ничего не сломает на уровне баз данных, например, и прочее. Вот. В целом, теперь все, что я хотел сегодня рассказать. Наверное, то есть мы с вами поговорили про CACD, про гид-ветвление и про варианты диплоймента, которые у нас бывают. В следующий раз мы поговорим уже, продолжим эту тему, но уже...

**[53:24]** более конкретных примерах как это делается в GitLab и как делать его в ICD. Как раз собственно к вашей лабе. Вот примерно так. Еще есть ли вопросы? Да, вот по последнему слайду, по rolling апдейтам, вы говорите, что у нас условно там три реплики, они постепенно накатываются, обновления, да? И вот если у нас одна

**[53:53]** обновилась, две остались. А мы как проверяем ее работоспособность? То есть на нее же тоже какая-то нагрузка уже начинает идти? Нет. Как условно у них там по 33 процента сейчас нет? Нет, нет, нет. То есть, во-первых, отвечая сразу на два твоих вопроса, я специально сказал, нагрузка на них не идет. В rolling аптейтах у нас мы постепенно обновляем реплики и трафик на них идет только когда все три обновлены. То есть вот в этом этапе весь трафик пойдет на одну вот эту бедную одну реплику. Потому что

**[54:23]** Пока у нас все не обновились, мы трафик на новые не пускаем. Отвечая на вопрос, как это проверять, обычно это делает система деплоя или оркестрация. Если берем, например, Kubernetes, то у него есть такая сущность, которая называется пробы. И он, соответственно, когда обновляет все эти версии, он делает пробы, буквально, не знаю, 9-point стукнется или пинганет что-нибудь. Если сервис ответит так, как он ожидается, что должен ответить, то Kubernetes считает, что все, этот сервис готов,

**[54:53]** принимать на себя трафик вместо желтого. Вот примерно так. Если хоть одна из проб не пройдет, то вот этот контейнер не умрет. То есть каждый контейнер, каждая реплика соответственно обновляется только после того, как успешно обновилась и прошла пробы предыдущая. Вот примерно так. Даже в компози это можно сделать, если мы будем добавлять сложные хелс-чеки. Вот примерно так. А если, например,

**[55:20]** такой случай в теории. Вот эти два уже обновились, на один идет нагрузка, и вот он решит условно упасть из-за чрезмерной нагрузки. Можно ли как-то автоскейлинг тут же настроить или что случится? Вот интересно. Ну, к сожалению, нет, потому что эти две вещи будут друг другу противопомешать. То есть ты, как сказать, автоскейлер, например, будут думать, то есть он

**[55:45]** либо будет горизонтально скейлит этот желтый еще какое-то количество, но он в то же время обновляется, и это все как-то помешает. Либо он будет скейлить вот эту штуку, на которую еще трафик не идет. Так что ты довольно хорошо заметил, что действительно может быть потенциально такая проблема, что если обновление совпадет с огромной нагрузкой на сервис, то очень действительно вероятна ситуация, что он загнется. Но обычно это редко происходит просто потому, что сам апдейт происходит довольно быстро.

**[56:14]** То есть вот это обновление, оно graceful, что называется, и оно учитывает состояние, в котором сейчас находится контейнер. То есть нет такого, что прошло какое-то время, и он резко начал убивать желтую реплику и делать ее фиолетовой. То есть он проверяет, что она в данный момент делает, и gracefully завершает ее, чтобы все операции, которые были на данный момент в желтой реплике, по возможности завершились. И поэтому чаще всего по этой причине...

**[56:42]** Это может висеть даже чуть дольше, пока эта штука вся завершит свои операции. Пока на уровне линкса его не прибьет, потому что там тоже есть свои треш-оуды, то есть сколько может выполняться graceful shutdown. По умолчанию 30 секунд. Если, конечно, за 30 секунд ты не успеешь доделать все, что ты делал в желтой реплике, она прибьется уже килом. И тогда да, есть, конечно, риск, что ты что-то там сломаешь или прочее,

**[57:12]** так далее. Но, повторюсь, это довольно быстро происходит и редко так бывает, что она начинает загибаться, пока обновляется. Вот, примерно так. Понял. Спасибо. Так, еще вопросы? Ну, супер. Тогда вроде бы у меня все. Напоминаю, что следующее занятие у нас

**[57:41]** мы пропускаем потом наверстаем его но и частично я сегодня рассказал больше чем планировал вот 4 мая выходной будем у нас с вами вот и соответственно 11 мы встречаемся как обычно вот тогда на этом у меня все всем спасибо что пришли и хорошего вечера спасибо спасибо
