Збираємо свій Nginx парою команд

Привіт!
Мене звуть Сергій, я працюю інфраструктурним інженером у команді API платформи tinkoff.ru.

У цій статті я розповім про проблеми, з якими стикалася наша команда під час підготовки балансувальників на основі Nginx для різних проектів. Також розповім про інструмент, який дозволив подолати більшу частину з них.

Nginx - це багатофункціональний проксі-сервер, що активно розвивається. Він відрізняється великою кількістю модулів, ось далеко не повний перелік. Кожен проект накладає певні вимоги до функціонала балансувальника та версії Nginx (наприклад наявність http/2 та проксування grpc), та складу його модулів.

Ми хочемо бачити свіжу версію з потрібним набором модулів, що працює під певним дистрибутивом Linux. У нашому випадку це deb- та rpm-based системи. Варіант із контейнерами у цій статті не розглядається.

Ми хочемо оперативно змінювати функціонал наших балансувальників. І тут відразу постає питання — як цього досягти, витративши якнайменше ресурсів? А ще краще налагодити процес так, щоб ми могли задати кінцеве число вхідних параметрів, а на виході отримати артефакт у вигляді deb/rpm пакета для потрібної ОС.

У результаті можна сформулювати низку проблем:

  • Не завжди є пакети зі свіжою версією Nginx.
  • Немає пакетів із потрібними модулями.
  • Компіляція та складання пакета вручну займає багато часу і просто втомлює.
  • Немає опису, як зібраний той чи інший інстанс Nginx.

Щоб вирішити ці проблеми, напрошується якийсь інструмент, який б приймав на вхід специфікацію в людиночитаному форматі і збирав по ній пакет Nginx з потрібним функціоналом.

Не знайшовши відповідного для нас варіанта на просторах гітхабу, ми вирішили створити свій інструмент. nginx-builder.

Специфікації

У нашому інструменті ми хотіли створювати опис специфікації у вигляді коду, який можна покласти в Git-репозиторій. Для цього вибрали звичний для подібних речей формат yaml. Приклад специфікації:

nginx_version: 1.14.1
output_package: deb
modules:
  - module:
      name: nginx-auth-ldap
      git_url: https://github.com/kvspb/nginx-auth-ldap.git
      git_branch: master
      dependencies:
        - libldap2-dev
  - module:
      name: ngx_http_substitutions_filter_module
      git_url: https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git
  - module:
      name: headers-more-nginx-module
      web_url: https://github.com/openresty/headers-more-nginx-module/archive/v0.261.zip
  - module:
      name: nginx-module-vts
      git_url: https://github.com/vozlt/nginx-module-vts.git
      git_tag: v0.1.18
  - module:
      name: ngx_devel_kit
      git_url: https://github.com/simplresty/ngx_devel_kit.git
      git_tag: v0.3.0
  - module:
      name: ngx_cache_purge
      git_url: https://github.com/FRiCKLE/ngx_cache_purge.git
  - module:
      name: ngx_http_dyups_module
      git_url: https://github.com/yzprofile/ngx_http_dyups_module.git
  - module:
      name: nginx-brotli
      git_url: https://github.com/eustas/ngx_brotli.git
      git_tag: v0.1.2
  - module:
      name: nginx_upstream_check_module
      git_url: https://github.com/yaoweibin/nginx_upstream_check_module.git
  - module:
      name: njs
      git_url: https://github.com/nginx/njs.git
      git_tag: 0.2.5
      config_folder_path: nginx

Тут ми вказуємо, що хочемо бачити deb-пакет із версією Nginx 1.14.2 з потрібним набором модулів. Секція з модулями – опціональна. Для кожного з них можна задати:

  • Назва.
  • Адреса, де її можна отримати:
    • Git-репозиторій. Можна також вказати гілку або тег.
    • Веб-посилання на архів.
    • Локальне посилання на архів.

Деякі модулі вимагають встановлення додаткових залежностей, наприклад, для nginx-auth-ldap потрібен встановлений libldap2-dev. Необхідні залежності також можна вказати під час опису модуля.

оточення

У нашому інструменті можна швидко отримувати оточення із встановленими утилітами для компіляції, складання пакету та іншим допоміжним програмним забезпеченням. Тут якнайкраще підходить docker-контейнер з усім необхідним (у репозиторії вже є пара прикладів docker-файлів для ubuntu та centos).

Після того, як специфікація складена та підготовлено оточення, ми запускаємо наш збирач, попередньо встановивши його залежність:

pip3 install -r requirements.txt
./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]

Номер ревізії тут опціональний і служить для версіювання збірок. Він записується у метаінформацію пакета, що дозволяє легко оновлювати його на серверах.
По логах можна спостерігати за тим, що відбувається. Ось приклад основних моментів:

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), шляхи установки, користувача для запуску.
  • Додаємо варіанти автоматичного відправлення пакета до різних сховищ артефактів.
  • Виконання команди користувача при завантаженні модуля (наприклад для використання github.com/nginx-modules/nginx_upstream_check_module потрібно спочатку застосувати патч певної версії)
  • Додаємо проведення тестів:
    • Пакет коректно встановлюється.
    • Nginx має потрібну версію та зібраний з необхідними прапорами та модулями.
    • Створюються необхідні шляхи, облікові записи тощо.

Але користуватися цим інструментом ви можете вже зараз, а також пропонувати доопрацювання. github.com/TinkoffCreditSystems/Nginx-builder wellcome!

Джерело: habr.com

Додати коментар або відгук