A partir de la versión 2.0 de Haproxy este lleva incorporado el exporter de Prometheus, de este modo podremos visualizar multitud de métricas mediante Grafana y recibir alertas en base a estas, en este tutorial explicaré como configurarlo bajo PMM2.
Compilamos e instalamos Haproxy con la opción prometheus-exporter habilitada:
emerge -av net-proxy/haproxy
La configuración del exporter se realiza en el mismo puerto que las stats pero dependiendo del path servirá las stats o las métricas.
frontend stats
bind :8405
option http-use-htx
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
Debemos proteger el acceso mediante password, la configuración completa serÃa esta:
global
stats socket ipv4@0.0.0.0:9999 level admin
stats socket /var/run/haproxy.sock mode 666 level admin
stats timeout 2m
defaults
option forwardfor
option http-server-close
mode http
timeout connect 5000
timeout client 50000
timeout server 50000
userlist statsuser
user admin insecure-password PASSWORD
frontend stats
bind :8405
acl pmmserver src PMM_SERVER_IP/32
acl statsauthok http_auth(statsuser)
http-request auth if !pmmserver !statsauthok
option http-use-htx
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
frontend www-http
bind *:80
default_backend www-backend
backend www-backend
server www00 SERVERIP:80 check
server www01 SERVERIP:80 check
NOTA: Con la configuración anterior solo pedirá password si se consultan las métricas desde un ip distinta a la del PMM server.
Arrancamos Haproxy:
rc-update add haproxy default
Comprobamos que los servicios se hayan bindeado a las interfaces correctas:
tcp 0 0 0.0.0.0:8405 0.0.0.0:* LISTEN 10154/haproxy
Podemos ver las métricas accediendo a la url:
Comprobamos que las stats sigan funcionando con normalidad:
http://SERVER_IP:8405/stats
admin/PASSWORD
Comprobamos que desde Prometheus no pida password:
Configuramos el scrape en Prometheus:
scrape_configs:
- job_name: haproxy
scrape_interval: 1m
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- SERVER_IP:8405
Recargamos la configuración:
En la sección de targets podemos ver el exporter, en mi caso monitorizo dos Haproxys:
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/12693
En PMM recientes(16/11/2022) he tenido que importar esta dashboard:
https://grafana.com/grafana/dashboards/16675-haproxy-2-full/
Para ello le damos a import:
Pegamos el id de la dashboard:
Ya podemos visualizar las gráficas:
Para el sistema de alertas podemos dumpear las métricas y definir las alarmas:
groups:
- name: haproxyRules
rules:
- alert: HaproxyDown
expr: up{job="haproxy"} == 0
for: 5m
labels:
severity: critical
- alert: HaproxyHighHttp4xxErrorRate
expr: sum(rate(haproxy_server_http_responses_total{code="4xx"}[1m])) by (server) / sum(rate(haproxy_server_http_responses_total{}[1m])) by (server) * 100 > 5
for: 5m
labels:
severity: critical
- alert: HaproxyHighHttp5xxErrorRate
expr: sum(rate(haproxy_server_http_responses_total{code="5xx"}[1m])) by (server) / sum(rate(haproxy_server_http_responses_total{}[1m])) by (server) * 100 > 5
for: 5m
labels:
severity: critical
- alert: HaproxyBackendConnectionErrors
expr: rate(haproxy_backend_connection_errors_total[1m]) * 100 > 5
for: 5m
labels:
severity: critical
- alert: HaproxyServerResponseErrors
expr: rate(haproxy_server_response_errors_total[1m]) * 100 > 5
for: 5m
labels:
severity: critical
- alert: HaproxyServerConnectionErrors
expr: rate(haproxy_server_connection_errors_total[1m]) * 100 > 5
for: 5m
labels:
severity: critical
- alert: HaproxyPendingRequests
expr: haproxy_backend_current_queue > 0
for: 5m
labels:
severity: warning
- alert: HaproxyServerHealthcheckFailure
expr: increase(haproxy_server_check_failures_total[1m]) > 0
for: 5m
labels:
severity: warning
- alert: HaproxyMaxConnectionsReached
expr: (haproxy_process_max_connections - haproxy_process_current_connections) <= 0
for: 5m
labels:
severity: critical
- alert: BackendWithoutActiveServers
expr: haproxy_backend_active_servers == 0
for: 5m
labels:
severity: critical
- alert: UnhealthyBackendStatus
expr: haproxy_backend_status != 1
for: 5m
labels:
severity: warning
- alert: UnhealthyServerStatus
expr: haproxy_server_status != 1
for: 5m
labels:
severity: critical
- alert: HaproxyFrontendSecurityBlockedRequests
expr: rate(haproxy_frontend_requests_denied_total[1m]) > 10
for: 5m
labels:
severity: warning
Recargamos la configuración:
Si paramos el haproxy veremos la siguiente alarma:
Si hemos seguido la guÃa sobre
Alertmanager
veremos en Telegram alertas como esta:
Si paramos un servidor web:
En Telegram: