Montamos nuestro Nginx con un par de comandos

Hi!
Mi nombre es Sergey, trabajo como ingeniero de infraestructura en el equipo API de la plataforma tinkoff.ru.

En este artículo hablaré de los problemas que enfrentó nuestro equipo al preparar balanceadores basados ​​​​en Nginx para diversos proyectos. También te hablaré de la herramienta que me permitió superar la mayoría de ellos.

Nginx es un servidor proxy multifuncional y en desarrollo activo. Cuenta con una gran cantidad de módulos, Esta no es una lista completa. Cada proyecto impone ciertos requisitos sobre la funcionalidad del balanceador y la versión de Nginx (por ejemplo, la presencia de proxy http/2 y grpc) y la composición de sus módulos.

Nos gustaría ver una versión nueva con el conjunto de módulos requerido, ejecutándose en una distribución de Linux específica. En nuestro caso, se trata de sistemas basados ​​en deb y rpm. La opción con contenedores no se considera en este artículo.

Queremos cambiar rápidamente la funcionalidad de nuestros balanceadores. Y aquí surge inmediatamente la pregunta: ¿cómo lograrlo gastando la menor cantidad de recursos posible? Sería incluso mejor configurar el proceso para que podamos establecer un número finito de parámetros de entrada y, en la salida, recibir un artefacto en forma de un paquete deb/rpm para el sistema operativo deseado.

Como resultado, se pueden formular una serie de problemas:

  • No siempre hay paquetes con la última versión de Nginx.
  • No hay paquetes con los módulos requeridos.
  • Compilar y crear un paquete manualmente lleva mucho tiempo y es francamente tedioso.
  • No hay ninguna descripción de cómo se ensambla tal o cual instancia de Nginx.

Para resolver estos problemas, surge la necesidad de una herramienta que tome como entrada una especificación en un formato legible por humanos y ensamble un paquete Nginx con la funcionalidad necesaria basada en ella.

Al no encontrar una opción adecuada para nosotros en la inmensidad de Github, decidimos crear nuestra propia herramienta: constructor nginx.

Especificaciones

En nuestra herramienta, queríamos crear una descripción de la especificación en forma de código, que luego se pueda colocar en un repositorio de Git. Para hacer esto, elegimos el formato habitual para este tipo de 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 requerido. La sección de módulos es opcional. Para cada uno de ellos puedes configurar:

  • Título.
  • Dirección donde conseguirlo:
    • Repositorio Git. También puede especificar una rama o etiqueta.
    • Enlace web de archivo.
    • Enlace local al archivo.

Algunos módulos requieren la instalación de dependencias adicionales, por ejemplo, nginx-auth-ldap requiere la instalación de libldap2-dev. Las dependencias necesarias también se pueden especificar al describir el módulo.

Medio ambiente

En nuestra herramienta puede obtener rápidamente un entorno con utilidades instaladas para compilación, ensamblaje de paquetes y otro software auxiliar. Un contenedor Docker con todo lo que necesitas es ideal aquí (el repositorio ya tiene un par de ejemplos de archivos Docker para ubuntu y centos).

Una vez redactada la especificación y preparado el entorno, lanzamos nuestro constructor, habiendo instalado previamente sus dependencias:

pip3 install -r requirements.txt
./main.py build -f [конфиг_файл].yaml -r [номер_ревизии]

El número de revisión aquí es opcional y se utiliza para versiones de ensamblajes. Está escrito en la metainformación del paquete, lo que facilita su actualización en los servidores.
Desde los registros puedes monitorear lo que está sucediendo. A continuación se muestra un ejemplo de los puntos principales:

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 requerido, y el paquete aparece en el directorio desde donde se inicia el script.

incrustación

También podemos integrar nuestra herramienta en procesos de CI/CD. Cualquiera de los muchos sistemas de CI que existen hoy en día puede ayudar con esto, por ejemplo Ciudad del equipo o CI de Gitlab.

Como resultado, cada vez que cambia la especificación en el repositorio de Git, la compilación del artefacto se inicia automáticamente. El número de revisión está vinculado al contador de lanzamiento de compilación.
Con un poco más de tiempo, puede configurar el artefacto para que se envíe a su repositorio de paquetes local, Nexus, Artifactory, etc.

Una ventaja adicional es que el archivo de configuración yaml se puede conectar a Ansible u otro sistema de configuración automática, y de ahí podemos tomar el número de versión y el tipo de paquete que queremos implementar.

¿Qué sigue

El proyecto aún no está terminado. Esto es en lo que estamos trabajando ahora:

  • Ampliamos la posibilidad de configuración, pero al mismo tiempo la mantenemos lo más sencilla posible. No querrás definir mil parámetros si sólo necesitas dos y el resto encaja por defecto. Esto incluye indicadores de compilación (ahora puede cambiarlos en el archivo de configuración interno src/config.py), ruta de instalación y usuario de inicio.
  • Estamos agregando opciones para enviar automáticamente un paquete a varios repositorios de artefactos.
  • Ejecute un comando personalizado al cargar un módulo (por ejemplo, para usar github.com/nginx-modules/nginx_upstream_check_module primero debes aplicar un parche de una versión específica)
  • Agregar pruebas:
    • El paquete está instalado correctamente.
    • Nginx tiene la versión requerida y está construido con las banderas y módulos requeridos.
    • Se crean las rutas, cuentas, etc. necesarias.

Pero puedes usar esta herramienta ahora y también sugerir mejoras. github.com/TinkoffCreditSystems/Nginx-builder ¡Bienvenido!

Fuente: habr.com

Añadir un comentario