0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>В этой статье я расскажу о проблемах, с которыми сталкивалась наша команда при подготовке балансировщиков на основе Nginx для различных проектов. Также расскажу об инструменте, который позволил преодолеть большую часть из них.</p>
1
<p>В этой статье я расскажу о проблемах, с которыми сталкивалась наша команда при подготовке балансировщиков на основе Nginx для различных проектов. Также расскажу об инструменте, который позволил преодолеть большую часть из них.</p>
2
<p><strong>Nginx</strong>- это многофункциональный и активно развивающийся прокси-сервер. Он отличается большим количеством модулей, вот<a>далеко не полный список</a>. Каждый проект налагает определенные требования к функционалу балансировщика и версии Nginx (например наличие http/2 и проксирование grpc), и составу его модулей.</p>
2
<p><strong>Nginx</strong>- это многофункциональный и активно развивающийся прокси-сервер. Он отличается большим количеством модулей, вот<a>далеко не полный список</a>. Каждый проект налагает определенные требования к функционалу балансировщика и версии Nginx (например наличие http/2 и проксирование grpc), и составу его модулей.</p>
3
<p>Нам хочется видеть свежую версию с нужным набором модулей, работающую под определенным дистрибутивом<strong>Linux</strong>. В нашем случае это deb- и rpm-based системы. Вариант с контейнерами в данной статье не рассматривается.</p>
3
<p>Нам хочется видеть свежую версию с нужным набором модулей, работающую под определенным дистрибутивом<strong>Linux</strong>. В нашем случае это deb- и rpm-based системы. Вариант с контейнерами в данной статье не рассматривается.</p>
4
<p>Нам хочется оперативно изменять функционал наших балансировщиков. И здесь сразу встает вопрос - как этого добиться, затратив как можно меньше ресурсов? А еще бы лучше наладить процесс так, чтобы мы могли задать конечное число входных параметров, а на выходе получить артефакт в виде deb/rpm пакета для нужной ОС.</p>
4
<p>Нам хочется оперативно изменять функционал наших балансировщиков. И здесь сразу встает вопрос - как этого добиться, затратив как можно меньше ресурсов? А еще бы лучше наладить процесс так, чтобы мы могли задать конечное число входных параметров, а на выходе получить артефакт в виде deb/rpm пакета для нужной ОС.</p>
5
<p>В итоге можно сформулировать ряд проблем:</p>
5
<p>В итоге можно сформулировать ряд проблем:</p>
6
<ol><li>Не всегда есть пакеты со свежей версией Nginx.</li>
6
<ol><li>Не всегда есть пакеты со свежей версией Nginx.</li>
7
<li>Нет пакетов с нужными модулями.</li>
7
<li>Нет пакетов с нужными модулями.</li>
8
<li>Компиляция и сборка пакета вручную занимает много времени и попросту утомительна.</li>
8
<li>Компиляция и сборка пакета вручную занимает много времени и попросту утомительна.</li>
9
<li>Нет описания, как собран тот или иной инстанс Nginx.</li>
9
<li>Нет описания, как собран тот или иной инстанс Nginx.</li>
10
</ol><p>Чтобы решить эти проблемы, напрашивается некий инструмент, который принимал бы на вход спецификацию в человекочитаемом формате и собирал по ней пакет Nginx с нужным функционалом.</p>
10
</ol><p>Чтобы решить эти проблемы, напрашивается некий инструмент, который принимал бы на вход спецификацию в человекочитаемом формате и собирал по ней пакет Nginx с нужным функционалом.</p>
11
<p>Не найдя подходящего для нас варианта на просторах гитхаба, мы решили создать свой инструмент -<a>nginx-builder</a>.</p>
11
<p>Не найдя подходящего для нас варианта на просторах гитхаба, мы решили создать свой инструмент -<a>nginx-builder</a>.</p>
12
<h2>Спецификации</h2>
12
<h2>Спецификации</h2>
13
<p>В нашем инструменте мы хотели создавать описание спецификации в виде кода, который затем можно положить в Git-репозиторий. Для этого выбрали привычный для подобных вещей формат - yaml. Пример спецификации:</p>
13
<p>В нашем инструменте мы хотели создавать описание спецификации в виде кода, который затем можно положить в Git-репозиторий. Для этого выбрали привычный для подобных вещей формат - yaml. Пример спецификации:</p>
14
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<p>Здесь мы указываем, что хотим видеть deb-пакет с версией Nginx 1.14.2 с нужным набором модулей. Секция с модулями - опциональная. Для каждого из них можно задать:</p>
14
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<p>Здесь мы указываем, что хотим видеть deb-пакет с версией Nginx 1.14.2 с нужным набором модулей. Секция с модулями - опциональная. Для каждого из них можно задать:</p>
15
<ol><li>Название.</li>
15
<ol><li>Название.</li>
16
<li>Адрес, где его можно получить:</li>
16
<li>Адрес, где его можно получить:</li>
17
<li>Git-репозиторий. Также можно указать ветку или тег.</li>
17
<li>Git-репозиторий. Также можно указать ветку или тег.</li>
18
<li>Веб-ссылка на архив.</li>
18
<li>Веб-ссылка на архив.</li>
19
<li>Локальная ссылка на архив.</li>
19
<li>Локальная ссылка на архив.</li>
20
</ol><p>Некоторые модули требуют установки дополнительных зависимостей, например для nginx-auth-ldap нужен установленный libldap2-dev. Необходимые зависимости также можно указать при описании модуля.</p>
20
</ol><p>Некоторые модули требуют установки дополнительных зависимостей, например для nginx-auth-ldap нужен установленный libldap2-dev. Необходимые зависимости также можно указать при описании модуля.</p>
21
<h2>Окружение</h2>
21
<h2>Окружение</h2>
22
<p>В нашем инструменте можно быстро получать окружение с установленными утилитами для компиляции, сборки пакета и другим вспомогательным ПО. Здесь как нельзя лучше подходит docker-контейнер со всем необходимым (в репозитории уже есть пара примеров docker-файлов для ubuntu и centos).</p>
22
<p>В нашем инструменте можно быстро получать окружение с установленными утилитами для компиляции, сборки пакета и другим вспомогательным ПО. Здесь как нельзя лучше подходит docker-контейнер со всем необходимым (в репозитории уже есть пара примеров docker-файлов для ubuntu и centos).</p>
23
<p>После того, как спецификация составлена и подготовлено окружение, мы запускаем наш сборщик, предварительно установив его зависимости:</p>
23
<p>После того, как спецификация составлена и подготовлено окружение, мы запускаем наш сборщик, предварительно установив его зависимости:</p>
24
pip3 install -r requirements.txt ./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]<p>Номер ревизии здесь опционален и служит для версионирования сборок. Он записывается в метаинформацию пакета, что позволяет легко обновлять его на серверах. По логам можно наблюдать за происходящим. Вот пример основных моментов:</p>
24
pip3 install -r requirements.txt ./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]<p>Номер ревизии здесь опционален и служит для версионирования сборок. Он записывается в метаинформацию пакета, что позволяет легко обновлять его на серверах. По логам можно наблюдать за происходящим. Вот пример основных моментов:</p>
25
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'.<p>Так буквально парой команд мы создаем окружение и нужную сборку Nginx, и пакет появляется в директории, откуда запущен скрипт.</p>
25
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'.<p>Так буквально парой команд мы создаем окружение и нужную сборку Nginx, и пакет появляется в директории, откуда запущен скрипт.</p>
26
<h2>Встраивание</h2>
26
<h2>Встраивание</h2>
27
<p>Также мы можем встроить наш инструмент в CI/CD процессы. В этом может помочь любая из множества существующих на сегодняшний день CI-систем, например Teamcity или Gitlab CI.</p>
27
<p>Также мы можем встроить наш инструмент в CI/CD процессы. В этом может помочь любая из множества существующих на сегодняшний день CI-систем, например Teamcity или Gitlab CI.</p>
28
<p>В итоге при каждом изменении спецификации в Git-репозитории автоматически запускается сборка артефакта. Номер ревизии привязывается к счетчику запусков билда. Потратив еще немного времени, можно настроить отправку артефакта в локальный репозиторий пакетов, Nexus, Artifactory и так далее.</p>
28
<p>В итоге при каждом изменении спецификации в Git-репозитории автоматически запускается сборка артефакта. Номер ревизии привязывается к счетчику запусков билда. Потратив еще немного времени, можно настроить отправку артефакта в локальный репозиторий пакетов, Nexus, Artifactory и так далее.</p>
29
<p>Дополнительным плюсом является то, что конфигурационный yaml-файл можно подключить в Ansible или другую систему автоматического конфигурирования, и брать оттуда номер версии и типа пакета, которые мы хотим задеплоить.</p>
29
<p>Дополнительным плюсом является то, что конфигурационный yaml-файл можно подключить в Ansible или другую систему автоматического конфигурирования, и брать оттуда номер версии и типа пакета, которые мы хотим задеплоить.</p>
30
<h2>Что дальше</h2>
30
<h2>Что дальше</h2>
31
<p>Проект еще не завершен. Вот над чем мы работаем сейчас:</p>
31
<p>Проект еще не завершен. Вот над чем мы работаем сейчас:</p>
32
<ol><li>Расширяем возможность конфигурирования, но при этом сохраняем ее максимально простой. Не хочется определять тысячу параметров, если нужно всего два, а остальное подходит по умолчанию. К этому относятся флаги компиляции (сейчас изменить их можно во внутреннем файле конфигурации src/config.py), пути установки, пользователя для запуска.</li>
32
<ol><li>Расширяем возможность конфигурирования, но при этом сохраняем ее максимально простой. Не хочется определять тысячу параметров, если нужно всего два, а остальное подходит по умолчанию. К этому относятся флаги компиляции (сейчас изменить их можно во внутреннем файле конфигурации src/config.py), пути установки, пользователя для запуска.</li>
33
<li>Добавляем варианты автоматической отправки пакета в различные хранилища артефактов.</li>
33
<li>Добавляем варианты автоматической отправки пакета в различные хранилища артефактов.</li>
34
<li>Выполнения пользовательской команды при загрузке модуля (например для использования<a>github.com/nginx-modules/nginx_upstream_check_module</a>нужно сначала применить патч определенной версии)</li>
34
<li>Выполнения пользовательской команды при загрузке модуля (например для использования<a>github.com/nginx-modules/nginx_upstream_check_module</a>нужно сначала применить патч определенной версии)</li>
35
<li>Добавляем проведение тестов:</li>
35
<li>Добавляем проведение тестов:</li>
36
<li>Пакет корректно устанавливается.</li>
36
<li>Пакет корректно устанавливается.</li>
37
<li>Nginx имеет нужную версию и собран с требуемыми флагами и модулями.</li>
37
<li>Nginx имеет нужную версию и собран с требуемыми флагами и модулями.</li>
38
<li>Создаются нужные пути, учетные записи и так далее.</li>
38
<li>Создаются нужные пути, учетные записи и так далее.</li>
39
</ol><p>Но пользоваться этим инструментом вы можете уже сейчас, а также предлагать доработки -<a>github.com/TinkoffCreditSystems/Nginx-builder</a>wellcome!</p>
39
</ol><p>Но пользоваться этим инструментом вы можете уже сейчас, а также предлагать доработки -<a>github.com/TinkoffCreditSystems/Nginx-builder</a>wellcome!</p>
40
40