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:
- Librerias Lua en Nginx que ejecutan un script de logeo de métricas en cada petición recibida, esto es un performance killer además de que no funciona(el script se ejecuta con errores).
- Cambio del formato de log de Nginx para que guarde tiempos de respuesta en los logs y asà parsearlos mediante mtail, tampoco funciona(solo saca las métricas del stat no del mtail).
- Habilitar el stats de Nginx y arrancar un exporter que lea el status y exporte los datos en forma de métricas, proporciona una información demasiado básica.
- Habilitar el VTS de Nginx y arrancar un exporter que lea el vts y exporte los datos en forma de métricas.
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 plus
Nos bajamos el código fuente y recompilamos Nginx indicándole donde encontrar módulos adicionales:
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:
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:
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:
vi /var/www/localhost/htdocs/index.html
<html>
<header><title>This is title</title></header>
<body>
kr0mtest
</body>
</html>
Reiniciamos el servicio:
Comrpobamos que podamos acceder al status desde local:
Compilamos e instalamos el exporter:
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:
rc-update add nginx-vts-exporter default
Comprobamos que el exporter esté a la escucha y que saque las métricas:
tcp6 0 0 :::9913 :::* LISTEN 30387/nginx-vts-exp
Filtramos el acceso al exporter ya que vamos a poner una capa de autenticación por delante mediante Nginx:
/etc/init.d/iptables save
rc-update add iptables default
Ahora el curl deberÃa de fallar:
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:
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:
Generamos el fichero de passwords:
htpasswd -c /etc/nginx/.htpasswd admin
Volvemos a consultar las métricas pero esta vez a través de Nginx y utilizando las credenciales:
El proceso de acceso a las métricas sigue la siguiente lógica:
- Puerto 9914 protegido por auth mediante Nginx -> proxy_pass localhost:9913
- Puerto 9913 filtrado por Iptables para que solo se acceda desde localhost -> /stats
- /stats filtrado por Nginx para que solo se acceda desde localhost
La configuración de Prometheus serÃa esta:
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
veremos en Telegram alertas como esta: