Меня зовут Константин Кузнецов, в ПСБ я занимаюсь, в числе прочего, поддержкой ИТ-инфраструктуры.
В этой статье я расскажу о том, как концепция инфраструктурного релиза помогала формировать процессы обеспечения идентичности сред.
Если вы начинающий специалист в области ИТ-инфраструктуры, который видит своё будущее в ИТ-менеджменте — эта статья для вас. Думаю, вам будет полезно ознакомиться с вызовами и олдскульными способами их решения, основанными частично на ITIL, частично на devops.
Что такое среда и сколько их нужно
Давайте сразу договоримся: в рамках данной статьи среда = контур. Я буду использовать оба этих термина как синонимы. Речь идёт об обособленной совокупности инсталляций информационных систем, предназначенной для:
создания ценности для потребителей (прод);
каких-либо видов тестирования (тестовые среды);
или для разработки (dev).
Почему тестовых сред несколько и сколько именно их должно быть? Такой вопрос мне задали на одном из собеседований 10 лет назад. Отвечать на него конкретным числом не стоит. Давайте лучше рассуждать. И рассуждать мы будем с помощью треугольника эффективности: качество, деньги, скорость.
Качество
Каждая отдельная тестовая среда предназначена для отдельного вида тестирования (или группы видов тестов). Чем больше разновидностей тестов мы проводим, тем качественнее получается тестируемый продукт. Чем выше требования к качеству, тем больше видов тестирования и, соответственно, тем больше тестовых сред.
Перечень видов тестирования приводить здесь не буду — его можно легко найти самостоятельно. Отмечу лишь, что некоторые виды тестов можно проводить на одном и том же контуре. Например, функциональное тестирование и регресс. Или короткое нагрузочное и длительный стресс-тест. Таким образом, количество сред не обязательно должно равняться количеству видов тестов, которые проводятся у вас в организации.
Деньги
С другой стороны, наличие тестовых сред — это расходы как CAPEX (например, оборудование, лицензии), так и OPEX (например, фонд оплаты труда, аренда стоек, электричество). Можно услышать и такую точку зрения: «иметь тестовые среды, идентичные проду, очень дорого. Сколько же мощностей для этого потребуется!». Да, тестовые среды это дорого. Однако выбор на самом деле не между «дорого или дёшево». Вопрос стоит иначе: стоит ли экономить в краткосрочной перспективе, если при этом с высокой степенью вероятности реализуются риски (в том числе репутационные)? Для одних продуктов такая экономия оправдана, для других — нет. Отвечать на этот вопрос должен бизнес-заказчик проекта с ИТ-составляющей. Наша же задача — помочь ему с выбором, грамотно объяснив последствия каждого варианта и стоимость их реализации.
Добавлю, что большАя часть расходов приходится на оборудование (вычислительные мощности). Однако не для всех контуров необходимо соблюдать требование ресурсной идентичности. Исключение — контур нагрузочного тестирования, но про него я отдельно напишу чуть ниже.
Скорость
Речь, конечно же, про TTM (Time To Market). TTM — это про то, как быстро мы выкатим в прод очередную порцию хотелок: концепт, MVP, первый полноценный релиз, доработки (уязвимости, ошибки, новый функционал, дизайн, рефакторинг) и прочее.
Развертывание тестовых сред, их поддержка (в том числе поддержка их идентичности), прохождение всех тестов — всё это оказывает существенное (негативное) влияние на TTM. К счастью, заказчики это понимают, и аргумент «система не прошла тестирование» для них достаточно весом.
Можно ли обойтись одним тестовым контуром?
Технически - возможно. Закончив проводить один тестовый сценарий, мы, перенастраивая контур превращаем его в контур, пригодный для другого вида тестов. Выключаем заглушки, включаем интеграции и так далее. Да, проводить одновременно разные тесты в этом случае не получится, но в моей практике такая возможность никогда не была критичным требованием. Тем более, согласно конвейерному подходу, следующий вид тестирования должен начинаться только после успешного прохождения предыдущего.
Можно даже не перенастраивать контур, а выключить его (высвободив пул ресурсов) и включить другой тестовый контур на этом же пуле. Неважно, о какой технологии мы говорим — виртуализация или контейнеры. И там, и там есть пул ресурсов. В таком случае не придётся тратить время на перенастройку.
Если пул ресурсов ограничен, описанный подход вполне работоспособен.
Контур нагрузочного тестирования
В этом контексте, как и обещал, позволю себе ещё несколько слов про контур нагрузочного тестирования (НТ). Он заслуживает отдельного внимания.
Многие считают, что он (в отличие от других контуров) обязательно должен быть идентичен проду с точки зрения мощностей. Таким образом, расходы на оборудование составляют уже ×2 (прод и НТ). У меня есть сомнения. Давайте снова порассуждаем.
Нагрузочные тесты редко проводятся на интегрированных друг с другом системах. Обычно — на заглушках. Если на предприятии нет необходимости проводить НТ нескольких разных систем одновременно, то это означает, что можно использовать один и тот же пул ресурсов для последовательного проведения НТ разных систем.
А когда нагрузочное тестирование ни одной из систем не проводится, контур НТ вообще может быть выключен (все системы в контуре НТ остановлены), пул ресурсов высвобожден и может использоваться для других целей.
Но и это ещё не всё.
К вопросу «должны ли контуры прод и НТ быть идентичными с точки зрения ресурсов?». Прежде чем ответить, у меня есть встречный вопрос: а что вы хотите видеть в результате нагрузочного тестирования? TPS? RPS? FPS? Зелёные галочки в отчёте?
Лично я хочу видеть подробный сценарий управления производительностью (повышения или понижения) ИТ-системы. Своего рода отчёт-инструкцию по capacity management системы под разные профили её нагрузки. И эта инструкция должна отвечать и менеджерам и инженерам на вопрос: «Что нужно докрутить в системе, чтобы производительность изменилась в ту или иную сторону на нужное количество TPS/RPS/FPS?» Вспоминаем теорию ограничений — и вперёд.
Я хочу видеть минимальную (оптимальную с точки зрения ресурсов/мощностей/денег) комбинацию/конфигурацию, достаточную для безошибочной (или с допустимой степенью ошибок) обработки определённой нагрузки определённого профиля. И так — по каждой системе, по каждому профилю нагрузки и по нескольким значениям производительности (минимальное, максимальное и несколько промежуточных). Для каждого из этих значений должно быть расписано, как достичь минимальной конфигурации, обеспечивающей эту производительность. Чтобы понимать, как управлять ресурсами (в конечном счёте - деньгами) для повышения или понижения производительности.
Динамическая производительность в проде
В проде у вас вряд ли будет постоянное ожидание максимальной нагрузки по всем информационным системам и по всем профилям потребления. Зачем тогда греть воздух лишними мощностями? Необоснованная утилизация ресурсов — это ведь тоже про деньги. Потратив их на что-то ненужное, мы рискуем оказаться в ситуации, когда ресурсов на что-то действительно нужное уже не хватит.
Повышайте в проде производительность тех систем и под те профили нагрузки, которые действительно нужны в данный момент. Исходя из прогнозов бизнеса, исходя из трендов утилизации по данным мониторинга, исходя из опыта прошлых лет. И понижайте производительность тех систем, для которых сейчас нет необходимости жечь мощности.
Таким образом, состояние систем в проде с точки зрения ресурсов/мощностей (а иногда и конфигураций) становится динамическим. Одну систему ослабили, другую усилили. И так постоянно — маневрируя в условиях ограничения ресурсного пула.
Возвращаясь к идентичности НТ и прода
С учётом этого вернёмся к вопросу: “Должны ли контуры НТ и прода быть идентичными с точки зрения ресурсов?” Возникает новый (риторический?) вопрос: неужели мы НТ тоже будем постоянно подстраивать под динамически изменяемый (ресурсно) прод? Конечно же нет. Как я и говорил ранее, я считаю, что если нагрузочные тесты на системе не проводятся, то эту систему в контуре НТ можно (или даже нужно) выключить. А когда понадобится проводить нагрузочное тестирование этой системы, то мы её включаем с описанным выше подходом: поиск и фиксация комбинации конфигурационных/ресурсных состояний под разные показатели нагрузки.
В этом случае, как мы понимаем, НТ и прод не будут ресурсно идентичны. Прод динамически изменяется (высвобождая пул ресурсов одними системами и заполняя его другими), а НТ вообще выключен, пул ресурсов высвобожден или перераспределён на другие системы. И даже если его включить, он не будет (и, как я глубоко уверен, и не должен быть) ресурсно (а в некоторых случаях - и конфигурационно) идентичен проду по описанным выше причинам.
Это всё были рассуждения про конфигурацию мощностей (сколько выделять ресурсов из пула). Но ради справедливости надо заметить: сам пул ресурсов нужно где-то взять (купить или арендовать). Его размер, конечно, должен позволять проводить (точнее — проходить) нагрузочное тестирование с высокими показателями нагрузки. Возможно, даже превышающими требуемую на данный момент производительность системы в проде. Например, для оценки потенциала системы. Таким образом, пул ресурсов под НТ может быть даже больше, чем планируется выделять под прод.
Но вспоминаем: в проде все системы работают одновременно, а нагрузочные тесты мы зачастую можем проводить последовательно. Если у нас много систем, для каждой из которых надо проводить НТ, то покупать под каждую большой пул ресурсов кажется менее логичным, чем купить один общий пул (бОльший чем требуется одной самой требовательной системе, но меньший, чем сумма требуемых под все системы ресурсов) и определять очерёдность проведения нагрузочного тестирования на этих системах.
А как происходит на самом деле?
Хорошо, если есть инструмент нагрузочного тестирования и заглушки, позволяющие имитировать интеграцию. Запускаем какую-то очень высокую нагрузку. Если ошибок не было — выставляем в проде столько же ресурсов +10% «на всякий случай». Если были ошибки — «все расходимся думать, как поднять производительность»…
С нагрузочным тестированием разобрались.
Остальные тестовые контуры (а также контур разработки, т. н. dev) тоже не должны быть идентичны проду с точки зрения ресурсов. Таким образом, мы приходим к выводу: тезис «N контуров ⇒ ×N затрат» неверен и является заблуждением.
Идентичность контуров
Что это? Для чего она вообще нужна? Можно ли её добиться? Нужно ли это делать?
Что такое идентичность контуров
Идентичность — это в первую очередь состояние или степень соответствия, если хотите. Когда я говорю «идентичность контуров», я подразумеваю «идентичность и инфраструктуры в этих контурах, и инсталляций информационных систем в них».
Нужна эта идентичность для гарантии. Гарантии применимости тестов для принятия решения о степени готовности очередной версии чего-либо (например ПО) для её выпуска в прод (релиз). Или гарантии того, что в случае необходимости найти решение какой-либо ошибки, воспроизведённой на тестовом контуре, это решение подойдёт и для прода. Короче — для гарантии качества. По-английски, кстати, гарантия качества — Quality Assurance (сокращённо QA).
Можно ли добиться полной идентичности?
Да, но так никто не делает, потому что это неоправданно дорого. И в большинстве случаев в этом нет необходимости. Одинаковые IP-адреса, одинаковые hostname, сертификаты, имена пользователей, пароли… всё это и многое другое не даёт позитивного эффекта для гарантии качества. А в некоторых случаях даже вредит (например, с точки зрения информационной безопасности).
Поэтому, говоря «идентичны», мы подразумеваем «условно идентичны». Условно — потому что есть условие: «Если то, что влияет на гарантию качества, идентично, то степень идентичности всего остального не имеет значения». Другими словами, остальное (hostname, ip и прочее) может быть разным, и это не будет влиять на наше суждение о степени идентичности этих контуров.
Как мы уже говорили ранее, идентичность бывает:
ресурсная (мощности и пр.);
конфигурационная (настройки и пр.).
Когда кто-то говорит просто про «идентичность контуров» (не уточняя явно, какую именно идентичность он имеет ввиду), то мы обычно думаем, что он подразумевает оба этих аспекта сразу. Поэтому возьмите за правило уточнять.
Уточнённое определение
Итак, мы говорим «идентичность контуров», но подразумеваем «условную, конфигурационную и ресурсную (если явно не указано иное) идентичность инсталляций одной и той же системы в разных контурах, обеспечивающую гарантию качества этой системы за счёт валидности (применимости) результатов её тестирования».
Конфигурационная идентичность
Под конфигурационной идентичностью мы подразумеваем не только и не столько конфигурационные файлы программного обеспечения (хотя, конечно, и их тоже). В первую очередь это касается архитектуры системы и версий всех компонентов, из которых она состоит: ОС, библиотеки, прикладное ПО и так далее.
Более того, конфигурационные файлы как раз чаще всего отличаются на разных контурах. Но их отличие должно быть только в тех аспектах, которые не влияют на гарантию качества (ip, hostname, certificate, passwords и т.п.).
Как обеспечить конфигурационную идентичность
Для этого можно, например, в шаблонизаторе Jinja для Ansible жёстко задавать (hardcode) то, что должно быть одинаковым. А остальное параметризовать переменными и объявлять их через переменные инвентаря соответствующего контура.
Почему среды изменяются с течением времени
Главный и отчасти философский принцип: если система не изменяется, значит, она мертва.
Изменения нужны и обусловлены либо вынужденной реакцией — адаптацией системы под меняющийся контекст или потребности, либо носят проактивный характер — в силу естественного «принципа роста и развития систем» или каких-либо прогнозов.
Оставлять всё как есть — значит выигрывать в краткосрочной перспективе (ничего не меняли — не будет сбоя). Но в долгосрочной — обрекать себя на удорожание поддержки устаревших компромиссных решений и набора неподдерживаемых вендорами версий.
Конфигурационный дрифт
Существуют также неконтролируемые или неавторизованные изменения — конфигурационный дрифт (configuration drift). Он превращает наши системы из серверов-фениксов в серверы-снежинки.
Для справки:
Сервер-феникс - это такой сервер, управление конфигурацией которого позволяет нам достаточно легко его восстановить, если мы его вдруг случайно потеряли (сломали, удалили). Как птица Феникс - возрождаться из пепла.
Сервер-снежинка - противоположность серверу-фениксу. Название происходит оттого, что каждая снежинка уникальна. Потеря уникального сервера (уникальной комбинации ПО и конфигураций) крайне болезненна, ведь воссоздать или воспроизвести его почти невозможно.
Бороться с такими изменениями можно по-разному. Лучшее на мой взгляд техническое решение (хоть и не панацея) — контейнеризация. Помимо неё:
запреты (и соответствующие санкции) на внесение неавторизованных изменений;
выполнение мажорных обновлений (например, ОС) через свежие инсталляции из новых базовых состояний (шаблонов ВМ — для виртуализации, или базовых образов — для контейнеризации);
запрет на использование latest-версий — переход на явное указание тегов (как для базовых образов в контейнерах, так и для ролей или плейбуков в IaC/Ansible).
Обратная сторона этого подхода — version hell. Это и необходимость фиксации всех версий всех компонентов, и вынужденная поддержка зоопарка версий. Спасает регулярное принудительное (например, в рамках квартальных задач) обновление до последних стабильных версий и тегов везде, где это возможно — начиная с Git и Dockerfile и заканчивая заморозкой репозиториев (provisioning content view в Foreman/Katello). Либо можно использовать какие-то «костыли», либо смириться и следовать принципам DevOps, исправляя latest по мере поступления проблем.
Был как-то случай: проверенный на тестовых контурах плейбук применили к проду и вызвали сбой. Причина:
плейбук описывал установку ПО последней (latest) версии;
тестировался он за пару месяцев до внедрения в прод;
за эти два месяца в репозиториях появились более свежие версии ПО, несовместимые с конфигурационными файлами.
Дальше понятно. Нам с вами понятно. А бизнесу — не очень, почему мы это не предвидели и не предотвратили.
Регулярный DR
Полезна также регулярно проводимая процедура Disaster Recovery (DR), когда стенд зачищается (выключается или удаляется) и восстанавливается по заранее сформированному сценарию (плану). Не имеет значения, делаете вы это автоматизированно (например, с использованием практики IaC) или руками (по инструкциям). Результаты тестов восстановленной таким образом системы показывают качество сценария (плана). Вы его применять будете на проде, когда (не дай бог) утром какого-нибудь понедельника вам скажут: “На выходных мы потеряли ЦОД, вот вам новый. Настройте там всё так же, как было в старом.”
Кто-то из вас наверное сейчас вспомнит про бэкапы и пойдёт проверять наличие свежих резервных копий своих критических систем. Рекомендую настроить мониторинг (метрики и алерты) на проверку наличия этих бэкапов.
Изменения, которые не требуют change management
Надо отдельно сказать, что бывают изменения, которые не проходят через процесс change management. К ним относится штатная вариативность (параметризация, заложенная в архитектуру системы или компонента). Её изменение не влияет на качество и не нуждается в отдельном тестировании.
Например:
для прикладного ПО — изменение конфигурационного файла без выпуска новой версии;
для контейнеров — переменные окружения (env);
для IaC/Ansible — group/host-vars, объявляемые в инвентаре того или иного контура (хотя вопрос, конечно, спорный, т.к. роль/плейбук может быть написан таким образом, что от изменения vars логика работы автоматизации может кардинально меняться).
При анализе планируемого изменения я рекомендую каждый раз оценивать его влияние на качество системы в целом и на качество тестирования в частности.
Мы определили для себя следующий набор вопросов, помогающий принять решение:
Нужно ли предварительно прорабатывать (разрабатывать и тестировать) план отката этого изменения?
Нужно ли предварительно прорабатывать (разрабатывать и тестировать) это изменение и/или изменённую систему целиком?
Нужно ли предварительно прорабатывать (разрабатывать и тестировать) средства мониторинга, связанные с этим изменением?
Есть ли сомнения относительно полноты перечня пререквизитов для внедрения этого изменения в прод?
Может ли реализация этого изменения не во всех контурах (а лишь в части) привести к снижению степени их идентичности (а значит, к снижению валидности результатов тестирования и потере гарантии качества)?
Нужно ли оценивать влияние процесса внедрения этого изменения (простой/деградация, длительность)?
Влияет ли это изменение на какой-либо из видов тестирования других ИТ-систем (на валидность их тестирования), с которыми данная система имеет прямые или косвенные интеграции?
Вызвано ли это изменение требованиями к информационной системе в целом или оно обусловлено уникальными особенностями среды/контура/окружения?
Если хотя бы на один из этих вопросов ответ “Да”, то реализация этого изменения будет идти через change, который сначала попадает в бэклог. Оттуда (согласно приоритетам) берётся в очередную версию инфраструктурного релиза (аналог спринта) и идёт по всем контурам — от dev к проду — проходя все стадии тестирования (включая регресс и откат). В идеале нужно тестировать не только изменяемый компонент, но и всю систему целиком (включая прикладное ПО).
А бывают ещё запросы на изменение тестовых контуров. И их тоже нужно оценивать. Как минимум, с точки зрения идентичности: “А должна ли в проде (и остальных контурах) система измениться так же, как мы собираемся её изменить в тестовом контуре?” Если да, то это изменение тоже становится кандидатом на включение в бэклог и затем в очередной релиз. При этом реализация изменения в тестовом контуре (удовлетворение первоначальной потребности данного гипотетического сценария) будет выполняться в рамках тестирования данного релиза (который потом когда-то будет внедрён в прод).
Версионирование инфраструктуры
Совокупность версий компонентов информационной системы (мета-информация) в свою очередь тоже версионируется. Таким образом получается итоговая версия инфраструктуры информационной системы — зафиксированная комбинация версий всех её компонентов (например, плейбуков, ролей, инвентарей, дистрибутивов ПО и пр.). Со своим собственным жизненным/релизным циклом и дорожной картой.
Подготовка очередной версии может идти, например, по Agile или Scrum. Очередная стабильная версия, прошедшая все тесты и гарантирующая качество, объявляется готовой к выпуску в среду промышленной эксплуатации (релиз).
Преимущества инфраструктурного релиза
Подход с версионированием состояний инфраструктуры (инфраструктурный релиз) даёт:
возможность контроля и авторизации изменений;
контроль идентичности сред;
фиксацию состояния инфраструктуры, к которому можно откатиться или которое необходимо воспроизвести в любом из контуров;
более удобный учёт зависимостей между версиями прикладного ПО и инфраструктуры, на которой оно работает.
Есть правило: чем меньше изменений в релизе, тем ниже вероятность сбоя при внедрении и длительность простоя при диагностике сбоя. Отсюда следует, что в идеале нужно стремиться к множеству маленьких релизов (например, одно изменение на релиз). И стараться избегать смешанных релизов (когда меняется и прикладное ПО и инфраструктура), если в них нет явной необходимости.
Импортозамещение
Роль открытого ПО
Значение open source в России заметно выросло в контексте активного импортозамещения. Системы, базировавшиеся на импортных и зачастую монолитных технологиях, потребовалось в ускоренном режиме заменять — либо на отечественные решения, либо на собственную разработку.
Самым простым и быстрым решением стала реализация систем, собранных из комбинации open source-компонентов (без поддержки или на поддержке у отечественных вендоров) плюс минимальная (насколько это возможно) разработка прикладного ПО. И всё это — на базе микросервисной архитектуры или распределённого монолита.
В контексте инфраструктуры как код Open source-компоненты — это инфраструктурная составляющая: программные балансировщики, reverse-прокси, брокеры сообщений, сборщики журналов событий, service discovery и прочее. Базы данных не называю отдельно, так как они и так были «на выносе», и их импортозамещение в основном связано с миграцией с одной технологии СУБД на другую.
С точки зрения управления всем этим opensource-хозяйством всё сводится либо к технологиям оркестрации контейнеров, либо к DevOps-практике «инфраструктура как код». Оба подхода не являются взаимоисключающими и при грамотной организации взаимодополняют друг друга.
Из IaC я больше знаком с технологией Ansible, но и она имеет недостатки. Один из них — отсутствие встроенного в архитектуру механизма штатного отката. Действуем по всем канонам DevOps: изменения применяются только вперёд. Таким образом, откат — это процедура, закладываемая в очередную версию кода инфраструктуры и разрабатываемая сопровождающим персоналом. Либо используется другой подход: компонент системы полностью удаляется, после чего разворачивается из базового состояния, на него накатывается нужная (или предыдущая, последняя стабильная) версия кода инфраструктуры (вот он - сервер-феникс), а изменяемые данные восстанавливаются из резервной копии. При этом соблюдаются требования доступности (RTO и RPO), определённые для технического окна системы (исходя из класса критичности этой системы и оставшегося в отчётном периоде допустимого совокупного простоя согласно SLA).
Консистентность
Действительно ли контуры должны быть идентичными?
Возможно, кто-то скажет: «Конечно! Нам же нужна гарантия качества! Ты сам это только что сказал». Здесь я тоже позволю себе порассуждать.
Допустим, у нас есть система, представленная в нескольких контурах (включая прод), и во всех контурах она идентична. Но как только нам понадобится внести в неё изменения, мы (по конвейерному принципу) вносим их сначала в один из контуров — очевидно, в dev. И эту идентичность мы намеренно нарушаем. Затем мы вносим те же изменения в тестовый контур. Контуры dev и тест в этот момент становятся идентичными, но остальные контуры (включая прод) отличаются от них (оставаясь идентичными между собой). При отсутствии процессов контроля идентичности, при неавторизованных или не продублированных в остальные контуры изменениях, при дрифте конфигурации, появлении серверов-снежинок и других факторах некогда идентичные контуры с течением времени становятся всё более различными. А через несколько лет трудно будет поверить в то, что они когда-то были идентичными. Возникает иллюзия контроля и путаница, следствием которой становится снижение качества продукции.
Терминология: консистентность vs идентичность
С одной стороны, термин «консистентность» используется для изменяемых данных (CAP-теорема). С другой — я часто слышу его как синоним идентичности. Я специально искал в Интернете определение «консистентность сред» и, не найдя ничего вразумительного, решил, что стоит устранить это «белое пятно».
Исходя из этимологии слова консистентность (consistency = согласованность), я предлагаю называть консистентностью сред состояние системы, при котором среды (инсталляции системы в разных контурах, включая прод) находятся либо в идентичном состоянии, либо их (временная?) неидентичность согласована (например, обусловлена жизненным циклом этой системы).
Допустим, есть четыре контура:
dev;
тест;
НТ;
прод.
Систему внедрили идентично последовательно во все контуры. В данный момент среды идентичны (и консистентны, но об этом позже). Во всех контурах система, допустим, версии 1.0.
Далее начали реализовывать изменения. Поменяли в dev (стала версия 2.0). Среды тест, НТ и прод идентичны (там всё ещё версия 1.0). Dev отличается (там 2.0). Но все четыре среды при этом консистентны. Почему? Потому что эта временная неидентичность согласована всеми заинтересованными лицами и обусловлена согласованным ими же жизненным циклом системы.
Закончили разработку в деве, перешли к следующему контуру. Внедрили версию 2.0 в тестовый контур. В деве и тесте — версия 2.0, они идентичны. В НТ и проде — версия 1.0, они идентичны. При этом все четыре контура не идентичны, но консистентны. Всё по той же причине.
Развивая этот принцип, можно получить четыре разных версии в четырёх разных контурах. Например:
dev: 3.1
тест: 3.0
НТ: 2.9 (или вообще выключен/удалён!)
прод: 1.5
Если управление всеми этими версиями в этих средах соответствует вашим договорённостям (направленным на достижение гарантии качества), то, несмотря на очевидную неидентичность контуров, в данный момент все они консистентны.
Идентичность не должна быть у всех контуров в моменте. Она должна быть между конкретным тестовым контуром (в период тестирования на этом контуре) и тем состоянием прода, в котором он будет находиться в момент внедрения в него этих тестируемых изменений (релиза).
После успешно пройденных тестов тестовый контур можно «сжечь». Главное — обеспечить возможность его быстрого восстановления (вспоминаем про сервера-фениксы).
Даже сама процедура внедрения очередной версии в тестовые контуры является тестированием (проверкой). Результатом этой проверки будут следующие выводы:
успешно ли внедрилось изменение в ту версию системы, которая идентична проду? Если да, значит, и в прод внедрится тоже успешно;
какова длительность внедрения, чтобы заказывать соответствующее техокно?
есть ли влияние при внедрении (простой, деградация производительности, влияние на смежные системы), чтобы согласовать это влияние со всеми ЛПР (лицами, принимающими решения)?
какие именно пререквизиты требуются для внедрения (чтобы заранее заказать их в проде)?
протестирована ли процедура отката внедрённой версии?
Иногда среды могут быть неидентичны, но они обязательно всегда должны быть консистентны.
Ну как-то так. Если у вас есть альтернативное мнение — пишите свои варианты в комментариях.
Порядок
Можно найти множество определений этого термина. Мне нравится следующее: порядок — это высокая степень соответствия состояния объектов управления замыслу субъекта управления. Под объектами управления в контексте данного документа я подразумеваю:
ИТ-инфраструктуру;
информационную систему в целом;
её компоненты в частности (серверы, операционные системы, open source, прикладное ПО, конфигурации).
Под субъектом управления — персонал: системные администраторы, DevOps-инженеры, ИТ-менеджеры и даже в какой-то степени аудиторы.
Под замыслом субъекта управления — состояние объектов и процессов управления этими объектами, соответствующее предъявляемым к системе требованиям: доступность, мощность, непрерывность, безопасность, надёжность, обслуживаемость, идентичность, изменяемость и тому подобное.
Достичь порядка можно благодаря процессному управлению и автоматизации.
Разработать совокупность процессов (возможно, технологических), направленных на достижение этих целей, и планомерно повышать их уровень зрелости (например, по методике CMMI).
Кто-то скажет: «А потом всё это автоматизировать!»
Да, но ключевое слово здесь — «потом».
Автоматизация
Иногда можно услышать предложение: «Давайте автоматизируем всё! И прямо сейчас!»
Однако спешить с этим не стоит. Соглашусь, что в перспективе к этому действительно нужно стремиться. Но не сразу.
Важное правило: автоматизировать необходимо только то, что уже оптимизировано. Иначе можно получить автоматизированный хаос.
Согласно ITIL, повышать уровень зрелости процессов (то есть оптимизировать, а затем автоматизировать) следует параллельно — одновременно для всех взаимосвязанных процессов. Если автоматизировать только один процесс, то при последующей оптимизации других связанных с ним процессов он может сильно измениться или даже стать ненужным. В результате как минимум усилия будут потрачены впустую, как максимум — потребуются дополнительные затраты.
Автоматизация может быть дорогой, и в таком случае придётся признать, что проделанная работа была выполнена зря. Потраченные впустую ресурсы — это не только сожаление, но и риск того, что их может не хватить на что-то действительно важное.
Принцип Парето
Для оптимального расходования ресурсов обратимся к принципу Парето: 80% результата можно получить за счёт документирования процесса. Оставшиеся 20% результата достигаются уже более сложным путём — через контроль соблюдения задокументированных процессов и их последующую оптимизацию и автоматизацию.
Уровни зрелости
Согласно ITIL и CMMI, автоматизация — это пятый (последний) уровень зрелости процесса. Переходить к нему стоит только тогда, когда данный процесс и все смежные с ним находятся на четвёртом уровне. Аналогичное правило действует и для перехода на четвёртый уровень, и так далее.
Таким образом, рекомендую:
Выявить повторяемые виды деятельности.
Сформулировать их в виде workflow.
Унифицировать и зафиксировать их в виде процессов.
Оценить текущие уровни зрелости этих процессов (скорее всего, это будет второй уровень у всех).
Выявить взаимосвязанность между процессами.
Достичь по всем взаимосвязанным процессам одинакового уровня зрелости (например, поднять их все до второго).
Постепенно, параллельно повышать уровни зрелости взаимосвязанных процессов.
DevOps
DevOps как методология автоматизации
Кстати, раз уж заговорили об ИТ-процессах, ITIL и автоматизации.
Согласно определению, DevOps — это методология автоматизации технологических процессов. Исходя из этого, можно сказать, что внедрение DevOps в компании — это повышение тех процессов ITIL, которые можно считать технологическими, до последнего (пятого) уровня зрелости за счёт применения лучших мировых практик и технологий.
Другими словами, если в результате повышения уровней зрелости ИТ-процессов на предприятии все технологические ИТ-процессы были доведены до автоматизации с использованием best practices, то можно считать, что у вас внедрён DevOps. В этом случае сотрудники, занимающиеся созданием, развитием, сопровождением и поддержкой этой автоматизации — это и есть DevOps-инженеры.
Отличие DevOps-инженеров от системных администраторов
Иногда можно услышать мнение, что DevOps-инженеры и системные администраторы практически не отличаются друг от друга (ни по компетенциями, ни по функционалу). Позволю себе несколько слов об отличии между ними.
В моём понимании, одни занимаются ИТ-системами, автоматизирующими бизнес-процессы, тогда как другие — ИТ-системами, автоматизирующими технологические ИТ-процессы.
В некотором смысле системные администраторы являются одними из потребителей работы DevOps-инженеров. Примеры:
DevOps-инженер разработал код конвейера (CI/CD). Системный администратор подключил его в нужном проекте, параметризовал и периодически его запускает.
DevOps-инженер разработал Ansible-роль. Системный администратор включил её в нужный плейбук, параметризовал (переменными через инвентарь) и периодически его запускает.
DevOps-инженер реализовал Prometheus-экспортёр. Системный администратор установил его на нужных серверах и периодически наблюдает за метриками в Grafana.
DevOps-инженер реализовал парсинг и отправку логов определённого прикладного ПО. Системный администратор установил это на все серверы, где есть данный приклад этой версии, и периодически наблюдает за событиями в Kibana.
DevOps-инженер написал spec-файл. Системный администратор периодически инициирует сборку пакета.
DevOps-инженер написал Helm-чарт. Системный администратор подключил его в нужном проекте, параметризовал и использует для управления объектами в Kubernetes.
Ну что-то в этом духе.
Процесс взаимодействия
Если у системного администратора возникла проблема с этими разработанными DevOps-инженерами инструментами, он заводит им тикет. Исправляя ошибку по этому тикету, DevOps-инженеры выпускают очередную версию автоматизации, на которую предлагают перейти всем её потребителям (системным администраторам).
Если в вашей организации процесс взаимодействия системных администраторов и DevOps-инженеров устроен иначе — поделитесь в комментариях.
Роль DevOps-архитектора
В этом контексте существует также роль DevOps-архитектора, ответственного за roadmap всей этой автоматизации. Он и идейный вдохновитель, и амбассадор.
Инфраструктурный релиз как один из способов достичь консистентности
Что такое релиз
Определение этого термина, которое дано в ITIL, меня перестало устраивать. Там оно звучит примерно так: «совокупность изменений, разрабатывающихся, тестирующихся и внедряющихся одновременно». Я нашёл в Интернете другое определение, которое мне понравилось больше, и решил его немного доработать. Релиз — это ключевое событие в жизненном цикле изменяемого ИТ-объекта или системы, когда команда, работающая над его созданием или изменением, по результатам успешно пройденных тестов признаёт очередную версию готовой к выпуску в прод. Допустимо также релизом называть и саму версию, которая успешно прошла все тесты. Таким образом, у изменяемого ИТ-объекта может быть множество версий, некоторые из которых будут считаться релизами.
Как это выглядит на практике
Начальный этап. Система разворачивается во всех контурах идентично (допустим, версия 0.1). Тестирование. Система проходит тесты, по результатам которых в неё могут вноситься изменения. Версия, успешно прошедшая все тесты, объявляется релизом (например, версия 1.0 во всех контурах консистентно). Опытная эксплуатация (ОЭ). Система вводится в опытную эксплуатацию. В этот период выявляются ошибки и другие потребности в доработке. Исправляются технические долги, на которые были закрыты глаза при вводе в ОЭ. Система дорабатывается и тестируется, после чего получает версию (например, 1.7), пригодную для ввода в промышленную эксплуатацию. Поскольку она прошла все тесты, она также объявляется релизом. Таким образом, из всех версий системы именно версии 1.0 и 1.7 являются релизами. Промышленная эксплуатация. Релиз 1.7 внедряется в прод. Система вводится (переводится) в промышленную эксплуатацию. Она может продолжать изменяться и дорабатываться в связи с новыми потребностями. Но важно при этих доработках соблюдать подход с версиями, тестированием, релизами и консистентностью сред.
О версионировании
Рекомендую использовать семантическое версионирование.
С одной стороны, это всего лишь метка («хоть горшком назови»). С другой стороны, изменение мажорной версии может сигнализировать обслуживающему персоналу о нарушении обратной совместимости (например, ролей или плейбуков с объявленными переменными инвентаря group-vars или host-vars). Процедуры обновления патч-версий могут отличаться от мажорных. Это уже зависит от того, как вы сами организуете эти процессы у себя в компании. Инструмент интересный и лишним не будет.
Инфраплейбук
Базовые состояния
У виртуальных машин есть базовое состояние (версия шаблона ВМ), из которого они разворачиваются. У вас может быть несколько базовых состояний под разные назначения. Например, для СУБД-хостов — одно (с одной операционной системой), для open source — другое (с другой ОС), а для прикладного ПО — какое-то третье.
Если с точки зрения виртуализации и виртуальных хостов базовое состояние — это шаблон ВМ, то в контейнеризации — это базовый образ, указываемый в поле FROM в Dockerfile.
После развёртывания виртуального сервера из базового состояния на него устанавливается и настраивается какое-то ПО. Вручную или с помощью автоматизации. В нашем случае это плейбуки Ansible.
В качестве хорошей практики рекомендую следующее.
Всё, что применяется на абсолютно все серверы (вне зависимости от их назначения), выносится в отдельную автоматизацию. Я называю это «инфраплейбук». У инфраплейбука внутри свой набор инфраструктурных ролей, своя отдельная версионность, свои мейнтейнеры, своя дорожная карта и жизненный цикл. Его параметризуют (варсами в инвентаре) и запускают администраторы ОС.
После выполнения инфраплейбука мы получаем готовый к дальнейшей настройке «полуфабрикат» — хост, подключённый к нужным репозиториям, LDAP, DNS, зарегистрированный в системе мониторинга и тому подобное.
Дальнейшая настройка
Затем, в зависимости от последующего назначения, к хосту применяется вторая фаза автоматизации. Например, плейбук, устанавливающий и настраивающий на нём opensource, или конвейер, деплоящий на него прикладное ПО.
Таким образом мы получаем Сервер-феникс
В любой момент времени хост можно «сжечь», а затем:
создать новый из нужного базового состояния;
применить последнюю стабильную версию инфраплейбука (благо, варсы все в инвентаре сохранены);
применить нужную версию автоматизации (функционального плейбука или CI/CD);
восстановить изменяемые данные из резервной копии;
выполнить проверки.
Давайте решать проблемы по мере их поступления
Многие из описанных вызовов могли не решаться в компаниях по простой причине, которая называется «давайте решать проблемы по мере их поступления».
Когда мы рассуждаем о возможных негативных событиях, их последствиях, о вероятности их наступления и о наличии необходимости предпринимать какие-либо в связи с этим меры, это называется риск-менеджмент. Одним из его инструментов является квадрант (или матрица) Эйзенхауэра. Только риски с низкой вероятностью реализации и низким влиянием могут решаться «по мере поступления». Все остальные риски требуют той или иной степени проработки.
Если идентичность контуров обеспечивает нам более высокую степень качества продукции, то соответственно риск снижения степени идентичности контуров является риском снижения качества этой продукции. Его необходимо оценивать вместе с бизнес-заказчиком и предоставлять ему варианты (включая расчёты стоимости) митигации этого риска. Именно бизнес-заказчик принимает решение, закладывать ли в бюджет расходы на тестовые среды, процессы обеспечения идентичности и само тестирование. Либо эти риски могут быть приняты и решаться в момент их наступления.
Таким образом, вместо фразы «давайте решать проблемы по мере поступления» ответ может звучать так: «этот риск согласован с бизнесом» (или что-то в этом духе).
Обычно на на начальных этапах (концепт или MVP) такой риск принимается в угоду TTM. Далее, требования к качеству значительно повышаются (в том числе при заключении соглашения об уровне услуг — SLA).
РИТМ
С российского рынка ушёл ITIL, и теперь пройти сертификацию по этой методологии в нашей стране крайне сложно. Насколько я понимаю, эту нишу планирует занять проект РИТМ (Российская ИТ-методология). Я про него почти ничего не знаю, но хотелось бы, чтобы он учёл все недостатки ITIL и максимально адаптировал результат своей деятельности под отечественный ИТ-рынок.
Например, ITIL позиционировался как процессное управление, но согласно уровням зрелости управления процессное — это третья ступень из пяти возможных. На отечественном рынке (по моему сугубо личному мнению) процессное управление не в приоритетах по разным причинам.
Если РИТМу удастся реализовать методологию, охватывающую все пять уровней (и переходы между ними), я обязательно пройду эту сертификацию.
Искусственный интеллект
Учитывая высокую скорость развития технологий ИИ и его использования в ИТ-процессах, можно сказать, что данная статья — своего рода реквием по методам, которые уже успели стать олдскульными.
Я вижу следующие фазы эволюции:
Администрирование вручную без инструкций (и бэкапов!).
Администрирование вручную по инструкциям.
Автоматизация самописными скриптами.
Использование системы конфигурационного управления.
DevOps-практика «инфраструктура как код».
GitOps.
ChatOps.
Следующая, вероятно, AI-assistant-ops.
Если у вас будущее уже наступило, расскажите нам об этом.
Заключение
Все перечисленные вызовы в эпоху до искусственного интеллекта либо не решались (замалчивались?), либо решались не эффективно (ручными или полуавтоматизированными способами). Теперь же нам предоставляется возможность решать эти задачи эффективнее, вооружившись новым инструментом.
Согласно ITIL, полезность ИТ заключается либо в повышении производительности (например, бизнес-процессов), либо в устранении ограничений, благодаря чему появляются принципиально новые возможности (например, новые продукты). Будем надеяться, что искусственный интеллект даст и то, и другое.
Пофантазировать на эту тему также предлагаю в комментариях.
Если вам было интересно, дайте обратную связь — будем писать ещё