Ciao!
Mi chiamo Sergey e lavoro come ingegnere delle infrastrutture nel team API della piattaforma tinkoff.ru.
In questo articolo parlerò delle problematiche che la nostra squadra ha affrontato nella preparazione dei bilanciatori basati su per diversi progetti. Parlerò anche di uno strumento che ci ha permesso di superare gran parte di esse.
Nginx è un server proxy multifunzionale e in continua evoluzione. Si distingue per l'ampia gamma di moduli, . Ogni progetto impone determinati requisiti alle funzionalità del bilanciatore e alla versione di Nginx (ad esempio, la disponibilità di http/2 e il proxying grpc), nonché alla composizione dei suoi moduli.
Vogliamo vedere una versione aggiornata con il giusto set di moduli, funzionante su un certo distribuzione di Linux. Nel nostro caso, si tratta di sistemi basati su deb e rpm. L'opzione dei contenitori non è considerata in questo articolo.
Desideriamo apportare modifiche tempestive alle funzionalità dei nostri bilanciatori. E qui sorge immediatamente la domanda: come possiamo farlo spendendo il minor numero possibile di risorse? Sarebbe ancora meglio organizzare il processo in modo tale da poter specificare un numero finito di parametri di input e ricevere in output un artefatto sotto forma di pacchetto deb/rpm per il sistema operativo desiderato.
In definitiva, si possono formulare una serie di problemi:
- Non sempre sono disponibili pacchetti con l'ultima versione di Nginx.
- Non ci sono pacchetti con i moduli necessari.
- La compilazione e la creazione del pacchetto manualmente richiede molto tempo ed è semplicemente poco pratica.
- Manca una descrizione di come è stato assemblato un determinato istanza di Nginx.
Per risolvere questi problemi, si rende necessario creare uno strumento che prenda in input una specifica in un formato leggibile e costruisca il pacchetto Nginx con le funzionalità desiderate.
Non trovando un'opzione adeguata per noi su GitHub, abbiamo deciso di creare il nostro strumento — .
Specifiche
Nel nostro strumento, volevamo creare una descrizione della specifica sotto forma di codice, che potesse poi essere posizionata in un repository Git. Per questo abbiamo scelto un formato familiare per queste cose: yaml. Ecco un esempio di specifica:
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
Qui indichiamo che vogliamo vedere un pacchetto deb con la versione di Nginx 1.14.2 e il set di moduli richiesti. La sezione dei moduli è facoltativa. Per ciascuno di essi è possibile specificare:
- Nome.
- Indirizzo dove può essere ottenuto:
- Repository Git. È possibile anche specificare un ramo o un tag.
- Link web all'archivio.
- Link locale all'archivio.
Alcuni moduli richiedono l'installazione di dipendenze aggiuntive; ad esempio, per nginx-auth-ldap è necessario installare libldap2-dev. Le dipendenze necessarie possono essere specificate anche nella descrizione del modulo.
Ambiente
Nel nostro strumento puoi rapidamente ottenere un ambiente con le utilità installate per la compilazione, la creazione del pacchetto e altro software di supporto. Qui è particolarmente adatto un contenitore Docker con tutto il necessario (nel repository ci sono già un paio di esempi di file Docker per Ubuntu e CentOS).
Dopo aver redatto la specifica e preparato l'ambiente, avviamo il nostro costruttore, previa installazione delle sue dipendenze:
pip3 install -r requirements.txt
./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]
Il numero di revisione qui è facoltativo e serve per versionare le build. Viene registrato nelle metainformazioni del pacchetto, il che consente di aggiornarlo facilmente sui server.
Puoi osservare i log per monitorare cosa sta accadendo. Ecco un esempio dei punti principali:
builder - INFO - Analizzo il file yaml: example.config.yaml
builder - INFO - Scarico gli script per la build del pacchetto deb
builder - INFO - Downloading nginx src...
builder - INFO - --> http://nginx.org/download/nginx-1.14.1.tar.gz
builder - INFO - Scarico i moduli di terze parti...
builder - INFO - Il modulo nginx-auth-ldap sarà scaricato per ramo
builder - INFO - -- Fatto: nginx-auth-ldap
builder - INFO - -- Fatto: ngx_http_substitutions_filter_module
builder - INFO - Il modulo headers-more-nginx-module sarà scaricato
builder - INFO - Il modulo nginx-module-vts sarà scaricato per tag
builder - INFO - -- Fatto: nginx-module-vts
builder - INFO - Il modulo ngx_devel_kit sarà scaricato per tag
builder - INFO - -- Fatto: ngx_devel_kit
builder - INFO - -- Fatto: ngx_cache_purge
builder - INFO - -- Fatto: ngx_http_dyups_module
builder - INFO - Scarico dipendenze
builder - INFO - Costruendo il pacchetto .deb
builder - INFO - Eseguendo 'dh_make'...
builder - INFO - Eseguendo 'dpkg-buildpackage'...
dpkg-deb: costruendo il pacchetto 'nginx' in '../nginx_1.14.1-1_amd64.deb'.
In questo modo, con solo un paio di comandi, creiamo l'ambiente e la build necessaria di Nginx, e il pacchetto appare nella directory da cui è stato eseguito lo script.
Integrazione
Possiamo anche integrare il nostro strumento nei processi CI/CD. Questo può essere facilitato da uno dei molteplici sistemi CI esistenti oggi, per esempio o .
Alla fine, ad ogni modifica della specifica nel repository Git, viene automaticamente avviata la build dell'artefatto. Il numero di revisione è associato al contatore delle esecuzioni della build.
Investendo un po' più di tempo, possiamo configurare l'invio dell'artefatto in un repository locale di pacchetti, Nexus, Artifactory e così via.
Un ulteriore vantaggio è che il file di configurazione yaml può essere integrato in Ansible o in un altro sistema di configurazione automatica, e possiamo prelevare da lì il numero di versione e il tipo di pacchetto che desideriamo distribuire.
E ora?
Il progetto non è ancora concluso. Ecco su cosa stiamo lavorando attualmente:
- Espandiamo le possibilità di configurazione, mantenendola al contempo il più semplice possibile. Non vogliamo dover definire mille parametri se ci servono solo due e il resto va bene di default. Questo include le opzioni di compilazione (attualmente possono essere modificate nel file di configurazione interno src/config.py), i percorsi di installazione, l'utente per l'esecuzione.
- Aggiungiamo opzioni per l'invio automatico del pacchetto in vari archivi di artefatti.
- Esecuzione di comandi personalizzati al caricamento del modulo (ad esempio, per l'utilizzo di è necessario prima applicare una patch per una versione specifica)
- Aggiungiamo test:
- Il pacchetto si installa correttamente.
- Nginx ha la versione necessaria ed è stato costruito con i flag e i moduli richiesti.
- Vengono creati i percorsi necessari, gli account e così via.
Ma puoi già utilizzare questo strumento e proporre modifiche — benvenuto!
Fonte: habr.com
