Hi!
Nazywam się Sergey, pracuję jako inżynier infrastruktury w zespole API platformy Tinkoff.ru.
W tym artykule opowiem o problemach, z jakimi borykał się nasz zespół przygotowując w oparciu o wyważarki nginx dla różnych projektów. Opowiem też o narzędziu, które pozwoliło mi pokonać większość z nich.
Nginx to wielofunkcyjny i aktywnie rozwijający się serwer proxy. Posiada dużą liczbę modułów, Ta lista nie jest kompletna. Każdy projekt nakłada pewne wymagania na funkcjonalność balansera i wersję Nginx (np. obecność proxy http/2 i grpc) oraz skład jego modułów.
Chcielibyśmy zobaczyć świeżą wersję z wymaganym zestawem modułów, działającą pod konkretną dystrybucją Linuksa. W naszym przypadku są to systemy oparte na deb i RPM. W tym artykule nie uwzględniono opcji z kontenerami.
Zależy nam na szybkiej zmianie funkcjonalności naszych balanserów. I tu od razu pojawia się pytanie: jak to osiągnąć, wydając jak najmniej środków? Jeszcze lepiej byłoby skonfigurować proces tak, abyśmy mogli określić skończoną liczbę parametrów wejściowych, a na wyjściu otrzymać artefakt w postaci pakietu deb/rpm dla żądanego systemu operacyjnego.
W rezultacie można sformułować szereg problemów:
Nie zawsze są dostępne pakiety z najnowszą wersją Nginx.
Brak pakietów z wymaganymi modułami.
Ręczna kompilacja i budowanie pakietu jest czasochłonne i wręcz żmudne.
Nie ma opisu, w jaki sposób składana jest ta czy inna instancja Nginx.
Aby rozwiązać te problemy, pojawia się zapotrzebowanie na narzędzie, które jako dane wejściowe pobierze specyfikację w formacie czytelnym dla człowieka i na jej podstawie złoży pakiet Nginx z niezbędną funkcjonalnością.
Nie znajdując dla nas odpowiedniej opcji na ogromie Githuba, postanowiliśmy stworzyć własne narzędzie - kreator nginx.
Specyfikacja
W naszym narzędziu chcieliśmy stworzyć opis specyfikacji w formie kodu, który następnie będzie można umieścić w repozytorium Git. W tym celu wybraliśmy format znany z takich rzeczy - yaml. Przykład specyfikacji:
Tutaj wskazujemy, że chcemy zobaczyć pakiet deb z Nginx w wersji 1.14.2 z wymaganym zestawem modułów. Sekcja z modułami jest opcjonalna. Dla każdego z nich możesz ustawić:
Nazwa.
Adres, pod którym można go dostać:
Repozytorium Gita. Możesz także określić gałąź lub znacznik.
Link do archiwum.
Lokalny link do archiwum.
Niektóre moduły wymagają zainstalowania dodatkowych zależności, na przykład nginx-auth-ldap wymaga zainstalowanej biblioteki libldap2-dev. Niezbędne zależności można także określić przy opisie modułu.
Środowisko
W naszym narzędziu możesz szybko uzyskać środowisko z zainstalowanymi narzędziami do kompilacji, składania pakietów i innym oprogramowaniem pomocniczym. Kontener Docker ze wszystkim, czego potrzebujesz, jest tutaj idealny (w repozytorium znajduje się już kilka przykładów plików Dockera dla Ubuntu i Centos).
Po ustaleniu specyfikacji i przygotowaniu środowiska uruchamiamy nasz builder, po uprzednim zainstalowaniu jego zależności:
Numer wersji w tym miejscu jest opcjonalny i jest używany do zestawów wersji. Jest on zapisany w metainformacjach pakietu, co ułatwia aktualizację na serwerach.
Z dzienników możesz monitorować, co się dzieje. Oto przykład głównych punktów:
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'.
Zatem za pomocą kilku poleceń tworzymy środowisko i wymagany zestaw Nginx, a pakiet pojawia się w katalogu, z którego uruchamiany jest skrypt.
Osadzanie
Nasze narzędzie możemy także zintegrować z procesami CI/CD. Na przykład dowolny z wielu istniejących obecnie systemów CI może w tym pomóc Miasto drużyny lub Gitlab CI.
W rezultacie za każdym razem, gdy specyfikacja zmienia się w repozytorium Git, automatycznie uruchamiana jest kompilacja artefaktu. Numer wersji jest powiązany z licznikiem uruchomienia kompilacji.
Mając trochę więcej czasu, możesz skonfigurować wysyłanie artefaktu do lokalnego repozytorium pakietów, Nexusa, Artifactory i tak dalej.
Dodatkową zaletą jest to, że plik konfiguracyjny yaml można podłączyć do Ansible lub innego systemu automatycznej konfiguracji i stamtąd możemy pobrać numer wersji i typ pakietu, który chcemy wdrożyć.
Co dalej
Projekt nie jest jeszcze ukończony. Oto nad czym teraz pracujemy:
Rozszerzamy możliwości konfiguracji, ale jednocześnie dbamy o to, aby była ona jak najprostsza. Nie chcesz definiować tysiąca parametrów, jeśli potrzebujesz tylko dwóch, a reszta domyślnie pasuje. Obejmuje to flagi kompilacji (teraz możesz je zmienić w wewnętrznym pliku konfiguracyjnym src/config.py), ścieżkę instalacji i użytkownika uruchamiania.
Dodajemy opcje automatycznego wysyłania pakietu do różnych repozytoriów artefaktów.