Понимание разницы между СI и СD: «если что-то вызывает боль, делайте это почаще»

Автор оригинала: Костис Капелонис
  • Перевод
  • Tutorial
Disclaimer. Костис Капелонис — Developer advocate (человек, защищающий и отстаивающий принципы программной разработки) Codefresh, первой платформы CI/CD для Kubernetes и контейнеров. Миссия Codefresh «Автоматизировать и упрости всё, от кода до облака». Как инженер-программист, Костис имеет многолетний опыт контейнеризации приложений, построения конвейеров CI/CD и разработки приложений Java. Он живет в Греции и любит кататься на роликах.

Как гласит пословица, «если что-то вызывает боль, делайте это почаще». Непрерывная интеграция — это, по сути, повторение шага интегрирования с высокой частотой, чтобы облегчить вызываемую ею «боль». Статья именно об этом — о «боли» разработки и способах её уменьшить.

Существует много информации о непрерывной интеграции (CI) и непрерывной доставке (CD). Публикации в блогах с помощью технических терминов пытаются объяснить, что означают методологии CI/CD, что они делают и как они могут помочь вашей компании. К сожалению, часто обе эти методологии связывают с конкретными инструментами или даже поставщиками ПО. Типичный разговор на эту тему в компании звучит так:

— Вы используете непрерывную интеграцию в вашей команде?
— Да, конечно, мы используем инструмент X!

Позвольте мне раскрыть вам маленький секрет. Непрерывная интеграция и доставка – это два подхода к разработке кода, которые совершенно не связаны с конкретным инструментом или поставщиком. Несмотря на то, что существуют инструменты и решения, которые могут помочь вам в обеих случаях (например, Codefresh), в действительности компания может практиковать CI / CD, используя только сценарии bash и однострочники Perl. Ээто не очень практично, но, безусловно, вполне возможно.

Поэтому, вместо того, чтобы попадать в общую ловушку объяснения сути CI/CD с помощью инструментов и технических терминов, мы объясним, что представляют собой эти методологии, опираясь на самый важный фактор процесса разработки – людей!

История о людях: «тяжёлые времена» программной интеграции


Познакомьтесь с Алисой, Бобом, Чарли, Дэвидом и Элизабет — все они работают в компании SoftwareCo Inc. над созданием приложения SuperBigProject. Алиса, Боб и Чарли — разработчики. Дэвид — инженер-тестировщик, а Элизабет — руководитель проекта команды.

Традиционный способ разработки приложения заключается в следующем: Алиса, Боб и Чарли работают над тремя различными функциями на своей рабочей станции. Каждый разработчик пишет и тестирует код в индивидуальном порядке. Они используют длиннющие ветви функций, которые существуют в течение нескольких недель или даже месяцев, прежде чем быть объединенными в конечный продукт.



В какой-то момент руководитель проекта Элизабет собирает всю команду и говорит: «Народ, нам уже нужно выпустить релиз, так что вы постарайтесь»!

После этого Алиса, Боб и Чарли пытаются интегрировать все свои три функции в одну ветвь. Это очень напряженное время, потому что эти функции никогда не тестировались вместе. Многие ошибки и проблемы появляются из ниоткуда, из-за неправильных предположений или проблем с окружением, потому что, если вы помните, до этого момента все функции были просто протестированы на разных рабочих станциях, изолированных друг от друга.

Как только «интеграционная лихорадка» закончится, объединенный результат передается Дэвиду, который выполнит дополнительное ручное и автоматическое тестирование. Этот период также занимает много времени, поскольку именно Дэвид может одобрить или заблокировать релиз в зависимости от того, сколько критических ошибок найдено. Все пристально наблюдают за Дэвидом, пока он делает свою часть, так как его тестирование может выявить серьезные проблемы, способные отложить релиз продукта.

Наконец, тестирование завершено, и Элизабет радостно объявляет, что программный продукт готов к упаковке и отправке на продакшн.

