Monitoree sus instancias de Redis en Kubernetes desplegando el OpenTelemetry Collector como un DaemonSet. El recolector usa k8s_observer y receiver_creator para descubrir automáticamente los pods de Redis basándose en etiquetas — no se necesitan cambios en sus despliegues de Redis existentes.
Importante
El patrón compuesto (server.address:server.port) no es compatible en Kubernetes. Las IP de los pods son efímeras y cambian en cada reinicio, lo que crearía entidades duplicadas. Use el patrón redis.instance.id con un identificador estable (por ejemplo, cluster-name.namespace:port).
Antes de que empieces
Necesitará lo siguiente antes de configurar el recolector:
- Tu New Relic
kubectlacceso a su clúster de Kubernetes con permisos de administrador- Redis ejecutándose en su clúster de Kubernetes — se recomienda la versión 6.0 o posterior (la 4.0 y posteriores funcionan con un conjunto de métricas reducido)
- Para las rutas de NRDOT y OpenTelemetry Collector Contrib, sus pods de Redis deben llevar una etiqueta detectable (por ejemplo,
app: redis) - HTTPS saliente (puerto 443) al extremo OTLPde New Relic
Elija su distribución del recolector en Opciones de instalación: el recolector NRDOT, el Collector Contrib de OpenTelemetry o el receptor de Prometheus. Las rutas de NRDOT y Contrib descubren automáticamente los pod de Redis con k8s_observer; la ruta del receptor de Prometheus extrae un redis_exporter que usted despliega junto a Redis.
Opciones de instalación
Crear namespace y credenciales
Cree un namespace newrelic y almacene su clave de licencia y extremo OTLP en un Kubernetes Secret, que el recolector lee en tiempo de ejecución para que sus credenciales queden fuera de la configuración:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicConfigurar RBAC
El k8s_observer necesita permisos para observar pods. Cree rbac.yaml:
apiVersion: v1kind: ServiceAccountmetadata: name: otel-collector-redis namespace: newrelic---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: otel-collector-redisrules: - apiGroups: [""] resources: ["pods", "namespaces", "nodes"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["replicasets"] verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: otel-collector-redissubjects: - kind: ServiceAccount name: otel-collector-redis namespace: newrelicroleRef: kind: ClusterRole name: otel-collector-redis apiGroup: rbac.authorization.k8s.io$kubectl apply -f rbac.yamlConfigurar el recolector
Este ConfigMap le indica al recolector cómo descubrir los pods de Redis, recopilar sus métricas y enviarlas a New Relic. Se encarga de tres tareas principales:
Descubrir los pods de Redis automáticamente con
k8s_observery elreceiver_creatorDé forma a los datos — reduzca la cardinalidad, convierta los contadores en deltas y establezca la identidad de la entidad
Exporte las métricas procesadas a New Relic a través de OTLP
Crear
otel-collector-config.yaml:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/redis:watch_observers: [k8s_observer]receivers:redis:rule: type == "pod" && labels["app"] == "redis" # Update with your Redis pod labelsconfig:endpoint: "`endpoint`:6379"collection_interval: 10smetrics:redis.maxmemory:enabled: trueredis.role:enabled: falseredis.cmd.calls:enabled: trueredis.cmd.usec:enabled: trueredis.clients.max_input_buffer:enabled: falseredis.clients.max_output_buffer:enabled: falseredis.replication.backlog_first_byte_offset:enabled: falseresource_attributes:server.address:enabled: falseserver.port:enabled: falseprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/k8s_cluster:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertcumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check, k8s_observer]pipelines:metrics/redis:receivers: [receiver_creator/redis]processors: [memory_limiter, resource/k8s_cluster, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlQué hace esta configuración
Cada componente en la canalización tiene un trabajo específico:
Componente Descripción health_checkExpone un extremo de estado en 0.0.0.0:13133para que pueda confirmar que el recolector se está ejecutando.k8s_observerSupervisa la API de Kubernetes en busca de pods para que el recolector pueda descubrir instancias de Redis dinámicamente. receiver_creator/redisInicia un receptor redispara cada pod que coincida con la regla (labels["app"] == "redis") y lee sus métricas del comandoINFOde Redis cada 10 segundos.memory_limiterLimita el uso de memoria del recolector (límite flexible de 256 MiB, pico de 64 MiB) para proteger el pod. resource/k8s_clusterEstablece k8s.cluster.nameyredis.instance.id, la identidad estable para su entidad de Redis (el patrón compuestoserver.address:server.portno se utiliza en Kubernetes).attributes/entity_tagsMarca instrumentation.provider: opentelemetryen cada métrica para que pueda limitar las consultas a la ruta de OpenTelemetry.cumulativetodeltaConvierte los contadores acumulativos de Redis —comandos, aciertos de keyspace, desalojos, etc.— a valores delta para que New Relic grafique las tasas correctamente. filter/cardinalityDescarta los puntos de datos de alta cardinalidad (estados de CPU distintos de userysys, y métricas por comando para comandos poco comunes) para controlar el costo de ingesta.transform/metadata_nullifyBorra las descripciones y unidades de las métricas para reducir el tamaño de la carga. batchAgrupa los puntos de datos antes de la exportación (2048 por lote, hasta 4096) y los vacía al menos cada 10 segundos para reducir la sobrecarga de la red. otlp_httpExporta las métricas procesadas a New Relic a través de OTLP con compresión gzip, autenticadas con su clave de licencia.
Opcional: recopilar logs de Redis
Más allá de las métricas, el recolector puede reenviar los logs de Redis a New Relic para que pueda correlacionar los logs de eventos —reinicios, eventos de persistencia o errores— con los picos de métricas en la misma entidad. Para recopilarlos, agregue el receptor filelog a su ConfigMap y monte /var/log/pods en el DaemonSet.
Agregue a la sección receivers en su ConfigMap:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisAgregue un procesador resource/redis_logs:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Update with cluster.namespace:port action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertAgregue una canalización de logs a la sección de servicio:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Descomente el montaje de volumen varlogpods en el DaemonSet a continuación.
Opcional: habilitar el monitoreo de Redis Cluster
El monitoreo de Redis Cluster actualmente requiere el enfoque del receptor de Prometheus (usando redis_exporter). El receptor de Redis nativo del NRDOT Collector aún no es compatible con el comando CLUSTER INFO necesario para las métricas del clúster. Use la pestaña del receptor de Prometheus para la configuración del monitoreo del clúster.
Despliegue el DaemonSet
Crear otel-collector-daemonset.yaml:
apiVersion: apps/v1kind: DaemonSetmetadata: name: otel-collector-redis namespace: newrelicspec: selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: serviceAccountName: otel-collector-redis containers: - name: otel-collector image: newrelic/nrdot-collector:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel - name: machine-id mountPath: /etc/machine-id readOnly: true # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config - name: machine-id hostPath: path: /etc/machine-id # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-daemonset.yamlVerificar
Confirme que el pod del recolector se esté ejecutando:
$kubectl get pods -n newrelic -l app=otel-collector-redisEl pod debe mostrar Running con todos los contenedores listos. Si es CrashLoopBackOff o Error, verifique sus registros con kubectl logs -n newrelic -l app=otel-collector-redis —las causas más comunes son errores de YAML de ConfigMap, un ClusterRole de RBAC faltante o la regla de descubrimiento que no coincide con las etiquetas de su pod de Redis.
Luego confirme que sus métricas están llegando a New Relic. Espere aproximadamente un minuto después de que se inicie el pod, luego ejecute esta consulta en el generador de consultas:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoUn recuento distinto de cero confirma que las métricas de Redis están fluyendo. Si devuelve 0, consulte Solucionar problemas de Redis (OpenTelemetry).
Crear namespace y credenciales
Cree un namespace newrelic y almacene su clave de licencia y extremo OTLP en un Kubernetes Secret, que el recolector lee en tiempo de ejecución para que sus credenciales queden fuera de la configuración:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicConfigurar RBAC
El k8s_observer necesita permisos para observar pods. Cree rbac.yaml:
apiVersion: v1kind: ServiceAccountmetadata: name: otel-collector-redis namespace: newrelic---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: otel-collector-redisrules: - apiGroups: [""] resources: ["pods", "namespaces", "nodes"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["replicasets"] verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: otel-collector-redissubjects: - kind: ServiceAccount name: otel-collector-redis namespace: newrelicroleRef: kind: ClusterRole name: otel-collector-redis apiGroup: rbac.authorization.k8s.io$kubectl apply -f rbac.yamlConfigurar el recolector
Este ConfigMap le indica al recolector cómo descubrir los pods de Redis, recopilar sus métricas y enviarlas a New Relic. Se encarga de tres tareas principales:
Descubrir los pods de Redis automáticamente con
k8s_observery elreceiver_creatorDé forma a los datos — reduzca la cardinalidad, convierta los contadores en deltas y establezca la identidad de la entidad
Exporte las métricas procesadas a New Relic a través de OTLP
Crear
otel-collector-config.yaml:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/redis:watch_observers: [k8s_observer]receivers:redis:rule: type == "pod" && labels["app"] == "redis" # Update with your Redis pod labelsconfig:endpoint: "`endpoint`:6379"collection_interval: 10smetrics:redis.maxmemory:enabled: trueredis.role:enabled: falseredis.cmd.calls:enabled: trueredis.cmd.usec:enabled: trueredis.clients.max_input_buffer:enabled: falseredis.clients.max_output_buffer:enabled: falseredis.replication.backlog_first_byte_offset:enabled: falseresource_attributes:server.address:enabled: falseserver.port:enabled: falseprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/k8s_cluster:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertcumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check, k8s_observer]pipelines:metrics/redis:receivers: [receiver_creator/redis]processors: [memory_limiter, resource/k8s_cluster, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlQué hace esta configuración
Cada componente en la canalización tiene un trabajo específico:
Componente Descripción health_checkExpone un extremo de estado en 0.0.0.0:13133para que pueda confirmar que el recolector se está ejecutando.k8s_observerSupervisa la API de Kubernetes en busca de pods para que el recolector pueda descubrir instancias de Redis dinámicamente. receiver_creator/redisInicia un receptor redispara cada pod que coincida con la regla (labels["app"] == "redis") y lee sus métricas del comandoINFOde Redis cada 10 segundos.memory_limiterLimita el uso de memoria del recolector (límite flexible de 256 MiB, pico de 64 MiB) para proteger el pod. resource/k8s_clusterEstablece k8s.cluster.nameyredis.instance.id, la identidad estable para su entidad de Redis (el patrón compuestoserver.address:server.portno se utiliza en Kubernetes).attributes/entity_tagsMarca instrumentation.provider: opentelemetryen cada métrica para que pueda limitar las consultas a la ruta de OpenTelemetry.cumulativetodeltaConvierte los contadores acumulativos de Redis —comandos, aciertos de keyspace, desalojos, etc.— a valores delta para que New Relic grafique las tasas correctamente. filter/cardinalityDescarta los puntos de datos de alta cardinalidad (estados de CPU distintos de userysys, y métricas por comando para comandos poco comunes) para controlar el costo de ingesta.transform/metadata_nullifyBorra las descripciones y unidades de las métricas para reducir el tamaño de la carga. batchAgrupa los puntos de datos antes de la exportación (2048 por lote, hasta 4096) y los vacía al menos cada 10 segundos para reducir la sobrecarga de la red. otlp_httpExporta las métricas procesadas a New Relic a través de OTLP con compresión gzip, autenticadas con su clave de licencia.
Opcional: recopilar logs de Redis
Más allá de las métricas, el recolector puede reenviar los logs de Redis a New Relic para que pueda correlacionar los logs de eventos —reinicios, eventos de persistencia o errores— con los picos de métricas en la misma entidad. Para recopilarlos, agregue el receptor filelog a su ConfigMap y monte /var/log/pods en el DaemonSet.
Agregue a la sección receivers en su ConfigMap:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisAgregue un procesador resource/redis_logs:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Update with cluster.namespace:port action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertAgregue una canalización de logs a la sección de servicio:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Opcional: habilitar el monitoreo de Redis Cluster
El monitoreo de Redis Cluster actualmente requiere el enfoque del receptor de Prometheus (usando redis_exporter). El receptor de Redis nativo de OTel Collector Contrib aún no es compatible con el comando CLUSTER INFO necesario para las métricas del clúster. Use la pestaña del receptor de Prometheus para la configuración del monitoreo del clúster.
Despliegue el DaemonSet
Crear otel-collector-daemonset.yaml:
apiVersion: apps/v1kind: DaemonSetmetadata: name: otel-collector-redis namespace: newrelicspec: selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: serviceAccountName: otel-collector-redis containers: - name: otel-collector image: otel/opentelemetry-collector-contrib:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel - name: machine-id mountPath: /etc/machine-id readOnly: true # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config - name: machine-id hostPath: path: /etc/machine-id # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-daemonset.yamlVerificar
Confirme que el pod del recolector se esté ejecutando:
$kubectl get pods -n newrelic -l app=otel-collector-redisEl pod debe mostrar Running con todos los contenedores listos. Si es CrashLoopBackOff o Error, verifique sus registros con kubectl logs -n newrelic -l app=otel-collector-redis —las causas más comunes son errores de YAML de ConfigMap, un ClusterRole de RBAC faltante o la regla de descubrimiento que no coincide con las etiquetas de su pod de Redis.
Luego confirme que sus métricas están llegando a New Relic. Espere aproximadamente un minuto después de que se inicie el pod, luego ejecute esta consulta en el generador de consultas:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoUn recuento distinto de cero confirma que las métricas de Redis están fluyendo. Si devuelve 0, consulte Solucionar problemas de Redis (OpenTelemetry).
Crear namespace y credenciales
Cree un namespace newrelic y almacene su clave de licencia y extremo OTLP en un Kubernetes Secret, que el recolector lee en tiempo de ejecución para que sus credenciales queden fuera de la configuración:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicDesplegar redis_exporter
Despliegue redis_exporter como un sidecar en su pod de Redis o como un despliegue separado. Este ejemplo lo despliega como un despliegue independiente con un Service para que el recolector lo recopile.
Crear redis-exporter.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: redis-exporter namespace: default # Update with your Redis namespacespec: replicas: 1 selector: matchLabels: app: redis-exporter template: metadata: labels: app: redis-exporter spec: containers: - name: redis-exporter image: oliver006/redis_exporter:latest env: - name: REDIS_ADDR value: "redis://redis:6379" # Update with your Redis service name:port # Uncomment if using Redis authentication: # - name: REDIS_PASSWORD # valueFrom: # secretKeyRef: # name: redis-credentials # key: password ports: - containerPort: 9121 name: metrics livenessProbe: httpGet: path: /health port: 9121 initialDelaySeconds: 5 readinessProbe: httpGet: path: /health port: 9121 initialDelaySeconds: 5---apiVersion: v1kind: Servicemetadata: name: redis-exporter namespace: default # Update with your Redis namespacespec: selector: app: redis-exporter ports: - port: 9121 targetPort: 9121 name: metrics$kubectl apply -f redis-exporter.yamlVerifique que el exportador se esté ejecutando:
$kubectl port-forward svc/redis-exporter 9121:9121 &$curl -s http://localhost:9121/metrics | grep redis_upConfigurar el recolector
Este ConfigMap extrae métricas de redis_exporter y las envía a New Relic. Se encarga de estos trabajos principales:
Extraer el servicio
redis_exportera través del receptorprometheusRenombre las métricas de Prometheus a los nombres de métricas de Redis de New Relic
Dé forma a los datos — reduzca la cardinalidad, convierta los contadores en deltas y establezca la identidad de la entidad
Exporte las métricas procesadas a New Relic a través de OTLP
Crear
otel-collector-config.yaml:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"receivers:prometheus:config:scrape_configs:- job_name: 'redis'scrape_interval: 10sstatic_configs:- targets: ['redis-exporter.default.svc.cluster.local:9121'] # Update with your exporter service FQDNmetric_relabel_configs:- source_labels: [__name__]regex: '(go_|process_|promhttp_|redis_exporter_).*'action: dropprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/redis_identity:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertmetricstransform:transforms:- include: redis_uptime_in_secondsaction: updatenew_name: redis.uptime- include: redis_connected_clientsaction: updatenew_name: redis.clients.connected- include: redis_blocked_clientsaction: updatenew_name: redis.clients.blocked- include: redis_memory_used_bytesaction: updatenew_name: redis.memory.used- include: redis_memory_max_bytesaction: updatenew_name: redis.maxmemory- include: redis_mem_fragmentation_ratioaction: updatenew_name: redis.memory.fragmentation_ratio- include: redis_memory_used_rss_bytesaction: updatenew_name: redis.memory.rss- include: redis_memory_used_peak_bytesaction: updatenew_name: redis.memory.peak- include: redis_memory_used_lua_bytesaction: updatenew_name: redis.memory.lua- include: redis_connections_received_totalaction: updatenew_name: redis.connections.received- include: redis_rejected_connections_totalaction: updatenew_name: redis.connections.rejected- include: redis_commands_processed_totalaction: updatenew_name: redis.commands.processed- include: redis_keyspace_hits_totalaction: updatenew_name: redis.keyspace.hits- include: redis_keyspace_misses_totalaction: updatenew_name: redis.keyspace.misses- include: redis_evicted_keys_totalaction: updatenew_name: redis.keys.evicted- include: redis_expired_keys_totalaction: updatenew_name: redis.keys.expired- include: redis_net_input_bytes_totalaction: updatenew_name: redis.net.input- include: redis_net_output_bytes_totalaction: updatenew_name: redis.net.output- include: redis_connected_slavesaction: updatenew_name: redis.slaves.connected- include: redis_db_keysaction: updatenew_name: redis.db.keys- include: redis_db_keys_expiringaction: updatenew_name: redis.db.expires- include: redis_rdb_changes_since_last_saveaction: updatenew_name: redis.rdb.changes_since_last_save- include: redis_db_avg_ttl_secondsaction: updatenew_name: redis.db.avg_ttl- include: redis_latest_fork_secondsaction: updatenew_name: redis.latest_fork- include: redis_master_repl_offsetaction: updatenew_name: redis.replication.offset- include: redis_repl_backlog_first_byte_offsetaction: updatenew_name: redis.replication.backlog_first_byte_offset- include: redis_commands_totalaction: updatenew_name: redis.cmd.calls- include: redis_commands_duration_seconds_totalaction: updatenew_name: redis.cmd.usec- include: redis_cpu_sys_seconds_totalaction: updatenew_name: redis.cpu.timeoperations:- action: add_labelnew_label: statenew_value: sys- include: redis_cpu_user_seconds_totalaction: updatenew_name: redis.cpu.timeoperations:- action: add_labelnew_label: statenew_value: usercumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check]pipelines:metrics/redis:receivers: [prometheus]processors: [memory_limiter, resource/redis_identity, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlQué hace esta configuración
Cada componente en la canalización tiene un trabajo específico:
Componente Descripción health_checkExpone un extremo de estado en 0.0.0.0:13133para que pueda confirmar que el recolector se está ejecutando.prometheusreceptorExtrae el servicio redis_exporter(por defectoredis-exporter.default.svc.cluster.local:9121) cada 10 segundos y descarta las métricasgo_*,process_*,promhttp_*yredis_exporter_*propias del exportador.memory_limiterLimita el uso de memoria del recolector (límite flexible de 256 MiB, pico de 64 MiB) para proteger el pod. resource/redis_identityEstablece k8s.cluster.nameyredis.instance.id, la identidad estable para su entidad de Redis. Es necesario aquí porque el receptor de Prometheus no proporcionaserver.addressniserver.port.attributes/entity_tagsMarca instrumentation.provider: opentelemetryen cada métrica para que pueda limitar las consultas a la ruta de OpenTelemetry.metricstransformRenombra las métricas de Prometheus del exportador (por ejemplo, redis_uptime_in_seconds) a los nombres de Redis de New Relic (redis.uptime) y agrega la etiquetastatea las métricas de CPU.cumulativetodeltaConvierte los contadores acumulativos — comandos, aciertos de keyspace, desalojos, etc. — en valores delta para que New Relic grafique las tasas correctamente. filter/cardinalityDescarta los puntos de datos de alta cardinalidad (estados de CPU distintos de userysys, y métricas por comando para comandos poco comunes) para controlar el costo de ingesta.transform/metadata_nullifyBorra las descripciones y unidades de las métricas para reducir el tamaño de la carga. batchAgrupa los puntos de datos antes de la exportación (2048 por lote, hasta 4096) y los vacía al menos cada 10 segundos para reducir la sobrecarga de la red. otlp_httpExporta las métricas procesadas a New Relic a través de OTLP con compresión gzip, autenticadas con su clave de licencia.
Opcional: habilitar el monitoreo de Redis Cluster
Si su Redis se está ejecutando en modo Cluster, inicie redis_exporter con la bandera --is-cluster para recopilar automáticamente las métricas de estado del clúster de todos los nodos:
$redis_exporter --redis.addr=redis://localhost:7000 --is-clusterLa configuración del receptor de Prometheus anterior ya cambia el nombre de las métricas del clúster (por ejemplo, redis_cluster_state → redis.cluster.state). Para crear una entidad de clúster separada en New Relic, agregue un atributo de recurso redis.cluster.name a una canalización separada que NO incluya redis.instance.id:
resource/cluster: attributes: - key: redis.cluster.name value: "my-redis-cluster" # Update with your cluster name action: upsertAgregue una canalización de clúster a su sección de servicio:
metrics/cluster: receivers: [prometheus] processors: [memory_limiter, resource/cluster, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]Importante
La entidad de clúster requiere que redis.cluster.name esté presente Y que redis.instance.id esté ausente. Si ambos se establecen en las mismas métricas, solo se creará la entidad de instancia. Use canalizaciones separadas para las métricas de instancia y de clúster.
Opcional: recopilar logs de Redis
Más allá de las métricas, el recolector puede reenviar los logs de Redis a New Relic para que pueda correlacionar los logs de eventos —reinicios, eventos de persistencia o errores— con picos de métricas en la misma entidad. Para recolectarlas, agregue el receptor file_log a su ConfigMap y monte /var/log/pods en el despliegue.
Agregue a la sección receivers en su ConfigMap:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisAgregue un procesador resource/redis_logs:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Must match the value in resource/redis_identity action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertAgregue una canalización de logs a la sección de servicio:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Agregue el montaje de volumen /var/log/pods a su despliegue (consulte el paso de desplegar a continuación).
Desplegar el recolector
Crear otel-collector-deployment.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: otel-collector-redis namespace: newrelicspec: replicas: 1 selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: containers: - name: otel-collector image: otel/opentelemetry-collector-contrib:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-deployment.yamlSugerencia
Para usar el recolector NRDOT en su lugar, reemplace la imagen con newrelic/nrdot-collector:latest.
Verificar
Confirme que el pod del recolector se esté ejecutando:
$kubectl get pods -n newrelic -l app=otel-collector-redisEl pod debería mostrar Running con todos los contenedores listos. Si es CrashLoopBackOff o Error, verifique sus registros con kubectl logs -n newrelic -l app=otel-collector-redis — las causas más comunes son errores en el YAML del ConfigMap o un servicio redis_exporter inalcanzable.
Luego confirme que sus métricas están llegando a New Relic. Espere aproximadamente un minuto después de que se inicie el pod, luego ejecute esta consulta en el generador de consultas:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoUn recuento distinto de cero confirma que las métricas de Redis están fluyendo. Si devuelve 0, consulte Solucionar problemas de Redis (OpenTelemetry).
Sugerencia
Correlacione APM con Redis: para conectar su aplicación APM y la instancia de Redis en los mapas de servicio, incluya db.system="redis" y redis.instance.id como atributos de recursos en sus métricas de APM. El valor redis.instance.id debe coincidir con lo que configuró en el recolector. Esto permite la visibilidad entre servicios y una resolución de problemas más rápida dentro de New Relic.
Próximos pasos
- Instalación en el host: monitoree Redis en máquinas virtuales (VM)/bare metal
- Instalación de Docker: desplegar con Docker Compose
- Ver sus datos: explore los dashboard y las alertas
- Referencia de métricas: todas las métricas disponibles
- Resolución de problemas: problemas comunes de K8s