• /
  • EnglishEspañolFrançais日本語한국어Português
  • 로그인지금 시작하기

Install and configure Linkerd monitoring: NRDOT with Helm

|View as Markdown (English)

This page installs the NRDOT Collector using Helm, configures it to scrape Linkerd proxy and control plane metrics, and verifies that data is flowing to New Relic. Expect this to take about 15 minutes.

Compatibility and requirements

Supported

  • Kubernetes cluster (EKS, GKE, AKS, or self-managed) with kubectl configured against it
  • Linkerd installed and healthy (linkerd check passes)
  • Helm-managed cluster configuration

You need

  • A New Relic ingest license key

  • The base Kubernetes OpenTelemetry Helm installation completed

  • Network connectivity to New Relic OTLP endpoints

  • Injection enabled on the namespaces you want to observe. If it isn't, annotate and restart them:

    bash
    $
    kubectl annotate namespace <YOUR_NAMESPACE> linkerd.io/inject=enabled
    $
    kubectl rollout restart deployment -n <YOUR_NAMESPACE>

팁

The NRDOT Helm chart bundles kube-state-metrics and enables it by default, so your Kubernetes workload entities are already correlated with Linkerd metrics. No extra setup needed.

Install

  1. Set your cluster name in your values.yaml.

    deployment:
    envs:
    - name: OTEL_RESOURCE_ATTRIBUTES
    value: "k8s.cluster.name=<YOUR_CLUSTER_NAME>"
  2. Add the Linkerd scrape config and processors to deployment.configMap.extraConfig in your values.yaml.

    receivers:
    prometheus:
    config:
    scrape_configs:
    - job_name: 'linkerd-controller'
    kubernetes_sd_configs:
    - role: pod
    namespaces: { names: ['linkerd', 'linkerd-viz'] }
    relabel_configs:
    - { source_labels: [__meta_kubernetes_pod_container_port_name], action: keep, regex: admin-http }
    - { source_labels: [__meta_kubernetes_pod_container_name], target_label: component }
    - { source_labels: [__meta_kubernetes_namespace], target_label: namespace }
    - { source_labels: [__meta_kubernetes_pod_name], target_label: pod }
    - job_name: 'linkerd-proxy'
    kubernetes_sd_configs: [{ role: pod }]
    relabel_configs:
    - { source_labels: [__meta_kubernetes_pod_container_name, __meta_kubernetes_pod_container_port_name, __meta_kubernetes_pod_label_linkerd_io_control_plane_ns], action: keep, regex: ^linkerd-proxy;linkerd-admin;linkerd$$ }
    - { source_labels: [__meta_kubernetes_namespace], target_label: namespace }
    - { source_labels: [__meta_kubernetes_pod_name], target_label: pod }
    - { source_labels: [__meta_kubernetes_pod_label_linkerd_io_control_plane_ns], target_label: linkerd_control_plane_ns }
    - { source_labels: [__meta_kubernetes_pod_label_linkerd_io_control_plane_component], target_label: linkerd_control_plane_component }
    processors:
    resource/strip_service:
    attributes:
    - { key: service.name, action: delete }
    - { key: service.instance.id, action: delete }
    transform/k8s:
    metric_statements:
    - context: datapoint
    statements:
    - set(attributes["k8s.namespace.name"], attributes["namespace"]) where attributes["namespace"] != nil
    - set(attributes["k8s.pod.name"], attributes["pod"]) where attributes["pod"] != nil
    - delete_key(attributes, "instance")
    transform/deployment:
    metric_statements:
    - context: datapoint
    statements:
    - set(attributes["k8s.deployment.name"], attributes["k8s.pod.name"]) where attributes["k8s.deployment.name"] == nil and attributes["k8s.pod.name"] != nil
    - replace_pattern(attributes["k8s.deployment.name"], "-[a-z0-9]+-[a-z0-9]+$", "") where attributes["k8s.deployment.name"] == attributes["k8s.pod.name"]
    transform/metadata_nullify:
    metric_statements:
    - context: metric
    statements:
    - set(description, "")
    - set(unit, "")
    filter/drop_unused:
    error_mode: ignore
    metrics:
    metric:
    - 'name == "rustls_info" or name == "proxy_build_info"'
    - 'name == "scrape_series_added"'
    - 'IsMatch(name, "stack_(poll|create|drop)_total") or name == "stack_poll_total_ms"'
    - 'IsMatch(name, "tokio_rt_.*")'
    - 'IsMatch(name, "(inbound|outbound)_http_.*_frame_size_bytes")'
    - 'IsMatch(name, "(inbound|outbound)_tcp_detect_http_duration_seconds")'
    - 'IsMatch(name, "outbound_tcp_balancer_queue_.*")'
    - 'name == "scrape_duration_seconds" or name == "scrape_samples_scraped" or name == "scrape_samples_post_metric_relabeling"'
    pipelines:
    metrics/linkerd:
    receivers: [prometheus]
    processors: [memory_limiter, resource/strip_service, transform/k8s, transform/deployment, transform/metadata_nullify, filter/drop_unused, resource/newrelic, batch]
    exporters: [otlp_http/newrelic]

    pipelines: must be defined at the root of extraConfig, not nested under service:. The Helm chart template maps extraConfig.pipelines into service.pipelines.

Configure

  1. Update the values.yaml file as per the following table:

    ParameterDescription
    OTEL_RESOURCE_ATTRIBUTESSet k8s.cluster.name to your Kubernetes cluster name for identification in New Relic
    filter/drop_unusedDrops low-value Linkerd proxy metrics by default. Remove entries from this list to re-enable them
  2. Apply the updated values to your running Helm release.

    bash
    $
    helm upgrade nr-k8s-otel-collector newrelic/nr-k8s-otel-collector \
    >
    --namespace newrelic --reuse-values -f values.yaml

Find your data

  1. Go to one.newrelic.com > All capabilities > All entities.
  2. Search for your cluster name.
  3. Select your Linkerd entity to open the built-in dashboard.

The built-in dashboard covers request rate, latency p50/p95/p99, success rate, TCP connections, mTLS certificate status, control plane health, and meshed pod inventory. For detailed information, refer to Find Linkerd data documentation.

Linkerd distributed tracing with OpenTelemetry

Enable proxy trace export and instrument your application pods to correlate mesh spans with APM traces.

Collect Linkerd proxy logs

Optionally collect linkerd-proxy sidecar container logs.

Metrics reference

Full list of Linkerd metrics and resource attributes collected by the OTel Collector.

Copyright © 2026 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.