Esta página instala o OpenTelemetry Collector Contrib da comunidade usando manifestos do Kubernetes, configura-o para coletar métricas do proxy e do plano de controle do Linkerd e verifica se os dados estão fluindo para a New Relic. Espera-se que isso leve cerca de 15 minutos.
Compatibilidade e requisitos
Suportado
- Cluster do Kubernetes (EKS, GKE, AKS ou autogerenciado) com
kubectlconfigurado nele - Linkerd instalado e íntegro (
linkerd checkaprovado) - Configuração de cluster gerenciada por manifesto (sem Helm)
Você precisa
Uma chave de licença de ingestãoda New Relic
Conectividade de rede para os endpoints OTLP da New Relic
Injeção habilitada nos namespaces que você deseja observar. Se não estiver, anote e reinicie-os:
bash$kubectl annotate namespace <YOUR_NAMESPACE> linkerd.io/inject=enabled$kubectl rollout restart deployment -n <YOUR_NAMESPACE>(Opcional) kube-state-metrics em execução no seu cluster, se você quiser entidades de workload do Kubernetes correlacionadas com métricas do Linkerd. Se você já tem a integração do Kubernetes da New Relic instalada, isso já está resolvido
Instalar
- Copie o manifesto abaixo para um arquivo chamado
otel-collector.yaml.
apiVersion: v1 kind: ServiceAccount metadata: { name: my-opentelemetry-collector, namespace: newrelic } --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: { name: my-opentelemetry-collector } rules: - apiGroups: [""] resources: [pods, nodes, nodes/proxy, endpoints, services, namespaces] verbs: [get, list, watch] - apiGroups: ["apps"] resources: [replicasets, deployments, daemonsets, statefulsets] verbs: [get, list, watch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: { name: my-opentelemetry-collector } roleRef: { apiGroup: rbac.authorization.k8s.io, kind: ClusterRole, name: my-opentelemetry-collector } subjects: - { kind: ServiceAccount, name: my-opentelemetry-collector, namespace: newrelic } --- apiVersion: v1 kind: ConfigMap metadata: { name: my-opentelemetry-collector-config, namespace: newrelic } data: config: | 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: memory_limiter: check_interval: 1s limit_percentage: <MEMORY_LIMIT_PERCENTAGE> spike_limit_percentage: <MEMORY_SPIKE_LIMIT_PERCENTAGE> resource/strip_service: attributes: - { key: service.name, action: delete } - { key: service.instance.id, action: delete } resource/cluster: attributes: - key: k8s.cluster.name value: "<YOUR_CLUSTER_NAME>" action: insert 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, "") batch: {}
exporters: otlp_http/newrelic: endpoint: "https://otlp.nr-data.net:4318" headers: api-key: "<YOUR_NR_INGEST_LICENSE_KEY>"
service: pipelines: metrics: receivers: [prometheus] processors: [memory_limiter, resource/strip_service, resource/cluster, transform/k8s, transform/deployment, transform/metadata_nullify, batch] exporters: [otlp_http/newrelic] --- apiVersion: apps/v1 kind: Deployment metadata: { name: my-opentelemetry-collector, namespace: newrelic } spec: replicas: 1 selector: { matchLabels: { app: my-opentelemetry-collector } } template: metadata: labels: { app: my-opentelemetry-collector } spec: serviceAccountName: my-opentelemetry-collector securityContext: runAsNonRoot: true runAsUser: 10001 containers: - name: opentelemetry-collector image: otel/opentelemetry-collector-contrib:0.160.0 args: ["--config=/conf/config.yaml"] securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: { drop: [ALL] } resources: limits: { cpu: <CPU_LIMIT>, memory: <MEMORY_LIMIT> } volumeMounts: - { name: config, mountPath: /conf } volumes: - name: config configMap: name: my-opentelemetry-collector-config items: - { key: config, path: config.yaml } --- apiVersion: v1 kind: Service metadata: { name: my-opentelemetry-collector, namespace: newrelic } spec: selector: { app: my-opentelemetry-collector } ports: - { name: otlp, port: 4317, targetPort: 4317, protocol: TCP, appProtocol: grpc } - { name: otlp-http, port: 4318, targetPort: 4318, protocol: TCP }Dica
Este manifesto não filtra métricas de proxy de baixo valor por padrão. Se você deseja a mesma filtragem que o NRDOT aplica, adicione um processador filter/drop_unused. Consulte a página NRDOT com Helm para obter a lista de filtros.
Configurar
Preencha os espaços reservados em
otel-collector.yamlantes de aplicar:Campo Localização O que definir resource/clusterprocessador Nome do seu cluster Kubernetes otlp_http/newrelicexportador Sua chave de licença de ingestão da New Relic memory_limiterprocessador Porcentagens de limite e pico de memória, por exemplo, 80e25resources.limitsContêiner de implantação Limites de CPU e memória para o pod do coletor Aplique o manifesto.
$kubectl apply -f otel-collector.yaml$ kubectl rollout status deployment/my-opentelemetry-collector -n newrelicEncontre seus dados
Vá para one.newrelic.com > All capabilities > All entities.
Pesquise o nome do seu cluster.
Selecione sua entidade do Linkerd para abrir o dashboard integrado.
O dashboard integrado abrange a taxa de requisições, latência p50/p95/p99, taxa de sucesso, conexões TCP, status do certificado mTLS, integridade do plano de controle e inventário de pods na malha. Para obter informações detalhadas, consulte a documentação Find Linkerd data.
Artigos relacionados
Linkerd distributed tracing com OpenTelemetry
Ative a exportação de trace de proxy e instrumente os pods do seu aplicativo para correlacionar spans de malha com traces de APM.
Colete logs do proxy do Linkerd
Adicione um segundo release do coletor para coletar os logs do sidecar
linkerd-proxy
.
Referência de métricas
Lista completa de métricas e atributos de recursos do Linkerd coletados pelo OTel Collector.