Esta integración de Kubernetes descubre automáticamente los pods de HAProxy en su clúster y recopila métricas sin configuración manual para cada instancia. Utiliza el haproxyreceiver de OpenTelemetry y el receivercreator para monitorear dinámicamente las sesiones de HAProxy, las requests, los errores y el estado del servidor backend en su entorno en contenedores.
Sugerencia
¿Ejecuta HAProxy en hosts Linux? Consulte la guía de instalación autohospedada para despliegues en máquinas virtuales o bare metal.
Antes de que empieces
Asegúrese de tener:
- Clave de licenciade New Relic válida
- Pods de HAProxy con el extremo de stats habilitado (generalmente en el puerto 8404)
- Una etiqueta en cada pod de HAProxy para el descubrimiento (por ejemplo,
app: haproxy) - Si está utilizando el método de instalación de Helm, complete la instalación base de Helm de OpenTelemetry en Kubernetes
Configurar el monitoreo de HAProxy
Agregue las siguientes secciones bajo
deployment.extraConfigen suvalues.yaml:Importante
En
deployment.extraConfig,pipelines:debe definirse en el nivel raíz — no anidado bajoservice:. La plantilla del chart de Helm mapeaextraConfig.pipelinesenservice.pipelines, yextraConfig.service.extensionsenservice.extensions.Extensiones:
extensions:k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falseVariables de entorno (agregar bajo
deployment.envs):deployment:envs:- name: OTEL_RESOURCE_ATTRIBUTESvalue: "host.id=$(KUBE_NODE_NAME)"Importante
El atributo de recurso
host.ides necesario para la síntesis de la entidad. Las imágenes de contenedor no tienen/etc/machine-id, por lo que debe inyectarlo a través deOTEL_RESOURCE_ATTRIBUTES. El chart de Helm ya estableceKUBE_NODE_NAMEdesde la API Downward de Kubernetes.Receptores:
receivers:receiver_creator/haproxy:watch_observers: [k8s_observer]receivers:haproxy:rule: type == "pod" && labels["app"] == "haproxy"config:endpoint: 'http://`endpoint`:8404/stats'collection_interval: 30sProcesadores:
processors:resource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: inserttransform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server","k8s",attributes["k8s.cluster.name"],attributes["k8s.namespace.name"],"pod",attributes["k8s.pod.name"],"haproxy","8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")Extensiones de servicio:
service:extensions: [k8s_observer]Pipelines:
pipelines:metrics/haproxy:receivers: [receiver_creator/haproxy]processors: [batch, resource/cluster, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlphttp/newrelic]Parámetro de configuración
La siguiente tabla describe los parámetros de configuración clave:
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de estadísticas.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
collection_intervalCon qué frecuencia recopilar métricas. El valor predeterminado es
30s.
Aplique los valores actualizados a su release de Helm en ejecución:
bash$helm upgrade nr-k8s-otel-collector newrelic/nr-k8s-otel-collector \>--namespace newrelic \>--reuse-values \>-f values.yaml
Después de completar la instalación base del manifiesto de OpenTelemetry para Kubernetes, configure el monitoreo de HAProxy:
Actualice la imagen del recolector para usar el recolector NRDOT.
En el archivo
deployment.yamlde su directorio localrendered, actualice la imagen a:image: newrelic/nrdot-collector:latestMonte el
/etc/machine-iddel host en el contenedor del recolector agregando esto a la especificación de despliegue:volumeMounts:- name: machine-idmountPath: /etc/machine-idreadOnly: truevolumes:- name: machine-idhostPath:path: /etc/machine-idtype: FileImportante
El atributo de recurso
host.ides necesario para la síntesis de entidades. El procesadorresourcedetectionlee/etc/machine-idpara completarlo. Sin este montaje de volumen,host.idno se establecerá y no se crearán entidades.Reemplace el contenido en
deployment-configmap.yamlbajodeployment-config.yaml: |con:extensions:health_check:endpoint: 0.0.0.0:13133k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/haproxy:watch_observers: [k8s_observer]receivers:haproxy:rule: type == "pod" && labels["app"] == "haproxy"config:endpoint: 'http://`endpoint`:8404/stats'collection_interval: 30sprocessors:resourcedetection:detectors: [env, system]system:resource_attributes:host.name:enabled: truehost.id:enabled: trueos.type:enabled: truebatch:send_batch_max_size: 1000timeout: 30ssend_batch_size: 800memory_limiter:check_interval: 1slimit_percentage: 80spike_limit_percentage: 25resource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: inserttransform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server","k8s",attributes["k8s.cluster.name"],attributes["k8s.namespace.name"],"pod",attributes["k8s.pod.name"],"haproxy","8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")exporters:otlp_http/newrelic:endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>"headers:api-key: ${env:NR_LICENSE_KEY}service:extensions: [health_check, k8s_observer]pipelines:metrics/haproxy:receivers: [receiver_creator/haproxy]processors: [resourcedetection, batch, resource/cluster, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlp_http/newrelic]Elimine el DaemonSet y el despliegue de kube-state-metrics (no son necesarios para el monitoreo exclusivo de HAProxy):
bash$kubectl delete daemonset nr-k8s-otel-collector-daemonset -n newrelic$kubectl delete deployment nr-k8s-otel-collector-kube-state-metrics -n newrelicReinicie el despliegue del recolector para aplicar sus cambios:
bash$kubectl rollout restart deployment nr-k8s-otel-collector-deployment -n newrelicParámetro de configuración
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de estadísticas.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
<YOUR_NEWRELIC_OTLP_ENDPOINT>Su extremo OTLP de New Relic. Para obtener más información, consulte el
.
Despliegue el OpenTelemetry Collector Contrib en su clúster de Kubernetes. El recolector descubre y extrae automáticamente métricas de sus pods de HAProxy. Elija entre Helm (usando el chart de Helm de OTel upstream) o manifiestos de Kubernetes sin procesar.
Cree un archivo
values.yamlcon la siguiente configuración de monitoreo de HAProxy:mode: deploymentimage:repository: otel/opentelemetry-collector-contribclusterRole:create: truerules:- apiGroups: [""]resources: ["pods", "nodes"]verbs: ["get", "list", "watch"]- apiGroups: ["apps"]resources: ["replicasets"]verbs: ["get", "list", "watch"]extraVolumes:- name: machine-idhostPath:path: /etc/machine-idtype: FileextraVolumeMounts:- name: machine-idmountPath: /etc/machine-idreadOnly: trueconfig:extensions:health_check:endpoint: ${env:MY_POD_IP}:13133k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/haproxy:watch_observers: [k8s_observer]receivers:haproxy:rule: type == "pod" && labels["app"] == "haproxy"config:endpoint: 'http://`endpoint`:8404/stats'collection_interval: 30sprocessors:resourcedetection:detectors: [env, system]system:resource_attributes:host.name:enabled: truehost.id:enabled: trueos.type:enabled: truebatch:send_batch_size: 1024timeout: 30smemory_limiter:check_interval: 1slimit_percentage: 80spike_limit_percentage: 25resource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: inserttransform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server", "k8s", attributes["k8s.cluster.name"], attributes["k8s.namespace.name"], "pod", attributes["k8s.pod.name"], "haproxy", "8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")exporters:otlp_http/newrelic:endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>"headers:api-key: "<YOUR_NEW_RELIC_LICENSE_KEY>"service:extensions: [health_check, k8s_observer]pipelines:metrics/haproxy:receivers: [receiver_creator/haproxy]processors: [resourcedetection, batch, resource/cluster, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlp_http/newrelic]Parámetro de configuración
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de estadísticas.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
<YOUR_NEWRELIC_OTLP_ENDPOINT>Su extremo OTLP de New Relic. Para obtener más información, consulte el
.
<YOUR_NEW_RELIC_LICENSE_KEY>Tu clave de licencia de ingesta de New Relic.
Instale utilizando el chart de Helm de OpenTelemetry upstream:
bash$helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts$helm repo update$helm upgrade --install haproxy-otel-collector open-telemetry/opentelemetry-collector \>-f values.yaml \>-n newrelic --create-namespace
Utilice esta opción si no puede usar Helm o prefiere administrar los recursos de Kubernetes directamente con kubectl.
Cree un secreto con su clave de licencia de New Relic:
bash$kubectl create namespace newrelic$kubectl create secret generic otel-collector-haproxy-secret \>--namespace newrelic \>--from-literal=licenseKey='<YOUR_NEW_RELIC_LICENSE_KEY>'Guarde el siguiente manifiesto en un archivo (por ejemplo,
otel-collector-haproxy.yaml):---apiVersion: v1kind: ServiceAccountmetadata:name: otel-collector-haproxynamespace: newreliclabels:app: otel-collector-haproxy---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:name: otel-collector-haproxylabels:app: otel-collector-haproxyrules:- apiGroups: [""]resources: ["pods", "nodes"]verbs: ["get", "list", "watch"]- apiGroups: ["apps"]resources: ["replicasets"]verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: otel-collector-haproxylabels:app: otel-collector-haproxyroleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: otel-collector-haproxysubjects:- kind: ServiceAccountname: otel-collector-haproxynamespace: newrelic---apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-haproxy-confignamespace: newreliclabels:app: otel-collector-haproxydata:collector-config.yaml: |extensions:health_check:endpoint: 0.0.0.0:13133k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/haproxy:watch_observers: [k8s_observer]receivers:haproxy:rule: type == "pod" && labels["app"] == "haproxy"config:endpoint: 'http://`endpoint`:8404/stats'collection_interval: 30sprocessors:resourcedetection:detectors: [env, system]system:resource_attributes:host.name:enabled: truehost.id:enabled: trueos.type:enabled: truebatch:send_batch_size: 1024timeout: 30smemory_limiter:check_interval: 1slimit_percentage: 80spike_limit_percentage: 25resource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: inserttransform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server", "k8s", attributes["k8s.cluster.name"], attributes["k8s.namespace.name"], "pod", attributes["k8s.pod.name"], "haproxy", "8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")exporters:otlp_http/newrelic:endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>"headers:api-key: ${env:NR_LICENSE_KEY}service:extensions: [health_check, k8s_observer]pipelines:metrics/haproxy:receivers: [receiver_creator/haproxy]processors: [resourcedetection, batch, resource/cluster, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlp_http/newrelic]---apiVersion: apps/v1kind: Deploymentmetadata:name: otel-collector-haproxynamespace: newreliclabels:app: otel-collector-haproxyspec:replicas: 1selector:matchLabels:app: otel-collector-haproxytemplate:metadata:labels:app: otel-collector-haproxyspec:serviceAccountName: otel-collector-haproxycontainers:- name: otel-collectorimage: otel/opentelemetry-collector-contrib:latestcommand:- "/otelcol-contrib"- "--config=/conf/collector-config.yaml"env:- name: NR_LICENSE_KEYvalueFrom:secretKeyRef:name: otel-collector-haproxy-secretkey: licenseKey- name: GOGCvalue: "80"ports:- name: healthcontainerPort: 13133protocol: TCPresources:limits:cpu: 500mmemory: 512Mirequests:cpu: 100mmemory: 256MivolumeMounts:- name: configmountPath: /conf- name: machine-idmountPath: /etc/machine-idreadOnly: truevolumes:- name: configconfigMap:name: otel-collector-haproxy-configitems:- key: collector-config.yamlpath: collector-config.yaml- name: machine-idhostPath:path: /etc/machine-idtype: FileImportante
El montaje de volumen
/etc/machine-ides necesario para la síntesis de entidades. El procesadorresourcedetectionlee este archivo para completar el atributo de recursohost.id. Sin él, no se crearán entidades en New Relic.Aplique el manifiesto:
bash$kubectl apply -f otel-collector-haproxy.yamlVerifique que el recolector se esté ejecutando y descubriendo los pods de HAProxy:
bash$kubectl get pods -n newrelic -l app=otel-collector-haproxy$kubectl logs -n newrelic -l app=otel-collector-haproxyDebería ver líneas de registro que muestren
starting receivercon las IP de su pod de HAProxy.Parámetro de configuración
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de estadísticas.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
<YOUR_NEWRELIC_OTLP_ENDPOINT>Su extremo OTLP de New Relic. Para obtener más información, consulte el
.
<YOUR_NEW_RELIC_LICENSE_KEY>Tu clave de licencia de ingesta de New Relic.
Use este enfoque si sus pods de HAProxy ya exponen un extremo /metrics de Prometheus (HAProxy 2.0+) y prefiere extraer métricas de Prometheus en lugar de conectarse al extremo de estadísticas CSV.
Sugerencia
Si aún no tiene habilitado el extremo de Prometheus, use las pestañas recolector NRDOT u OpenTelemetry Collector Contrib en su lugar. Se conectan directamente al extremo de estadísticas de HAProxy sin necesitar compatibilidad con Prometheus.
Importante
Este enfoque requiere HAProxy 2.0+ con el extremo de Prometheus integrado habilitado. Tu configuración de HAProxy debe incluir:
frontend stats bind *:8404 http-request use-service prometheus-exporter if { path /metrics }Y sus pods de HAProxy deben exponer un puerto con nombre para el extremo de métricas:
ports: - name: metrics containerPort: 8404Complete la instalación base de Helm de OpenTelemetry para Kubernetes para nr-k8s-otel-collector antes de continuar.
Agregue las siguientes secciones bajo
deployment.configMap.extraConfigen suvalues.yaml:Importante
En
deployment.configMap.extraConfig,pipelines:debe definirse en el nivel raíz — no anidado bajoservice:. La plantilla del chart de Helm mapeaextraConfig.pipelinesenservice.pipelines, yextraConfig.service.extensionsenservice.extensions.Extensiones:
extensions:k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falseVariables de entorno (agregar bajo
deployment.envs):deployment:envs:- name: OTEL_RESOURCE_ATTRIBUTESvalue: "host.id=$(KUBE_NODE_NAME)"Importante
El atributo de recurso
host.ides necesario para la síntesis de entidades. El procesadorresourcedetectionleeOTEL_RESOURCE_ATTRIBUTESpara completarlo. El chart de Helm ya estableceKUBE_NODE_NAMEdesde la API Downward de Kubernetes.Receptores:
receivers:receiver_creator/haproxy_prom:watch_observers: [k8s_observer]receivers:prometheus:rule: type == "port" && pod.labels["app"] == "haproxy" && port == 8404config:config:scrape_configs:- job_name: haproxy_prommetrics_path: /metricsscrape_interval: 30sstatic_configs:- targets:- '`endpoint`'resource_attributes:haproxy.addr: 'http://`endpoint`/metrics'Procesadores:
processors:resourcedetection:detectors: [env]filter/haproxy:metrics:include:match_type: regexpmetric_names:- "haproxy_frontend_bytes_in_total"- "haproxy_frontend_bytes_out_total"- "haproxy_frontend_requests_denied_total"- "haproxy_frontend_request_errors_total"- "haproxy_frontend_http_requests_total"- "haproxy_frontend_current_sessions"- "haproxy_frontend_max_session_rate"- "haproxy_frontend_http_requests_rate_max"- "haproxy_frontend_connections_rate_max"- "haproxy_backend_bytes_in_total"- "haproxy_backend_bytes_out_total"- "haproxy_backend_connection_errors_total"- "haproxy_backend_http_requests_total"- "haproxy_backend_current_sessions"- "haproxy_backend_max_session_rate"- "haproxy_backend_current_queue"- "haproxy_server_bytes_in_total"- "haproxy_server_bytes_out_total"- "haproxy_server_connection_errors_total"- "haproxy_server_current_sessions"- "haproxy_server_max_session_rate"- "haproxy_server_current_queue"transform/add_labels:metric_statements:- context: datapointstatements:- set(attributes["haproxy.service_name"], "FRONTEND") where IsMatch(metric.name, "^haproxy_frontend_.*")- set(attributes["haproxy.service_name"], "BACKEND") where IsMatch(metric.name, "^haproxy_backend_.*")- set(attributes["haproxy.service_name"], attributes["server"]) where IsMatch(metric.name, "^haproxy_server_.*")- set(attributes["haproxy.proxy_name"], attributes["proxy"]) where attributes["proxy"] != nil- delete_key(attributes, "proxy") where attributes["proxy"] != nil- delete_key(attributes, "server") where attributes["server"] != nilmetricstransform/rename:transforms:- include: haproxy_frontend_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_backend_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_server_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_frontend_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_backend_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_server_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_backend_connection_errors_totalaction: updatenew_name: haproxy.connections.errors- include: haproxy_server_connection_errors_totalaction: updatenew_name: haproxy.connections.errors- include: haproxy_frontend_requests_denied_totalaction: updatenew_name: haproxy.requests.denied- include: haproxy_frontend_request_errors_totalaction: updatenew_name: haproxy.requests.errors- include: haproxy_frontend_http_requests_totalaction: updatenew_name: haproxy.requests.total- include: haproxy_backend_http_requests_totalaction: updatenew_name: haproxy.requests.total- include: haproxy_backend_current_queueaction: updatenew_name: haproxy.requests.queued- include: haproxy_server_current_queueaction: updatenew_name: haproxy.requests.queued- include: haproxy_frontend_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_backend_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_server_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_frontend_http_requests_rate_maxaction: updatenew_name: haproxy.requests.rate- include: haproxy_frontend_connections_rate_maxaction: updatenew_name: haproxy.connections.rate- include: haproxy_frontend_max_session_rateaction: updatenew_name: haproxy.sessions.rate- include: haproxy_backend_max_session_rateaction: updatenew_name: haproxy.sessions.rate- include: haproxy_server_max_session_rateaction: updatenew_name: haproxy.sessions.rateresource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: inserttransform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server", "k8s", attributes["k8s.cluster.name"], attributes["k8s.namespace.name"], "pod", attributes["k8s.pod.name"], "haproxy", "8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")Extensiones de servicio:
service:extensions: [k8s_observer]Pipelines:
pipelines:metrics/haproxy_prom:receivers: [receiver_creator/haproxy_prom]processors: [resourcedetection, filter/haproxy, transform/add_labels, metricstransform/rename, resource/cluster, batch, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlp_http/newrelic]Parámetro de configuración
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de Prometheus.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
scrape_intervalCon qué frecuencia recolectar métricas de Prometheus. Predeterminado:
30s.
Aplique los valores actualizados a su release de Helm en ejecución:
bash$helm upgrade nr-k8s-otel-collector newrelic/nr-k8s-otel-collector \>--namespace newrelic \>--reuse-values \>-f values.yaml
Cree un archivo
values.yamlcon la configuración del receptor de Prometheus:mode: deploymentimage:repository: otel/opentelemetry-collector-contribclusterRole:create: truerules:- apiGroups: [""]resources: ["pods", "nodes"]verbs: ["get", "list", "watch"]- apiGroups: ["apps"]resources: ["replicasets"]verbs: ["get", "list", "watch"]extraVolumes:- name: machine-idhostPath:path: /etc/machine-idtype: FileextraVolumeMounts:- name: machine-idmountPath: /etc/machine-idreadOnly: trueconfig:extensions:health_check:endpoint: ${env:MY_POD_IP}:13133k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/haproxy_prom:watch_observers: [k8s_observer]receivers:prometheus:rule: type == "port" && pod.labels["app"] == "haproxy" && port == 8404config:config:scrape_configs:- job_name: haproxy_prommetrics_path: /metricsscrape_interval: 30sstatic_configs:- targets:- '`endpoint`'resource_attributes:haproxy.addr: 'http://`endpoint`/metrics'processors:resourcedetection:detectors: [env, system]system:resource_attributes:host.name:enabled: truehost.id:enabled: trueos.type:enabled: truefilter/haproxy:metrics:include:match_type: regexpmetric_names:- "haproxy_frontend_bytes_in_total"- "haproxy_frontend_bytes_out_total"- "haproxy_frontend_requests_denied_total"- "haproxy_frontend_request_errors_total"- "haproxy_frontend_http_requests_total"- "haproxy_frontend_current_sessions"- "haproxy_frontend_max_session_rate"- "haproxy_backend_bytes_in_total"- "haproxy_backend_bytes_out_total"- "haproxy_backend_connection_errors_total"- "haproxy_backend_http_requests_total"- "haproxy_backend_current_sessions"- "haproxy_backend_max_session_rate"- "haproxy_backend_current_queue"- "haproxy_server_bytes_in_total"- "haproxy_server_bytes_out_total"- "haproxy_server_connection_errors_total"- "haproxy_server_current_sessions"- "haproxy_server_max_session_rate"- "haproxy_server_current_queue"transform/add_labels:metric_statements:- context: datapointstatements:- set(attributes["haproxy.service_name"], "FRONTEND") where IsMatch(metric.name, "^haproxy_frontend_.*")- set(attributes["haproxy.service_name"], "BACKEND") where IsMatch(metric.name, "^haproxy_backend_.*")- set(attributes["haproxy.service_name"], attributes["server"]) where IsMatch(metric.name, "^haproxy_server_.*")- set(attributes["haproxy.proxy_name"], attributes["proxy"]) where attributes["proxy"] != nil- delete_key(attributes, "proxy") where attributes["proxy"] != nil- delete_key(attributes, "server") where attributes["server"] != nilmetricstransform/rename:transforms:- include: haproxy_frontend_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_backend_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_server_bytes_in_totalaction: updatenew_name: haproxy.bytes.input- include: haproxy_frontend_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_backend_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_server_bytes_out_totalaction: updatenew_name: haproxy.bytes.output- include: haproxy_backend_connection_errors_totalaction: updatenew_name: haproxy.connections.errors- include: haproxy_server_connection_errors_totalaction: updatenew_name: haproxy.connections.errors- include: haproxy_frontend_requests_denied_totalaction: updatenew_name: haproxy.requests.denied- include: haproxy_frontend_request_errors_totalaction: updatenew_name: haproxy.requests.errors- include: haproxy_frontend_http_requests_totalaction: updatenew_name: haproxy.requests.total- include: haproxy_backend_http_requests_totalaction: updatenew_name: haproxy.requests.total- include: haproxy_backend_current_queueaction: updatenew_name: haproxy.requests.queued- include: haproxy_server_current_queueaction: updatenew_name: haproxy.requests.queued- include: haproxy_frontend_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_backend_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_server_current_sessionsaction: updatenew_name: haproxy.sessions.count- include: haproxy_frontend_max_session_rateaction: updatenew_name: haproxy.sessions.rate- include: haproxy_backend_max_session_rateaction: updatenew_name: haproxy.sessions.rate- include: haproxy_server_max_session_rateaction: updatenew_name: haproxy.sessions.rateresource/cluster:attributes:- key: k8s.cluster.namevalue: "<YOUR_CLUSTER_NAME>"action: insertbatch:send_batch_size: 1024timeout: 30smemory_limiter:check_interval: 1slimit_percentage: 80spike_limit_percentage: 25transform/haproxy:metric_statements:- context: resourcestatements:- set(attributes["haproxy.display.name"], Concat(["server", "k8s", attributes["k8s.cluster.name"], attributes["k8s.namespace.name"], "pod", attributes["k8s.pod.name"], "haproxy", "8404"], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")exporters:otlp_http/newrelic:endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>"headers:api-key: "<YOUR_NEW_RELIC_LICENSE_KEY>"service:extensions: [health_check, k8s_observer]pipelines:metrics/haproxy_prom:receivers: [receiver_creator/haproxy_prom]processors: [resourcedetection, filter/haproxy, transform/add_labels, metricstransform/rename, resource/cluster, batch, transform/haproxy, transform/metadata_nullify, memory_limiter]exporters: [otlp_http/newrelic]Importante
El montaje de volumen
/etc/machine-ides necesario para la síntesis de entidades. El procesadorresourcedetectionlee este archivo para completar el atributo de recursohost.id. Sin él, no se crearán entidades en New Relic.Parámetro de configuración
Parámetro
Descripción
labels["app"] == "haproxy"Selector de etiquetas de pod utilizado para descubrir pod de HAProxy. Actualice la regla para que coincida con las etiquetas de su pod.
<YOUR_PORT_NUMBER>El puerto donde HAProxy expone su extremo de Prometheus.
<YOUR_CLUSTER_NAME>Reemplace con el nombre de su clúster de Kubernetes para su identificación en New Relic.
<YOUR_NEWRELIC_OTLP_ENDPOINT>Su extremo OTLP de New Relic. Para obtener más información, consulte el
.
<YOUR_NEW_RELIC_LICENSE_KEY>Tu clave de licencia de ingesta de New Relic.
scrape_intervalCon qué frecuencia recolectar métricas de Prometheus. Predeterminado:
30s.
Instale utilizando el chart de Helm de OpenTelemetry upstream:
bash$helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts$helm repo update$helm upgrade --install haproxy-prom-collector open-telemetry/opentelemetry-collector \>-f values.yaml \>-n newrelic --create-namespace
Ver tus datos en New Relic
Después de unos minutos, las métricas de HAProxy aparecen en New Relic. Para encontrar sus datos:
- Vaya a one.newrelic.com > All capabilities > All entities.
- Busque sus entidades de HAProxy por nombre o filtre por tipo de entidad
HAPROXYINSTANCE. - Seleccione una entidad para ver la página de resumen con las métricas doradas (sesiones por segundo, requests por segundo, errores de conexión).
Resolución de problemas
- Verifique que los pods de HAProxy tengan la etiqueta correcta (por ejemplo,
app: haproxy):kubectl get pods -l app=haproxy - Verifique que el extremo de estadísticas responda:
kubectl exec -it <haproxy-pod> -- curl -s http://localhost:8404/stats - Revise los registros del recolector en busca de errores de descubrimiento:
kubectl logs -n newrelic -l app.kubernetes.io/name=nr-k8s-otel-collector -f(NRDOT) okubectl logs -n newrelic -l app=otel-collector-haproxy -f(manifiesto de OTel Contrib) - Asegúrese de que el ServiceAccount del recolector tenga permisos de
get,listywatchen los pods.
Cada pod de HAProxy debe crear una entidad separada en New Relic. Si ve solo una entidad:
- Verifique que el recolector tenga
host.idconfigurado. En entornos en contenedores, agregue esto al despliegue del recolector:env:- name: K8S_NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName- name: OTEL_RESOURCE_ATTRIBUTESvalue: "host.id=$(K8S_NODE_NAME)" - Confirme diferentes valores de
haproxy.addrpor pod consultando:FROM Metric SELECT uniques(haproxy.addr) WHERE metricName LIKE 'haproxy.%' SINCE 10 minutes ago
- El
receiver_creatorusa la IP del pod (nolocalhost) para llegar a HAProxy. Asegúrese de que el frontend de estadísticas se vincule a*:8404(todas las interfaces), no a127.0.0.1:8404. - Verifique las políticas de red que podrían bloquear el tráfico entre el pod del recolector y los pods de HAProxy.
Próximos pasos
- Revise la referencia de métricas para ver una lista completa de las métricas recopiladas.
- Aprenda a buscar y consultar sus datos de HAProxy.
- Configura alertas basadas en las métricas doradas de HAProxy.