配置与部署形态 · confmap 与 agent/gateway

Collector 的配置能从文件、环境变量、HTTP、甚至内联 YAML 来——这一章读 confmap 的 provider 机制,以及那个真正影响架构的决策:Collector 该部署成 agent(每节点一个)还是 gateway(集中一层),还是两者都要。

作者 David更新于 第 41 篇(共 52 篇)

配置与部署形态 · confmap 与 agent/gateway

组件都认识了(五类、数据模型、怎么传)。这一章讲怎么把它们配起来,以及一个真正影响架构的决策:Collector 该部署在哪。

confmap:配置从哪来

看 confmap/provider/ 目录:

confmap/provider/
├── fileprovider/     file:/etc/otel/config.yaml
├── envprovider/      env:MY_CONFIG
├── httpprovider/     http://config-server/otel.yaml
├── httpsprovider/    https://...
└── yamlprovider/     yaml:{...}  (内联)

配置源被抽象成 provider,用 URI scheme 区分。这带来两个实用能力:

  • 可以从远程拉配置 —— httpprovider 让你把配置放在配置中心。改配置不用重新打镜像。
  • 可以组合多个源 —— 这是最有用的:
    otelcol --config=file:/etc/otel/base.yaml \
            --config=file:/etc/otel/override.yaml \
            --config="yaml:exporters::otlp::endpoint: ${BACKEND}"
    多个配置会被合并**(后面的覆盖前面的)。** 于是你可以做“基础配置 + 环境覆盖”的分层——和 Kustomize / Helm values 一个思路。

${VAR} 语法可以在配置里直接引用环境变量,这是最常用的:把 endpoint、token 这类环境相关的东西外置。注意 token 别写进配置文件——用 ${ENV} 或专门的 extension 处理认证。

一份完整配置长什么样

receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }
  prometheus:                    # 它能像 Prometheus 一样去抓!
    config:
      scrape_configs:
        - job_name: 'app'
          static_configs: [{ targets: ['localhost:8080'] }]

processors:
  memory_limiter:                # ← 必须放最前面(上一章讲过)
    check_interval: 1s
    limit_mib: 512
  batch:                         # ← 削峰,几乎必配
    timeout: 10s
    send_batch_size: 8192
  resource:                      # 给所有数据加统一标签
    attributes:
      - key: env
        value: prod
        action: upsert

exporters:
  prometheusremotewrite:
    endpoint: "http://mimir:9009/api/v1/push"
  otlp/tempo:
    endpoint: "tempo:4317"

extensions:
  health_check: {}               # k8s 探针用
  pprof: {}

service:
  extensions: [health_check, pprof]
  pipelines:
    metrics:
      receivers: [otlp, prometheus]
      processors: [memory_limiter, resource, batch]    # ← 顺序有意义!
      exporters: [prometheusremotewrite]
    traces:
      receivers: [otlp]
      processors: [memory_limiter, resource, batch]
      exporters: [otlp/tempo]

两个新手必踩的坑:

① service.pipelines 才是真正生效的部分。 上面 receivers:/processors: 那些段只是定义组件;没有被 service.pipelines 引用的组件,压根不会被实例化。这是“我配了但没生效”的头号原因。

② processor 的顺序 = 数据流经的顺序。 [memory_limiter, resource, batch] 意味着数据依次经过这三个。顺序错了后果很实际:

  • memory_limiter 必须第一 —— 要在数据进管道前就拦住。
  • batch 通常最后 —— 攒批应该在所有加工之后,否则你在对着一批一批的数据反复做单条加工。
  • 过滤类 processor 要早 —— 越早丢掉不要的数据,后面的处理就越省。

otlp/tempo 这种 type/name 语法是给“同一类组件的多个实例”命名的(比如两个 otlp exporter 指向不同后端)。

部署形态:agent 还是 gateway

这才是真正影响架构的决策,而且它常被忽略。

两种形态,各有各的活:

图表加载中…
Agent(每节点一个)Gateway(集中一层)
应用到它的延迟极低(本地)有网络跳
能加节点级元数据✅(k8s pod/node 信息)❌(离得远,不知道)
能做全局的事❌✅(尾采样、跨服务聚合)
资源开销× 节点数(每个都占内存)集中,可控
后端连接数多(每个 agent 一份)少(集中收敛)

关键洞见:两者解决的问题不同,所以生产环境常常两层都要**:**

  • Agent(本地) —— 应用极快地把数据吐给本地进程就返回(不用等远程后端),agent 负责加节点/pod 元数据(它知道自己在哪台机器、哪个 pod),然后转发。
  • Gateway(集中) —— 做需要全局视野的事:尾采样(必须看到一条 trace 的所有 span,而它们可能来自不同节点!)、收敛到后端的连接数、统一的重试和缓冲。

尾采样必须在 gateway 这条尤其重要——它是“为什么需要两层”最硬的技术理由:agent 只看得到本节点的 span,而一条 trace 横跨多个节点。下一部分讲采样时会展开。

发行版:core / contrib / k8s / otlp

看 distributions.yaml(真实文件):

- name: core        # 最小集,只有核心组件
- name: contrib     # 全家桶,几百个社区组件
- name: k8s         # 为 k8s 场景裁剪的
- name: otlp        # 只有 OTLP 收发,极小

为什么要分发行版?因为 contrib 里有几百个组件(每个云厂商、每个中间件都有自己的 receiver/exporter),全打进一个二进制会非常臃肿——镜像几百 MB,而你可能只用其中三个。

实战建议:生产环境用 OCB(OpenTelemetry Collector Builder)构建自己的发行版,只打包你真正用的组件。好处:

  • 镜像小 —— 从几百 MB 降到几十 MB。
  • 攻击面小 —— 不用的组件不会有 CVE 影响你。
  • 启动快、内存省。

这个“按需组装”的模式,正是五类组件 + Factory 注册那套设计带来的红利——因为核心只认接口,组件可以自由增删。

小结与下一章

confmap 把配置源抽象成 provider(file/env/http/https/yaml),能从远程拉配置、且能组合多个源做分层覆盖(基础 + 环境覆盖,和 Kustomize 一个思路),配合 ${VAR} 外置环境相关的东西。两个必踩的坑:①只有 service.pipelines 引用的组件才会被实例化(“配了没生效”的头号原因);②processor 顺序 = 数据流经顺序(memory_limiter 必须第一、batch 通常最后、过滤要早)。部署形态是真正影响架构的决策:Agent(本地、极低延迟、能加节点元数据)vs Gateway(集中、能做全局的事、收敛后端连接);生产常常两层都要,而“尾采样必须在 gateway(agent 只看得到本节点的 span,而一条 trace 横跨多节点)”是需要两层最硬的技术理由。发行版分 core/contrib/k8s/otlp——生产该用 OCB 组装自己的(镜像小、攻击面小),这是Factory 注册那套设计的红利。

最后一章:怎么扩展它。👉 自定义组件。

参考资料

  • [1] OTel Collector 源码 confmap/provider/(file/env/http/https/yaml)、distributions.yaml。
  • [2] OTel Collector 官方文档:Configuration、Deployment patterns(agent/gateway)、OCB(ocb)。
  • [3] 关联Collector 架构、背压与 memory_limiter。

本页目录