Итак, как же чувствуют себя люди в этой воображаемой, но очень реалистичной истории?

  • Разработчики Алиса, Боб и Чарли недовольны, потому что они всегда узнают о проблемах интеграции прямо перед выпуском. Период интеграции похож на перестрелку, в которой пули прилетают одновременно со всех сторон.
  • Тестировщик Дэвид постоянно нервничает из-за «дерганного» характера своей работы — бывают спокойные периоды, когда он просто ждет, пока разработчики закончат работу над функциями, а бывает фаза тестирования, когда он просто завален работой и должен иметь дело с неожиданными сценариями тестов, к тому же в это время команда разработчиков буквально стоит у него за спиной.
  • Элизабет, как менеджер проекта, тоже недовольна. Этап интеграции — это критическое звено проекта. Это напряженный период, так как любая неожиданная проблема отодвигает выпуск продукта. Элизабет мечтает о релизе программного обеспечения без всяких сюрпризов, но на практике этого никогда не происходит. «Попадание» этапа интеграции в запланированные сроки проекта — это всегда игра в «угадайку».

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

Итак, здесь единственной и основной проблемой является фаза интеграции, которая имеет место при каждом выпуске программного продукта. Это болевая точка рабочего процесса, которая не позволяет команде программистов освободиться от стрессовой ситуации, связанной с релизом программы.

Добавляем непрерывность в интеграцию


Теперь, когда мы увидели, что означает «интеграция», очень легко понять, что означает «непрерывная интеграция». Как гласит пословица, «если что-то вызывает боль, делайте это почаще». Непрерывная интеграция — это, по сути, повторение шага интегрирования с высокой частотой, чтобы облегчить вызываемую ею «боль».

Наиболее очевидным способом сделать процесс менее болезненным – это выполнять интеграцию чаще, после каждого слияния функций, вместо того, чтобы ждать официального релиза.



Когда команда практикует непрерывную интеграцию, то:

  • Все объекты объединяются непосредственно в главную ветвь (mainline).
  • Разработчики работают совместно, а не изолированно. Все функции разрабатываются из основной линии.
  • Функция считается разработанной, если mainline полностью исправна и работает на любой машине, а не только на отдельной рабочей станции.
  • Тестирование происходит автоматически как на уровне отдельных элементов или объектов кода, так и на уровне mainline.

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

Непрерывная интеграция в процессе разработки программного обеспечения превосходит обычную интеграцию, потому что:

  • Уменьшает количество сюрпризов, появляющихся при слиянии объектов кода.
  • Решает проблему «программа работает только на моей машине».
  • Разбивает период тестирования на несколько периодов, где каждый объект кода постепенно сливается с основной линией, вместо одновременного слияния всех объектов сразу.

В результате команда, использующая CI, не чувствует себя как на американских горках, когда спокойные периоды развития перемежаются стрессовыми релизами. Кроме того, она получает возможность трезвой оценки того, насколько проект близок к завершению, вместо того, чтобы угадывать сроки релиза. Использование CI является одним из столпов современной разработки программного обеспечения. На сегодня этот метод очень хорошо документирован и достаточно известен. Поэтому не может быть никакого оправдания тому, что ваша компания до сих пор не практикует CI при разработке программных проектов.

«Тяжелые времена» доставки программного обеспечения


Теперь, когда мы рассмотрели историю обычной интеграции и то, как работает непрерывная интеграция, мы можем перенести это на следующий уровень процесса разработки — непрерывную доставку. Если мы вернемся к нашей оригинальной истории, то увидим картину, аналогичную процессу обычной интеграции:



Выпуск продукта по сути был событием сродни «большому взрыву». После того, как программное обеспечение считалось протестированным, кто-то должен был выполнить процесс свертывания и развертывания ПО из контейнеров. Развертывание программного обеспечения на продакшене также было очень напряженным периодом и традиционно включало много ручных шагов и выполнение контрольных процедур. Развертывания происходили очень редко, и даже сегодня есть компании, которые выполняют эту процедуру не чаще, чем раз в полгода. Лишь в крайних случаях развертывание происходило за один раз – при использовании каскадной модели разработки ПО (waterfall).

Доставка программного обеспечения только после достижения дедлайна создает те же проблемы, что и обычные, нечастые интеграции:

  • Рабочая среда обычно отличается от среды тестирования, что требует дополнительной настройки в последнюю минуту.
  • Функции, которые нормально работали в тестовой среде, в рабочей среде «ломаются».
  • Функции, которые не были готовы на момент выпуска, либо вообще никогда не предоставляются клиентам, либо их доработка отодвигает релиз еще дальше.
  • В связи с этим релизы создают напряженность между разработчиками, желающими добавлять новые функции для расширения функционала ПО, и операторами, которые желают стабильности и не хотят развертывать сразу слишком много новых функций.

