OpenTelemetry OpenTelemetry

Modèles de déploiement du Collector : sans Collector, agent et gateway

Choisissez une topologie et configurez le passage de relais agent-vers-gateway, y compris les métadonnées Kubernetes.

12 min Intermédiaire

Le Collector est un binaire unique, mais vous pouvez l’exécuter sous plusieurs formes. Le choix dépend du nombre de services, de la quantité de traitement nécessaire et de qui possède l’infrastructure. Ce guide décrit les modèles et montre la configuration du plus courant : des agents au niveau des nœuds qui transmettent à une gateway centrale.

Les modèles

Sans Collector. Les applications exportent l’OTLP directement vers un backend. C’est la configuration la plus simple, sans rien de plus à exécuter, et elle convient pour un prototype. Les inconvénients : chaque application a besoin de l’adresse et des identifiants du backend, changer de destination oblige à redéployer les applications, et il n’y a aucun endroit central pour filtrer, expurger ou échantillonner.

Agent. Un Collector s’exécute à côté de la charge de travail : en sidecar, ou un par nœud (un DaemonSet sur Kubernetes). Les applications envoient vers localhost ou vers le nœud, de sorte que l’export est rapide et que le chemin réseau de l’application est court. Les agents conviennent aux métriques d’hôte et de nœud, à la collecte de logs depuis des fichiers locaux, et à l’enrichissement des données avec des métadonnées locales. L’inconvénient est le grand nombre d’instances à configurer et à mettre à niveau.

Gateway. Un ou plusieurs Collectors s’exécutent comme un service central vers lequel les applications ou les agents envoient leurs données. Une gateway est l’endroit pour le travail lourd ou global : tail sampling, routage vers plusieurs backends, limitation de débit, et conservation des identifiants des backends. C’est un service que vous pouvez mettre à l’échelle horizontalement derrière un répartiteur de charge.

Agent plus gateway. Le modèle de production courant : les agents font la collecte locale et un enrichissement léger, et transmettent en OTLP à la gateway, qui effectue le traitement central et exporte vers les backends. Cela garde la configuration des applications triviale (envoyer à l’agent du nœud), garde les identifiants des backends en un seul endroit, et donne à chaque couche une seule mission.

App ─OTLP─▶ Agent (par nœud) ─OTLP─▶ Gateway (Deployment) ─▶ Backends
                │ métriques d'hôte, logs,        │ tail sampling, routage,
                │ métadonnées k8s                │ identifiants, retries

La configuration de l’agent

Un agent garde un traitement minimal et transmet tout à la gateway :

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
  hostmetrics:
    collection_interval: 30s
    scrapers:
      cpu:
      memory:
      filesystem:
      network:

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 75
    spike_limit_percentage: 15
  k8s_attributes:
    passthrough: true     # enregistre seulement l'IP du pod ; la gateway recherche le reste
  batch:

exporters:
  otlp/gateway:
    endpoint: otel-gateway.observability.svc.cluster.local:4317
    tls:
      insecure: true      # utilisez un vrai TLS entre les couches en production
    sending_queue:
      enabled: true
      queue_size: 2000
    retry_on_failure:
      enabled: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlp/gateway]
    metrics:
      receivers: [otlp, hostmetrics]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlp/gateway]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlp/gateway]

passthrough: true est la clé de la conception à deux couches. L’agent ajoute seulement l’IP du pod à chaque resource, sans appeler l’API Kubernetes. La gateway ne peut pas voir d’où provient la télémétrie une fois qu’elle arrive d’un agent ; elle utilise donc cette IP pour enrichir.

La configuration de la gateway

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20
  k8s_attributes:
    auth_type: serviceAccount
    passthrough: false
    extract:
      metadata:
        - k8s.namespace.name
        - k8s.pod.name
        - k8s.deployment.name
        - k8s.node.name
    pod_association:
      - sources:
          - from: resource_attribute
            name: k8s.pod.ip
      - sources:
          - from: connection
  batch:

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true
  otlphttp/prometheus:
    endpoint: http://prometheus:9090/api/v1/otlp
  otlphttp/loki:
    endpoint: http://loki:3100/otlp

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlphttp/prometheus]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, k8s_attributes, batch]
      exporters: [otlphttp/loki]

La gateway lit l’IP du pod jointe par l’agent, interroge l’API Kubernetes pour obtenir les métadonnées de ce pod, et ajoute les noms du namespace, du pod et du deployment. Les endpoints des backends diffèrent selon les produits ; confirmez donc les chemins OTLP exacts dans la documentation de votre backend (les guides Grafana de cette bibliothèque couvrent la stack Grafana).

Permissions Kubernetes pour k8s_attributes

Le processor lit les métadonnées des pods ; son service account a donc besoin d’un accès en lecture :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: otel-k8s-attributes
rules:
  - apiGroups: [""]
    resources: ["pods", "namespaces", "nodes"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["apps"]
    resources: ["replicasets", "deployments", "statefulsets", "daemonsets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["batch"]
    resources: ["jobs", "cronjobs"]
    verbs: ["get", "list", "watch"]

Liez-le au service account qui exécute le processor. Le preset kubernetesAttributes du chart Helm crée pour vous le RBAC nécessaire. Lorsque les agents s’exécutent en DaemonSet et font eux-mêmes leurs recherches au lieu de transmettre en passthrough, définissez filter.node_from_env_var sur une variable portant le nom du nœud (depuis la downward API), afin que chaque agent ne surveille que les pods de son propre nœud, ce qui maintient une faible charge sur l’API dans les gros clusters.

Choisir un modèle

SituationÀ utiliser
Prototype, un ou deux servicesSans Collector, ou une gateway
Besoin de métriques de nœud ou de fichiers de logsAgent en DaemonSet
Plusieurs équipes, politique centrale, tail sampling, identifiants des backends en un seul endroitAgent plus gateway
Isolation stricte par équipeUne gateway par équipe, éventuellement une gateway de plateforme partagée derrière elles

Notes opérationnelles

  • Exécutez au moins deux réplicas de gateway derrière un Service, et donnez aux agents une file d’attente et des retries afin qu’un redémarrage de la gateway ne fasse pas perdre de données.
  • Utilisez TLS entre les agents et la gateway en dehors d’un réseau de confiance, et authentifiez les émetteurs auprès de la gateway lorsqu’elle est exposée.
  • Épinglez la même version du Collector sur toutes les couches lorsque c’est possible, et mettez à niveau la gateway en premier.
  • Si vous ajoutez du tail sampling, ajoutez entre les agents et l’échantillonneur la couche de répartition de charge décrite dans le guide sur l’échantillonnage.

Guides populaires