OpenTelemetry OpenTelemetry

Collector 部署模式:无 Collector、Agent 与 Gateway

选择一种拓扑,并配置从 agent 到 gateway 的交接,包括 Kubernetes 元数据。

12 min 中级

Collector 是单个二进制文件,但你可以以多种形态运行它。哪一种适合取决于你有多少服务、需要多少处理,以及谁拥有基础设施。本指南介绍这些模式,并展示最常见模式的配置:节点级的 agent 转发到中心 gateway。

各种模式

无 Collector。 应用直接将 OTLP 导出到后端。这是最简单的配置,没有任何额外需要运行的东西,适合原型。缺点:每个应用都需要后端地址和凭据,更换目的地意味着重新部署应用,而且没有任何中心位置可以进行过滤、脱敏或采样。

Agent。 Collector 与工作负载一起运行:作为 sidecar,或每个节点一个(Kubernetes 上的 DaemonSet)。应用向 localhost 或节点发送,所以导出很快,应用的网络路径很短。Agent 适合主机和节点指标、从本地文件收集日志,以及用本地元数据丰富数据。缺点是要配置和升级的实例很多。

Gateway。 一个或多个 Collector 作为中心服务运行,应用或 agent 向其发送数据。gateway 是做繁重或全局工作的地方:尾部采样、路由到多个后端、限流,以及持有后端的凭据。它是一个可以在负载均衡器后面水平扩展的服务。

Agent 加 gateway。 常见的生产设计:agent 做本地收集和轻量的丰富,并通过 OTLP 转发给 gateway,gateway 做中心处理并导出到后端。它让应用配置保持简单(发送到节点 agent),把后端凭据集中在一处,并让每一层只做一件事。

App ─OTLP─▶ Agent (per node) ─OTLP─▶ Gateway (Deployment) ─▶ Backends
                │ host metrics, logs,            │ tail sampling, routing,
                │ k8s metadata                   │ credentials, retries

Agent 的配置

agent 让处理保持最小,并将一切转发给 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     # only record the pod IP; the gateway looks up the rest
  batch:

exporters:
  otlp/gateway:
    endpoint: otel-gateway.observability.svc.cluster.local:4317
    tls:
      insecure: true      # use real TLS between layers in 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 是两层设计的关键。agent 只是把 pod IP 添加到每个资源上,而不调用 Kubernetes API。一旦遥测数据从 agent 到达,gateway 就无法看出它来自哪里,所以它使用该 IP 来丰富数据。

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]

gateway 读取 agent 附加的 pod IP,向 Kubernetes API 询问该 pod 的元数据,并添加命名空间、pod 和 deployment 的名称。后端端点因产品而异,所以请在你的后端文档中确认确切的 OTLP 路径(本资料库中的 Grafana 指南涵盖了 Grafana 栈)。

k8s_attributes 的 Kubernetes 权限

该 processor 读取 pod 元数据,所以它的 service account 需要读权限:

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"]

把它绑定到运行该 processor 的 service account。Helm chart 的 kubernetesAttributes preset 会为你创建所需的 RBAC。当 agent 作为 DaemonSet 运行并自己做查询而不是 passthrough 时,请将 filter.node_from_env_var 设置为一个携带节点名称的变量(来自 downward API),这样每个 agent 只监视自己节点上的 pod,这在大型集群上能保持较低的 API 负载。

选择模式

情形使用
原型,一两个服务无 Collector,或一个 gateway
需要节点指标或日志文件作为 DaemonSet 的 agent
多个团队、中心策略、尾部采样、后端凭据集中在一处Agent 加 gateway
每个团队严格隔离每个团队一个 gateway,可选地在它们后面再有一个共享的平台 gateway

运维说明

  • 在 Service 后面至少运行两个 gateway 副本,并给 agent 一个队列和重试,这样 gateway 重启不会丢失数据。
  • 在不可信网络之外,在 agent 和 gateway 之间使用 TLS,并在暴露 gateway 的地方对发送方进行认证。
  • 尽可能在各层固定相同的 Collector 版本,并先升级 gateway。
  • 如果你添加尾部采样,请在 agent 和采样器之间添加采样指南中的负载均衡层。

热门指南