Решением данной проблемы является тот же шаблон, что и в случае интеграции. Если мы можем облегчить болезненность процесса интеграции, делая её чаще, то мы сможем проделать то же самое в процессе доставки ПО.

Добавляем непрерывность в доставку


Непрерывная доставка — это практика упаковки в контейнеры и подготовки программного обеспечения, как если бы оно отправлялось на продакшн, так часто, как насколько это возможно. И самый экстремальный способ доставки — после каждого слияния функций.



Таким образом, CD продвигает CI на шаг вперед. После слияния каждой функции с ветвью mainline приложение не только проверяется на корректность, но и упаковывается и развертывается в тестовую среду, которая идеально соответствует рабочей среде. Все это происходит в полностью автоматическом режиме — обратите внимание на отсутствие на рисунке человечков, которые обозначают ручные процедуры.

Также примите во внимание, что каждая новая функция является потенциальным кандидатом для запуска в производство. На практике не все кандидаты отправляются на продакшн. В зависимости от организации процесса, принятие решения о развертывании в продакшн иногда требует вмешательства ответственного человека, который решает, отправлять ли релиз в производство или нет, но при этом лично не принимает участия в подготовке релиза. К этому моменту релиз уже упакован, протестирован и развернут в тестовой среде.

Непрерывную доставку (СD) осуществить немного сложнее, чем непрерывную интеграцию (CI). Причина в том, что, поскольку каждый кандидат на выпуск потенциально может достичь продакшена, полный жизненный цикл должен быть автоматизирован:

  • Сборки должны быть повторяемыми и детерминированными.
  • Все шаги должны быть автоматизированы, что довольно сложно реализовать на практике.
  • Все конфигурационные и связанные файлы должны существовать в системе управления версиями, а не только в исходном коде.
  • Каждая функция/выпуск должна быть протестирована в своей собственной, динамически создаваемой и динамически уничтожаемой тестовой среде.
  • Все наборы тестов должны быть автоматизированы и относительно быстры, что также представляет собой нелегкую задачу.

Хотя «облако», безусловно, может помочь осуществить все эти требования, команде программистов, как разработчиков, так и операторов, необходим определенный уровень дисциплины, действительно обеспечивающий процесс непрерывной доставки ПО.

После внедрения CD релизы становятся рутинной процедурой, как если бы осуществлялись простым нажатием кнопки. Каждый член команды, а не только руководитель проекта, может видеть текущего кандидата на релиз. У этого кандидата могут отсутствовать некоторые требуемые функции или же он может не полностью удовлетворять всем требованиям, но это совершенно не важно, пока не затрагивает самого процесса релиза.

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

Если вы используете CD, жизненный цикл программного обеспечения можно представить следующим образом:



Каждый кандидат на релиз всегда готовится заранее. Человек решает, будет ли кандидат на релиз также выдвинут на продакшн. Кандидаты на выпуск, которые не достигают продакшена, продолжают храниться как артефакты на тот случай, если их понадобится использовать в будущем.

К вашему сведению, о непрерывной доставке, как и о непрерывной интеграции, также написана целая книга, из которой можно узнать подробности этой методологии.

Бонус: непрерывное развертывание


Буква «D» в CD может означать развертывание Deployment, а не доставку Delivery. Этот подход к процессу развития основывается на непрерывной доставке и, по существу, полностью устраняет вмешательство человека. Любой кандидат на выпуск, который пройдет все тесты и проверки качества и будет признан готовым, немедленно отправляется на продакшн.



Следует признать, что лишь очень небольшое количество компаний способно работать таким образом. Продвижение на продакшн без участия человека не должно восприниматься легкомысленно, так как на момент написания этой статьи многие компании не практикуют даже непрерывную доставку, не говоря уже о непрерывном развертывании.

Вы должны понимать, что каждый следующий подход к процессу развития основывается на внедрении предыдущего подхода.



Прежде чем двигаться вверх по пути совершенствования, ваша компания должна убедиться, что каждая из основ процесса действительно прочна. Мы в Codefresh видели множество компаний, которые намеревались перейти к облачным технологиям, пытаясь переоборудовать на конвейерах CI/CD свои технологии, оптимизированные для использования в дата-центрах, при этом не понимая, что некоторые из этих технологий на сегодня устарели. Попытка внедрить непрерывное развертывание без полного охвата непрерывной доставки обречена на провал.

