El módulo VTS(Virtual Host Traffic Status) de Nginx nos permite visualizar estadísticas de Nginx por vhost, estas resultan muy interesantes para detectar posibles problemas de rendimiento o preveer futuras ampliaciones de hardware, en este artículo se explicará como configurar VTS y el exporter para que Prometheus sea capaz de leer dicha información.
La monitorización de Nginx mediante Prometheus se puede realizar empleando distintos exporters:
En la web de Prometheus podemos encontrar el enlace de dos exporters, la librería Lua y el VTS. Vamos a utilizar VTS ya que es la opción que mejor se adapta a mis necesidades.
Para que el exporter pueda leer los datos hay que compilar Nginx con el módulo VTS. Según el programador del módulo:
This is similar to the live activity monitoring of nginx plusNos bajamos el código fuente y recompilamos Nginx indicándole donde encontrar módulos adicionales:
cd /usr/src git clone git://github.com/vozlt/nginx-module-vts.git echo 'NGINX_ADD_MODULES="/usr/src/nginx-module-vts"' >> /etc/portage/make.conf emerge -av www-servers/nginx
En el configure que ejecuta emerge podemos ver:
configuring additional modules
adding module in /usr/src/nginx-module-vts
+ ngx_http_vhost_traffic_status_module was configured
Comprobamos que el Nginx compilado realmente soporte VTS:
nginx -V 2>&1 | tr -- - '\n'|grep vts vts
Configuramos Nginx para que solo permita el acceso a las estadísticas desde localhost ya que solo debe acceder a estas el exporter local:
vi /etc/nginx/nginx.conf
http { ... vhost_traffic_status_zone; server { listen 80; server_name _; access_log /var/log/nginx/localhost.access_log main; error_log /var/log/nginx/localhost.error_log info; root /var/www/localhost/htdocs; location /status { allow 127.0.0.1; deny all; vhost_traffic_status_display; vhost_traffic_status_display_format html; } } ... }
Creamos un docroot básico para hacer las pruebas:
mkdir /var/www/localhost/htdocs/
vi /var/www/localhost/htdocs/index.html
<html> <header><title>This is title</title></header> <body> kr0mtest </body> </html>
Reiniciamos el servicio:
/etc/init.d/nginx restart
Comrpobamos que podamos acceder al status desde local:
curl http://localhost/status/format/json | jq
Compilamos e instalamos el exporter:
mkdir /etc/portage/package.accept_keywords echo "app-metrics/nginx-vts-exporter ~amd64" > /etc/portage/package.accept_keywords/nginx-vts-exporter emerge -av app-metrics/nginx-vts-exporter
Arrancamos el exporter:
/etc/init.d/nginx-vts-exporter start rc-update add nginx-vts-exporter default
Comprobamos que el exporter esté a la escucha y que saque las métricas:
netstat -nputa|grep LISTEN|grep vts tcp6 0 0 :::9913 :::* LISTEN 30387/nginx-vts-exp curl http://SERVER_IP:9913/metrics|grep -v '#'
Filtramos el acceso al exporter ya que vamos a poner una capa de autenticación por delante mediante Nginx:
iptables -I INPUT 1 ! -s 127.0.0.1 -p tcp --dport 9913 -j DROP /etc/init.d/iptables save rc-update add iptables default
Ahora el curl debería de fallar:
curl http://SERVER_IP:9913/metrics|grep -v '#' curl: (28) Failed to connect to SERVER_IP port 9913: Operation timed out
Añadimos autenticación, si la petición viene del servidor PMM no pedimos credenciales:
vi /etc/nginx/nginx.conf
http { ... vhost_traffic_status_zone; server { listen 80; server_name _; access_log /var/log/nginx/localhost.access_log main; error_log /var/log/nginx/localhost.error_log info; root /var/www/localhost/htdocs; location /status { allow 127.0.0.1; deny all; vhost_traffic_status_display; vhost_traffic_status_display_format html; } } server { listen 9914; server_name _; location /metrics {
satisfy any;
allow PMM_SERVER_IP/32; auth_basic "Restricted Content"; auth_basic_user_file /etc/nginx/.htpasswd;
deny all;
proxy_pass http://127.0.0.1:9913; } } ... }
Reiniciamos el servicio:
/etc/init.d/nginx restart
Generamos el fichero de passwords:
emerge -av app-admin/apache-tools htpasswd -c /etc/nginx/.htpasswd admin PASSWORD
Volvemos a consultar las métricas pero esta vez a través de Nginx y utilizando las credenciales:
curl --user admin:PASSWORD http://SERVER_IP:9914/metrics|grep -v '#'
El proceso de acceso a las métricas sigue la siguiente lógica:
La configuración de Prometheus sería esta:
vi prometheusConf/prometheus.base.yml
scrape_configs:
- job_name: nginxExporter
scrape_interval: 1m
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- kr0mtest3:9914
- kr0mtest4:9914
Podemos ver el exporter en targets:
Ahora tan solo queda importar la dashboard correspondiente en Grafana y ya podremos visualizar los datos.
Vamos a Dashboards -> Manage
Importamos esta dashboard:
https://grafana.com/grafana/dashboards/2949
Para ello le damos a import:
Pegamos el id de la dashboard:
Ya podemos visualizar las gráficas:
Las alertas de Prometheus serían estas, recordad que en PMM2 las alertas se configuran desde Grafana(http://pmm.alfaexploit.com/graph/d/pmm-settings/):
groups: - name: nginxRules rules: - alert: NginxDown expr: sum(up{job="nginxExporter"} == 0) by (instance) for: 5m labels: severity: critical
Si paramos un Nginx podemos ver la alarma:
Si hemos seguido la guía sobre Alertmanager: https://www.alfaexploit.com/readArticle/363 veremos en Telegram alertas como esta:
Si te ha gustado el artículo puedes invitarme a un redbull aquí.