Ciao!
Mi chiamo Sergey, sono un ingegnere infrastrutturale nel team della piattaforma API di tinkoff.ru.
In questo articolo parlerò dei problemi che il nostro team 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 essi.
Nginx è un server proxy multifunzionale e in continua evoluzione. Si distingue per l'ampia gamma di moduli disponibili, . Ogni progetto impone requisiti specifici sulle funzionalità del bilanciatore e sulla versione di Nginx (ad esempio il supporto per http/2 e il proxying grpc) e sui suoi moduli.
Desideriamo avere l'ultima versione con il set di moduli necessario, funzionante su una specifica distribuzione Linux. Nel nostro caso si tratta di sistemi basati su deb e rpm. L'opzione dei container non è trattata in questo articolo.
Desideriamo modificare rapidamente le funzionalità dei nostri bilanciatori. E qui si pone subito la domanda: come ottenere ciò spendendo il minor numero possibile di risorse? Sarebbe ideale organizzare il processo in modo da poter specificare un numero finale di parametri di input e ricevere in output un artefatto sotto forma di pacchetto deb/rpm per il sistema operativo desiderato.
Di conseguenza, possiamo formulare una serie di problemi:
- Non sempre ci sono pacchetti con la versione aggiornata di Nginx.
- Ci sono pacchetti senza i moduli necessari.
- La compilazione e la costruzione del pacchetto manualmente richiedono molto tempo e sono davvero stancanti.
- Manca la documentazione su come è stato assemblato un particolare istanza di Nginx.
Per risolvere questi problemi, sembra necessario uno strumento che prenda in input una specifica in un formato leggibile e costruisca un pacchetto Nginx con le funzionalità richieste.
Non trovando un'opzione adatta a noi nelle vastità di GitHub, abbiamo deciso di creare il nostro strumento — .
Specifiche
Nel nostro strumento volevamo creare una descrizione della specifica in formato codice, che poi potesse essere archiviata in un repository Git. Per questo abbiamo scelto un formato familiare per simili esigenze — 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 specifichiamo che vogliamo vedere un pacchetto deb con la versione di Nginx 1.14.2 con il set di moduli desiderato. La sezione moduli è opzionale. Per ciascuno di essi è possibile specificare:
- Nome.
- Indirizzo in cui può essere ottenuto:
- Repository Git. È possibile indicare anche il ramo o il tag.
- Link web per l'archivio.
- Link locale per l'archivio.
Alcuni moduli richiedono l'installazione di dipendenze aggiuntive, ad esempio per nginx-auth-ldap è necessaria l'installazione di libldap2-dev. Le dipendenze necessarie possono essere specificate anche nella descrizione del modulo.
Ambiente
Nel nostro strumento è possibile ottenere rapidamente un ambiente con gli strumenti necessari per la compilazione, la creazione del pacchetto e altre applicazioni ausiliarie. In questo caso, il contenitore Docker è l'ideale, con tutto il necessario (nel repository sono già presenti un paio di esempi di Dockerfile per ubuntu e centos).
Dopo aver redatto la specifica e preparato l'ambiente, avviamo il nostro builder, installando prima le sue dipendenze:
pip3 install -r requirements.txt
./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]
Il numero di revisione è qui opzionale e serve per il versionamento delle costruzioni. Viene registrato nelle metainformazioni del pacchetto, consentendo di aggiornarlo facilmente sui server.
Dai log è possibile monitorare quanto sta accadendo. Ecco un esempio dei punti principali:
builder - INFO - Analizza il file yaml: example.config.yaml
builder - INFO - Scarica script per la creazione del pacchetto deb
builder - INFO - Downloading nginx src...
builder - INFO - --> http://nginx.org/download/nginx-1.14.1.tar.gz
builder - INFO - Downloading moduli di terze parti...
builder - INFO - Il modulo nginx-auth-ldap verrà scaricato per branch
builder - INFO - -- Fatto: nginx-auth-ldap
builder - INFO - -- Fatto: ngx_http_substitutions_filter_module
builder - INFO - Il modulo headers-more-nginx-module verrà scaricato
builder - INFO - Il modulo nginx-module-vts verrà scaricato per tag
builder - INFO - -- Fatto: nginx-module-vts
builder - INFO - Il modulo ngx_devel_kit verrà scaricato per tag
builder - INFO - -- Fatto: ngx_devel_kit
builder - INFO - -- Fatto: ngx_cache_purge
builder - INFO - -- Fatto: ngx_http_dyups_module
builder - INFO - Scaricamento delle dipendenze
builder - INFO - Creazione del pacchetto .deb
builder - INFO - Esecuzione di 'dh_make'...
builder - INFO - Esecuzione di 'dpkg-buildpackage'...
dpkg-deb: costruzione del pacchetto 'nginx' in '../nginx_1.14.1-1_amd64.deb'.
Con appena un paio di comandi creiamo l'ambiente e la compilazione necessaria di Nginx, e il pacchetto appare nella directory da cui è stato avviato lo script.
Integrazione
Possiamo anche integrare il nostro strumento nei processi CI/CD. Questo può essere fatto grazie a uno dei numerosi sistemi CI esistenti oggi, ad esempio o .
Alla fine, ad ogni modifica della specifica nel repository Git, la compilazione dell'artefatto viene avviata automaticamente. Il numero di revisione è legato al contatore delle esecuzioni del build.
Investendo un po' più di tempo, è possibile configurare l'invio dell'artefatto a un repository locale di pacchetti, come Nexus, Artifactory e così via.
Un ulteriore vantaggio è che il file di configurazione yaml può essere collegato in Ansible o in un altro sistema di configurazione automatica, permettendo di prendere il numero di versione e il tipo di pacchetto che desideriamo deployare.
Cosa succede dopo
Il progetto non è ancora completato. Ecco su cosa stiamo lavorando attualmente:
- Stiamo ampliando le possibilità di configurazione, mantenendola però il più semplice possibile. Non vogliamo definire mille parametri se ne servono solo due, mentre gli altri possono restare ai valori predefiniti. Questo include le flag di compilazione (attualmente possono essere modificate nel file di configurazione interno src/config.py), i percorsi di installazione e 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 utilizzare è necessario prima applicare il patch di una versione specifica)
- Aggiungiamo l'esecuzione di test:
- Il pacchetto si installa correttamente.
- Nginx ha la versione necessaria ed è compilato con i flag e i moduli richiesti.
- Vengono creati i percorsi, gli account e così via necessari.
Ma puoi già utilizzare questo strumento e proporre miglioramenti — benvenuto!
Fonte: habr.com
