Hola
Mi nombre es Sergey, trabajo como ingeniero de infraestructura en el equipo API de la plataforma tinkoff.ru.
En este artículo hablaré sobre los problemas que nuestro equipo enfrentó al preparar equilibradores basados en
Nginx para varios proyectos. También hablaré sobre la herramienta que me permitió superar la mayoría de ellos.
Nginx es un servidor proxy multifuncional y en desarrollo activo. Tiene una gran cantidad de módulos,
pero esta no es una lista completa . Cada proyecto impone ciertos requisitos sobre la funcionalidad del equilibrador y la versión de Nginx (por ejemplo, la presencia de http / 2 y proxying grpc) y la composición de sus módulos.
Queremos ver la última versión con el conjunto correcto de módulos, trabajando bajo una distribución específica de Linux. En nuestro caso, estos son sistemas basados en deb y rpm. La opción de contenedor no se considera en este artículo.
Queremos cambiar rápidamente la funcionalidad de nuestros equilibradores. Y aquí surge la pregunta de inmediato: ¿cómo lograr esto gastando la menor cantidad de recursos posible? Y sería mejor configurar el proceso para que podamos establecer un número finito de parámetros de entrada, y en la salida obtener un artefacto en forma de un paquete deb / rpm para el sistema operativo deseado.
Como resultado, se pueden formular varios problemas:
- No siempre hay paquetes con la última versión de Nginx.
- No hay paquetes con los módulos correctos.
- Compilar y ensamblar un paquete manualmente lleva mucho tiempo y es simplemente tedioso.
- No hay una descripción de cómo se construye una instancia particular de Nginx.
Para resolver estos problemas, una determinada herramienta pide aceptar una especificación en formato legible para humanos y recopilar el paquete Nginx con la funcionalidad necesaria.
Al no haber encontrado una opción adecuada para nosotros en la inmensidad del github, decidimos crear nuestra propia herramienta:
nginx-builder .
Especificaciones
En nuestra herramienta, queríamos crear una descripción de especificación en forma de código, que luego se puede poner en el repositorio de Git. Para hacer esto, elegimos el formato habitual para tales cosas: yaml. Ejemplo de especificación:
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
Aquí indicamos que queremos ver un paquete deb con Nginx versión 1.14.2 con el conjunto de módulos deseado. La sección con módulos es opcional. Para cada uno de ellos puede configurar:
- Nombre
- Dirección donde puede obtenerla:
- Repositorio Git. También puede especificar una rama o etiqueta.
- Enlace web al archivo.
- Enlace local al archivo.
Algunos módulos requieren la instalación de dependencias adicionales, por ejemplo, nginx-auth-ldap necesita instalar libldap2-dev. Las dependencias necesarias también se pueden especificar en la descripción del módulo.
El medio ambiente
En nuestra herramienta, puede obtener rápidamente un entorno con utilidades instaladas para compilar, crear un paquete y otro software auxiliar. Aquí, el contenedor docker con todo lo que necesita es el mejor (el repositorio ya tiene un par de ejemplos de archivos docker para ubuntu y centos).
Después de que el entorno compila y prepara la especificación, ejecutamos nuestro recopilador, preinstalando sus dependencias:
pip3 install -r requirements.txt ./main.py build -f [_].yaml -r [_]
El número de revisión aquí es opcional y sirve para versionar ensamblajes. Se registra en la metainformación del paquete, lo que facilita su actualización en los servidores.
Por los registros puedes observar lo que está sucediendo. Aquí hay un ejemplo de lo más destacado:
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'.
Entonces, con solo un par de comandos, creamos el entorno y el ensamblado Nginx deseado, y el paquete aparece en el directorio desde donde se ejecuta el script.
Incrustación
También podemos incrustar nuestra herramienta en procesos de CI / CD. Cualquiera de los muchos sistemas de CI existentes, como
Teamcity o
Gitlab CI, puede ayudar con esto.
Como resultado, cada vez que cambia la especificación en el repositorio de Git, el ensamblaje del artefacto se inicia automáticamente. El número de revisión está vinculado al contador de lanzamiento de compilación.
Después de pasar más tiempo, puede configurar el artefacto para enviarlo al repositorio de paquetes local, Nexus, Artifactory, etc.
Una ventaja adicional es que el archivo yaml de configuración se puede conectar a Ansible u otro sistema de configuración automática, y tomar de él el número de versión y el tipo de paquete que queremos implementar.
Que sigue
El proyecto aún no se ha completado. Esto es en lo que estamos trabajando ahora:
- Ampliamos la posibilidad de configuración, pero al mismo tiempo la mantenemos lo más simple posible. No quiero definir mil parámetros, si solo se necesitan dos, y el resto es el predeterminado. Esto incluye indicadores de compilación (ahora puede cambiarlos en el archivo de configuración interno src / config.py), rutas de instalación, usuario para ejecutar.
- Agregue opciones para enviar automáticamente el paquete a varios repositorios de artefactos.
- Al ejecutar un comando de usuario al cargar un módulo (por ejemplo, para usar github.com/nginx-modules/nginx_upstream_check_module, primero debe aplicar un parche de una versión determinada)
- Añadir prueba:
- El paquete está instalado correctamente.
- Nginx tiene la versión correcta y se compila con los indicadores y módulos necesarios.
- Se crean las rutas necesarias, las cuentas, etc.
Pero puede usar esta herramienta ahora, así como sugerir mejoras:
github.com/TinkoffCreditSystems/Nginx-builder ¡bienvenido!