- PVSM.RU - https://www.pvsm.ru -
Чуть больше года назад я столкнулся с тем, что на внутреннем проекте совсем не айтишной компании вырос целый отдел веб-разработки, которым мне и довелось руководить. Рабочий процесс вроде как устаканился и всех устраивал, но оставались проблемы:
Внутренний перфекционист жаждал организовать всё правильно. Делюсь результатами поисков ответа на вопрос: «а как, собственно, “правильно”»?
Мы добились
Данная статья будет полезна, если вы:
Под катом вы найдёте
Статья состоит из трех частей:
В процессе поиска лучших практик находилось много теории по методологиям, разным инструментам, но всё разрозненно. Не было чего-то, что показывало бы единый процесс, как он выглядит со стороны менеджера, разработчика и системного администратора (а-ля DevOps).
Например статьи, где абстрактно [1] рассуждают [2] о процессе разработки, оставляют открытыми вопросы: “ок, хорошо, так а с помощью каких инструментов это можно сделать?”.
Не хватает реального практического примера по реализации некоего “базового” процесса, от которого уже можно было бы строить собственный. Видимо, авторами статей он считается очевидным. Напрашивается вариант перенять опыт крупных компаний или нанять человека с таким опытом, но такой подход может оказаться неэффективным. Ведь у крупной компании инфраструктура скорее всего заточена под задачи гораздо сложнее ваших текущих потребностей и требует много ресурсов и знаний для её реализации.
В конце концов, я пересмотрел большое количество связанных с данной темой материалов, ознакомился с различными инфраструктурными инструментами, пропустил всё через собственный опыт. При реализации прошёлся по всем граблям, о которых в официальной документации было сказано мало, но грабли должны были быть пройдены во имя “best practices”. Также понадобилось время по наладке работы отдела по-новому.
И, хотя данный опыт был получен уже как год назад, гугл показывает, что ещё не появилось гайда, который я искал когда-то.
Итак, приступим.
Вам понадобится:
1. Работа по классической модели в git
A successful Git branching model [3] by Vincent Driessen
Необходимый минимум — иметь ветки: master, dev и feature.
Feature
В каждой feature-ветке ведется работа над каждым отдельным функционалом / исправлениями, создаются от dev-ветки. Прекращают существование после того, как изменения вольются в dev.
Dev
В dev происходит окончательная совместная отладка и тестирование всех новых изменений, после этого производится релиз в master.
Master
От этой ветки и происходит релиз на production-сервер. Также, при необходимости срочных исправлений, от неё создаются hotfix-ветки, вливаются в неё же и удаляются.
Master и dev защищены от прямых пушей, существуют всегда.
2. Совместная работа в трекере задач. Документация всех принятых решений.
Это очень важный момент. При переключении между несколькими feature ветками, программисты теряют контекст буквально на следующий день. Записать задачу с невысоким приоритетом в виде “глянуть, что не так с xxx” недостаточно, чтобы вспомнить, о чем идёт речь. Все замечания необходимо фиксировать в обсуждениях Merge Request-а данной ветки. Необходимо вести wiki проекта, чтобы ускорить адаптацию новичков и утверждать принятые решения.
Важно всегда помнить, что если что-то не записано — этого не существует.
Крайней степенью документирования может служить опыт GitLab, которая была компанией без офиса ещё до того, как это стало мейнстримом пандемии.
3. Автоматизация инфраструктуры для тестирования и релизов
Всё просто — чем быстрее вы можете выводить свои решения в продакшн, тем они надёжнее и вы конкурентоспособнее. Часто можно встретить статьи, где измеряется количество релизов в месяц/неделю/день.
Я считаю, что это и послужило катализатором развития всех современных IT-гигантов и то, что сформировало DevOps. Сперва они автоматизировали процесс тестирования и выкатки своего монолита. Появилась проблема ожидания и невозможности локально развернуть окружение для разработки. Решением стала идея микросервисной архитектуры, что принесло новые проблемы. Где-то тут появилась идея контейнеризации (LXC), затем Docker, оркестраторы и понеслось...
При совместной работе необходимо понимать, кто за что ответственный. Прошу обратить внимание, что это именно функциональные роли, а не должности. То есть, один человек может совмещать в себе несколько функциональных ролей. Уверен, в каждом проекте эти функции выполняются в какой-то мере, даже если об этом не подозревают. Привожу своё понимание, поскольку во многих статьях пишут так, будто все сразу родились со знанием, кто есть кто.
Менеджер проекта
Общается с ключевыми лицами заказчика, начальством, определяет ключевые показатели, ведёт документооборот, решает все финансовые и кадровые вопросы, занимается продвижением продукта — сам или взаимодействуя с другими отделами компании. Отвечает за коммерческий результат, прессует владельца продукта.
Владелец продукта
Представляет себе общий образ продукта, чем он должен стать, какие ценности нести для клиента. Ведет бэклог (список задач) продукта, определяет приоритеты задач, знает о всех функциях продукта, также, до определённой степени, с технической стороны. Должен иметь опыт разработки. Именно тот человек, который должен сказать, что “людей не хватает”. Ограждает команду от прессинга начальства.
Аналитик / Технический писатель
Всегда находится рядом с конечным пользователем продукта, изучает бизнес-процессы заказчика, собирает обратную связь после внедрения каждой фичи. Можно сказать, информатор владельца продукта, помогает формировать техническое задание. Также должен знать о всех функциях продукта. Участвует в обучении клиента, написании документации для передачи заказчику.
Дизайнер UI/UX
Ответственный за то, чтобы пользователям было удобно работать с продуктом. Критически важный элемент успеха (если вы не Microsoft, конечно).
Архитектор
Скорее всего работает на нескольких проектах. Самый опытный разработчик в компании. Консультирует тимлида.
Тимлид
Опытный разработчик, консультирует владельца продукта, оценивает трудоёмкость задач, распределяет их между разработчиками, занимается их дальнейшей декомпозицией и проработкой с технической стороны. Проводит финальную приёмку готовых работ.
Разработчик
Пишет и документирует код. Проводит код-ревью коллег.
Разработчики специализируются на своих направлениях: бэкенд, фронтенд, мобильная разработка и т.д., в зависимости от проекта.
Тестировщик (QA / QC)
Quality Control (QC) тестирует продукт. Как вручную, так и с помощью написания кода. Quality Assurance (QA) также участвует в разработке архитектуры и инфраструктуры проекта, чтобы получение качественного результата закладывалось в процессе производства (Дао Toyota — принцип встраивания качества). К примеру, тестировать именно тот docker-образ, который и будет выкачен на продакшн, а не пересобирать его после тестов.
Системный администратор (DevOps)
Как и архитектор, скорее всего работает на нескольких проектах. Создаёт инфраструктуру при старте проекта, вносит изменения по ходу его развития.
Этапы workflow
Примечание: для того, чтобы минимизировать конфликты при слияниях веток, необходимо, чтобы архитектура вашего приложения поддерживала минимальную связанность модулей [4]. А также не стоит начинать работать над задачей, реализация которой приходится на тот же самый участок кода, который изменен в другой задаче, но по ней ещё не принят merge-request.
При выборе инструментов использовались критерии:
Итогом стал выбор технологий: Traefik [5], GitLab [6] и Docker [7].
*.dev.company.ru
, подключившись к докеру [Staging] по TCP и предоставляет к ним доступ. Также автоматически получает SSL сертификаты для приложения на [Production]. Wildcard (WC) сертификат *dev.company.ru
получается с помощью отдельного контейнера letsencrypt-dns, если ваш DNS-провайдер не поддерживается в Traefik. Traefik использует этот или самостоятельно полученный сертификат, обрезает SSL от клиентов и перенаправляет http запросы по доменным именам на соответствующие сервисы. Работает на [Production] вместе с основным приложением App.Привожу ссылку на github-репозиторий, в котором пошагово описан процесс создания данной инфраструктуры. Дабы не раздувать ещё больше этот лонгрид, прошу читать их там:
Предупреждение
- Данное инфраструктурное решение является скорее стартовой площадкой для понимания основных принципов, нагрузочных тестирований не проводилось. Очень многое зависит от железа и архитектуры приложения. Для больших нагрузок, повышения надёжности и работы в облаке рекомендуется рассмотреть Enterprise версии Traefik и GitLab и воспользоваться консультациями специалистов.
- В репозитории содержатся части конфигурации, которые очевидно нужно будет изменить под себя. Например, временная зона, почтовые адреса, домены и т.п.
- Так как работа была проведена год назад, Traefik и GitLab заметно развились за это время и уже многие вещи можно оптимизировать. Так, Traefik уже поддерживает DNS Yandex (не без моего скромного участия [9]) и больше не нужен промежуточный сервис [10]. А в GitLab появились более гибкие возможности конфигурирования. Например, rules [11].
- Также стоит обратить на секцию “Что можно сразу улучшить”.
Пример приводится для небольшого веб-приложения, также для понимания основных принципов, так как предполагает:
- Недоступность приложения при обновлениях. Для организации выкатки без downtime потребуется поддержка со стороны кода приложения (версионность API бэкенда, поэтапные миграции БД), более сложные настройки load-balancer-а и алгоритма выкатки, а в идеале — переход на другой уровень инфраструктуры — kubernetes. Так что это уже далеко не уровень “для начинающих”
- Запуск базы данных в докере (влияет на производительность)
- Копирование production-базы данных для стейджинга (конфиденциальность данных)
- Вызов команд от root в контейнерах (далеко не лучшая практика)
Самое главное в репозитории — файл .gitlab-ci.yml. Рассмотрим стадии pipeline-а и входящие в них задачи на соответствие шагам в рабочем процессе:
И в заключение привожу видео митапа в феврале этого года, где показывается результат вживую. В части с экраном чуть рассинхрон с рассказом — пришлось потом повторить, забыл включить запись. Первое выступление на публике, волновался.
Анализ докер-образов: https://github.com/wagoodman/dive [35]
# Команда для анализа docker образов (утилита запускается в докере)
sudo docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest gitlab/gitlab-runner:latest
Генератор конфигов различных серверов для работы с SSL: https://ssl-config.mozilla.org/#server=traefik&server-version=2.1&config=intermediate [36]
GitLab Shell Runner. Конкурентный запуск тестируемых сервисов при помощи docker-compose https://habr.com/ru/post/449910 [37]
Группы в телеграмме:
Доклады Дмитрия Столярова из компании "Флант"
Автор: Дмитрий
Источник [42]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/358543
Ссылки в тексте:
[1] абстрактно: https://habr.com/ru/company/mailru/blog/196184/
[2] рассуждают: https://habr.com/ru/company/badoo/blog/335254
[3] A successful Git branching model: https://nvie.com/posts/a-successful-git-branching-model/
[4] минимальную связанность модулей: https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D1%86%D0%B5%D0%BF%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
[5] Traefik: https://traefik.io/traefik/
[6] GitLab: https://about.gitlab.com/
[7] Docker: https://www.docker.com/
[8] https://github.com/Akkarine/demo_cicd: https://github.com/Akkarine/demo_cicd
[9] скромного участия: https://github.com/go-acme/lego/pull/953
[10] промежуточный сервис: https://github.com/adferrand/dnsrobocert
[11] rules: https://docs.gitlab.com/ce/ci/yaml/#rules
[12] https://github.com/Akkarine/demo_cicd_project: https://github.com/Akkarine/demo_cicd_project
[13] https://docs.traefik.io/: https://docs.traefik.io/
[14] https://habr.com/ru/post/328048/: https://habr.com/ru/post/328048/
[15] https://habr.com/ru/post/445448/: https://habr.com/ru/post/445448/
[16] https://github.com/jwilder/nginx-proxy: https://github.com/jwilder/nginx-proxy
[17] https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion: https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion
[18] https://docs.gitlab.com/omnibus/docker: https://docs.gitlab.com/omnibus/docker
[19] https://docs.gitlab.com/omnibus/settings/ssl.html: https://docs.gitlab.com/omnibus/settings/ssl.html
[20] https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl: https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl
[21] https://docs.gitlab.com/ce/administration/container_registry.html#configure-container-registry-under-its-own-domain: https://docs.gitlab.com/ce/administration/container_registry.html#configure-container-registry-under-its-own-domain
[22] https://docs.gitlab.com/omnibus/maintenance/#container-registry-garbage-collection: https://docs.gitlab.com/omnibus/maintenance/#container-registry-garbage-collection
[23] https://docs.gitlab.com/runner/install/docker.html: https://docs.gitlab.com/runner/install/docker.html
[24] https://docs.gitlab.com/runner/executors/docker.html: https://docs.gitlab.com/runner/executors/docker.html
[25] https://docs.gitlab.com/runner/executors/ssh.html: https://docs.gitlab.com/runner/executors/ssh.html
[26] https://docs.gitlab.com/runner/register/index.html#docker: https://docs.gitlab.com/runner/register/index.html#docker
[27] https://docs.gitlab.com/ce/ci/docker/using_docker_build.html: https://docs.gitlab.com/ce/ci/docker/using_docker_build.html
[28] https://docs.gitlab.com/ce/ci/docker/using_kaniko.html: https://docs.gitlab.com/ce/ci/docker/using_kaniko.html
[29] https://docs.gitlab.com/runner/configuration/advanced-configuration.html: https://docs.gitlab.com/runner/configuration/advanced-configuration.html
[30] https://docs.gitlab.com/runner/commands/README.html: https://docs.gitlab.com/runner/commands/README.html
[31] https://docs.docker.com/install/linux/linux-postinstall/: https://docs.docker.com/install/linux/linux-postinstall/
[32] https://docs.docker.com/compose/reference/overview/: https://docs.docker.com/compose/reference/overview/
[33] https://docs.docker.com/compose/reference/config/: https://docs.docker.com/compose/reference/config/
[34] https://docs.docker.com/engine/security/https/: https://docs.docker.com/engine/security/https/
[35] https://github.com/wagoodman/dive: https://github.com/wagoodman/dive
[36] https://ssl-config.mozilla.org/#server=traefik&server-version=2.1&config=intermediate: https://ssl-config.mozilla.org/#server=traefik&server-version=2.1&config=intermediate
[37] https://habr.com/ru/post/449910: https://habr.com/ru/post/449910
[38] https://t.me/ru_gitlab: https://t.me/ru_gitlab
[39] https://t.me/ru_docker: https://t.me/ru_docker
[40] https://t.me/PostgreSQL_1C_Linux: https://t.me/PostgreSQL_1C_Linux
[41] https://t.me/werf_ru: https://t.me/werf_ru
[42] Источник: https://habr.com/ru/post/526440/?utm_source=habrahabr&utm_medium=rss&utm_campaign=526440
Нажмите здесь для печати.