Привіт!
Мене звуть Сергій, я працюю інфраструктурним інженером у команді API платформи tinkoff.ru.
У цій статті я розповім про проблеми, з якими стикалася наша команда під час підготовки балансувальників на основі Nginx для різних проектів. Також розповім про інструмент, який дозволив подолати більшу частину з них.
Nginx - це багатофункціональний проксі-сервер, що активно розвивається. Він відрізняється великою кількістю модулів, ось далеко не повний перелік. Кожен проект накладає певні вимоги до функціонала балансувальника та версії Nginx (наприклад наявність http/2 та проксування grpc), та складу його модулів.
Ми хочемо бачити свіжу версію з потрібним набором модулів, що працює під певним дистрибутивом Linux. У нашому випадку це deb- та rpm-based системи. Варіант із контейнерами у цій статті не розглядається.
Ми хочемо оперативно змінювати функціонал наших балансувальників. І тут відразу постає питання — як цього досягти, витративши якнайменше ресурсів? А ще краще налагодити процес так, щоб ми могли задати кінцеве число вхідних параметрів, а на виході отримати артефакт у вигляді deb/rpm пакета для потрібної ОС.
У результаті можна сформулювати низку проблем:
Не завжди є пакети зі свіжою версією Nginx.
Немає пакетів із потрібними модулями.
Компіляція та складання пакета вручну займає багато часу і просто втомлює.
Немає опису, як зібраний той чи інший інстанс Nginx.
Щоб вирішити ці проблеми, напрошується якийсь інструмент, який б приймав на вхід специфікацію в людиночитаному форматі і збирав по ній пакет Nginx з потрібним функціоналом.
Не знайшовши відповідного для нас варіанта на просторах гітхабу, ми вирішили створити свій інструмент. nginx-builder.
Специфікації
У нашому інструменті ми хотіли створювати опис специфікації у вигляді коду, який можна покласти в Git-репозиторій. Для цього вибрали звичний для подібних речей формат yaml. Приклад специфікації:
Тут ми вказуємо, що хочемо бачити deb-пакет із версією Nginx 1.14.2 з потрібним набором модулів. Секція з модулями – опціональна. Для кожного з них можна задати:
Назва.
Адреса, де її можна отримати:
Git-репозиторій. Можна також вказати гілку або тег.
Веб-посилання на архів.
Локальне посилання на архів.
Деякі модулі вимагають встановлення додаткових залежностей, наприклад, для nginx-auth-ldap потрібен встановлений libldap2-dev. Необхідні залежності також можна вказати під час опису модуля.
оточення
У нашому інструменті можна швидко отримувати оточення із встановленими утилітами для компіляції, складання пакету та іншим допоміжним програмним забезпеченням. Тут якнайкраще підходить docker-контейнер з усім необхідним (у репозиторії вже є пара прикладів docker-файлів для ubuntu та centos).
Після того, як специфікація складена та підготовлено оточення, ми запускаємо наш збирач, попередньо встановивши його залежність:
Номер ревізії тут опціональний і служить для версіювання збірок. Він записується у метаінформацію пакета, що дозволяє легко оновлювати його на серверах.
По логах можна спостерігати за тим, що відбувається. Ось приклад основних моментів:
builder - INFO - Parse yaml file: example.config.yaml
builder - INFO - Download scripts for build deb package
builder - INFO - Downloading nginx src...
builder - INFO - --> http://nginx.org/download/nginx-1.14.1.tar.gz
builder - INFO - Downloading 3d-party modules...
builder - INFO - Module nginx-auth-ldap will download by branch
builder - INFO - -- Done: nginx-auth-ldap
builder - INFO - -- Done: ngx_http_substitutions_filter_module
builder - INFO - Module headers-more-nginx-module will downloading
builder - INFO - Module nginx-module-vts will download by tag
builder - INFO - -- Done: nginx-module-vts
builder - INFO - Module ngx_devel_kit will download by tag
builder - INFO - -- Done: ngx_devel_kit
builder - INFO - -- Done: ngx_cache_purge
builder - INFO - -- Done: ngx_http_dyups_module
builder - INFO - Downloading dependencies
builder - INFO - Building .deb package
builder - INFO - Running 'dh_make'...
builder - INFO - Running 'dpkg-buildpackage'...
dpkg-deb: building package 'nginx' in '../nginx_1.14.1-1_amd64.deb'.
Так буквально парою команд ми створюємо оточення та потрібну збірку Nginx, і пакет з'являється в директорії, звідки запущено скрипт.
Вбудовування
Також ми можемо вбудувати наш інструмент у процесах CI/CD. У цьому може допомогти будь-яка з безлічі CI-систем, що існують на сьогодні, наприклад Teamcity або Gitlab CI.
У результаті, при кожній зміні специфікації в Git-репозиторії автоматично запускається складання артефакту. Номер ревізії прив'язується до лічильника запуску білда.
Витративши ще трохи часу, можна налаштувати відправлення артефакту в локальний пакет репозиторій, Nexus, Artifactory і так далі.
Додатковим плюсом є те, що конфігураційний yaml-файл можна підключити до Ansible або іншої системи автоматичного конфігурування, і брати звідти номер версії та типу пакета, які ми хочемо задеплоїти.
Що далі
Проект ще не завершено. Ось над чим ми працюємо зараз:
Розширюємо можливість конфігурування, але зберігаємо її максимально простий. Не хочеться визначати тисячу параметрів, якщо потрібно лише два, а решта підходить за умовчанням. До цього відносяться прапори компіляції (зараз можна змінити їх у внутрішньому файлі конфігурації src/config.py), шляхи установки, користувача для запуску.
Додаємо варіанти автоматичного відправлення пакета до різних сховищ артефактів.