Лучшие DevOps практики и кейсы

12 Factor App: Меньше нервов для разработчиков и менеджеров


После частого повторения одних и тех же действий мы приходим к некоторым шаблонам и алгоритмам действий, которые ускоряют процессы и облегчают нашу жизнь. 12 Factor App собрал в себе опыт разработки и развертывания приложений, которые были проделаны его участниками  во время работы над платформой Heroku
Эти практики сделают ваше приложение готовым к:
  • облачным хостингам
  • горизонтальному масштабированию
  • непрерывному развертыванию
  • слаженной работе разработчиков над его улучшением и ростом

1. Одно приложение - один репозиторий

Независимо от размера и важности изменений код должен быть в git. И разворачиваться на prod, dev, test сервера из одного репозитория.

Общий код, используемый несколькими приложениями стоит вынести в отдельную библиотеку, объявив зависимостью. В одном репозитории должны находится только сильно связанные между собой приложения. Например frontend и backend можно вынести в отдельные приложения, которые будет следовать принципам 12 Factor App.

2. Явные зависимости

Приложения не должны иметь неявных зависимостей, даже если библиотека без указанной версии не доставляет проблем уже несколько релизов. Поэтому все системные зависимости (версия сборки ОС), части инфраструктуры (БД, очереди сообщений, reverse proxy), языки программирования, и версии библиотеки через пакетный менеджер (Python - pip, Node.js - npm) должны быть указаны в коде.

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

Уточнение: Docker изолирует контейнеры и явно объявляет зависимости, рекомендуем явно указывать версию и не использовать тэг latest.

3. Конфигурация - в отдельных файлах

Конфигурация — это все параметры, которые меняются в зависимости от окружения (где запускаем):
  • логины, пароли и адреса баз данных;
  • сетевой адрес и номер порта
  • сторонние сервисы и ключи АПИ.

Хорошей практикой является хранить конфиг файлы под каждое окружение. Логины/Пароли и другие конфиденциальные данные нельзя хранить в репозитории. Нужно добавлять их в системы управления конфиденциальными данными (Hashicorp Vault) или шифровать (Ansible Vault). Хорошее README.md с описанием всех параметров намного лучше чем несколько сессий передачи знаний.

Довольно популярный вариант – хранить конфиг файлы в отдельной директории в том же репозитории. А сикрет файлы хранить в Hashicorp Vault или AWS Secret Manager.

4. Подключаемые сервисы (Backing services + 3rd party)

Подключаемые сервисы - это любая сторонняя служба, которая доступна по сети и необходима приложению для нормальной работы. Например, базы данных (MongoDB, PostgreSQL), почтовые SMTP сервера (Postfix), очередь сообщений (RabbitMQ), различиные API (Facebook, Twitter, Google Calendar) и т.п. 

Каждое 12 Factor приложение должно иметь возможность заменить локальный сервис на 3rd Party, например локальную БД PostgreSQL на Amazon RDS. При это мы должны менять только переменные в файле конфигурации, не трогая код приложения.

5. Разделение стадий развертывания приложения

Развертывания приложение происходит за 3 этапа:
  1. Сборка - трансформируем код в исполняемый пакет, загружаем зависимости, компилируем файлы, проводим тестирование
  2. Релиз - объединение сборки с конфигурацией
  3. Выполнение - запуск релиза и его процессов

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

6. Приложение и процессы

Приложение работает в среде выполнения как 1 или несколько процессов. Его процессы не должны сохранять внутреннее состояние, чтобы не потерять его при перезапуске(stateless).
Приложение может использовать оперативную память или файловую систему только как временное хранилище, например при чтении файлов. Любые пользовательские данные должны сохранять в постоянное хранилище, например базу данных.

В особенности это касается данных сессии, сейчас весьма распространены sticky session, которые кэшируют пользовательские данные в памяти процесса. 12 Factor App рекомендует не использовать их, потому что данные могут быть утеряны из-за аппаратного сбоя или перезагрузки процессора. Отличной заменой sticky session будет Redis или Memcached.

7. Работа с портами

Приложение может быть запущено как модуль внутри сервера, например Java-приложение внутри Tomcat. Однако, 12 Factor приложение должно быть полностью самодостаточным, поэтому мы объявим библиотеку веб-сервера зависимостью (Flask для Python, Spring в Java).

Таким образом мы экспортируем наше http приложение в мир, привязывая его к определенному порту. Однако, точно так же мы можем поступать и с другими типами приложений, независимо от их протокола, например ejabberd или Redis. И, конечно же, имея ссылку и порт мы можем обращаться к какому-либо приложению как к подключаемому сервису.

8. Параллелизм

12 Factor App рекомендует использовать разные процессы для разных задач. Например, http запросы обрабатываются web-процессом, а тяжелые и длительные задачи - воркером, фоновым процессом.

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

9. Быстрый запуск и завершение

Если процессы не сохраняют свое состояние(stateless), то могут быстро запустится и завершатся без ошибок даже в аварийных ситуациях. Это способствует стабильному и гибкому масштабированию, высокой надежности и скорости развертывания нового кода и конфигураций.

При внезапном завершении воркеры, выполняющие фоновые запросы должны возвращать текущую задачу в очередь сообщений (RabbitMQ), а процессы обработки запросов корректно их заканчивать. Также в 12 Factor приложении должно уметь  повторять задачи, и обрабатывать неожиданные ошибки.

10. Максимально похожее на production окружение 


Если не использовать Docker и прочие инструменты контейнеризации у вас могут очень сильно отличаться dev и prod окружения. Особенно, если вы используете разные инструменты на разных этапах, напротив 12 Factor App поможет решить основные моменты:
  • Время: код будет попадать в рабочую среду через несколько часов после его написания, благодаря системе CI/CD
  • Люди: разработчик участвует в развертывании своего кода или всегда на связе с DevOps инженером
  • Инструменты: среда разработки и тестирования совпадает с продакшеном.

Сейчас эта проблема встречается гораздо реже, благодаря Docker контейнерам и декларативным инструментам подготовки окружения, как Ansible и Chef.

11. Логирование

Лог - это поток событий, поэтому с ним стоит так и работать, а не заводить отдельные файлы. 12 Factor App рекомендует приложению не заниматься хранением и маршрутизацией логов, а писать все в stdout. Разработчик может просматривать логи в терминале, но мы настоятельно рекомендуем выбрать удобный инструмент для анализа и архивирования, например Splunk, Fluentd, или Logstash.

Такой подход позволяет агрегировать логи приложения и сторонних сервисов (БД, очереди сообщений). Благодаря системе анализа логов можно получить ценную информацию о состоянии работы системы и ее частей, и увидеть пики активности.

12. Задачи администрирования

Разовые и повторяющиеся задач администрирования (миграции, исправления базы данных) должны подчиняться тем же правилам, что и остальные процессы:
  • код задач находится в репозитории приложения (пункт 1)
  • все зависимости явно объявлены (пункт 2)
  • конфигурацию записываем в переменные окружения (пункт 3)

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

Если у вас все еще остались вопросы или вам нужна инфраструктура для внедрения 12 Factor App – свяжитесь с нами.
Статьи