На следующем рисунке показано, какие стадии процесса разработки и внедрения ПО, осуществляемые Алисой, Бобом, Чарли, Дэвидом и Элизабет, охватывает CD и CI.



Убедитесь, что вы в правильном порядке подходите к каждой парадигме разработки ПО. Поверьте, что внедрение непрерывной доставки – весьма реалистичная цель, для реализации которой имеются все необходимые инструменты.

Немного рекламы :)


Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99, 30% скидка для пользователей Хабра на уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2650 v4 (6 Cores) 10GB DDR4 240GB SSD 1Gbps от $20 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

Dell R730xd в 2 раза дешевле? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?
ua-hosting.company
414,95
Хостинг-провайдер: серверы в NL / US до 100 Гбит/с
Поделиться публикацией

Комментарии 15

    +4
    сияй / сиди
      0
      Тестируют только трусливые программеры, смелые — правят код на проде!
        0
        Не смелые, а безумные. :-)
          +1

          Безумие и отвага!

            0
            Слабоумие и отвага! © не мой
            :-)
          0
          Ну, это как с пожилыми смелыми альпинистами — излишне смелый программист быстро перестаёт быть программистом (по меньшей мере на текущем месте работы).
            0

            безумные, которые не отвечают за последствия никак финансово!

              0
              Ну… Всегда можно свалить на менеджера.
              Хотели быстро — получили быстро! :-)
            –2
            Есть фичи которые большие и половинками их запихать низя, а если она трогает основные куски кода, а если таких фич не одна + рефакторинг и переделка данных, так что CD работает только с достаточно маленькими кусочками, а с большими только через релизы, УИ отлично работают с CD, так как всё достаточно локально, а рефакторинг они в принципе не делают(что мне очень не нравиться), в БЕ всё намного сложнее, надо впихнуть логику в общую чтоб не плодить кучу имплементаций одного и тогоже, но для разных стран, всё впихнулось теперь надо права допилить и придумать как старую структуру данных переделать под новую ничего не потеряв, все 3 таска никак нормально не распаралелить, ну разве что изначально будет спека уже техническая, но создание такой спеки тоже не распаралелись и она должна быть достаточно свежей, ведь пока её писали тоже могло появиться чтото новое или измениться. Как-то так ну или я просто ещё дурачёк и не знаю как сложные линейные задачи распаралелить.

            Вобщем иногда код это ракета и без того что сделаешь всё и правильно она не полетит :)
            но к CD надо как минимум стремиться
              +5

              Вот вам запас точек, не экономьте:


              ...............................................


              Возможно, после разбития потока мыслей на отдельные предложения, вы и фичи сможете разбить на более мелкие.

                0
                а если таких фич не одна + рефакторинг и переделка данных

                Тогда стоит делать это отдельными частями, именно так, как вы сказали (хотя переделку данных хорошо бы сделать вначале).

                УИ отлично работают с CD, так как всё достаточно локально, а рефакторинг они в принципе не делают

                Смотря кто. У меня в проекте он делается по необходимости.

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

                Для чего-то столь сложного спека нужна и без CI/CD. И еще хорошо-бы версионирование поодерживать.
                  0

                  правильная декомпозиция задач "карпаччо из слона" решает эти проблемы.
                  к сожалению, не все заказники к этому готовы, но это уже к вопросу не понимания agile

                    0
                    Попробуйте воспользоваться BETA/Feature флагами. Все что за флагом — выключено у всех, либо у тех, у кого флаг отсутствует. Таким образом если если код новый — вообще нет проблем. Если перемежается со старым — то да, добавляет complexity. Нет серебряной пули — по каждому коду нужно решать на месте уже. Однако обычно флаги хорошо работают и дают возможность использовать часть кода другими участниками проекта до того, как им будут пользоваться пользователи.

                    Также этот подход позволяет умирать быстро — если вдруг код ломает что-то, то это позволяет исправить ошибку до финального релиза — когда снимается флаг и функционал становится публичным.
                    +1

                    Всё верно написано кроме слова — дурачОк.

                      –1
                      Очень полезная статья. Хороший перевод, включая и иллюстрации. Такой перевод не часто встретишь. Надеюсь, ребята не забросят, будут новые качественные статьи

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое