LabHub
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

把 Collector 配置文件做成完整一套

在 LabHub 中继续学习

目标

从头到尾编写一整套可用于生产环境的 Collector 配置文件。完成后,只需查看他人的 Collector 配置和 Processor 顺序,就能预测会发生什么事故。

为什么重要

Collector 配置中只要一行 YAML 有误,进程就无法启动;问题在于,大多数时候要等到在集群中看到 CrashLoopBackOff 后才会知道。更糟糕的是,某些配置能够启动,却悄无声息地出错。如果把 memory_limiter 放在后面,平时不会有问题,只有负载升高时才会因 OOM 崩溃;如果把 batch 放在 tail_sampling 前面,trace 会被随机截断,但指标不会报告任何异常。组件如果只定义却不加入 service,它虽然存在于配置文件中,却不会运行。这三种情况构成了 Collector 事故的大多数,而且只需阅读配置文件就能全部发现。

步骤

  1. 创建 /root/otca-collector/config.yaml,在 receivers.otlp.protocols 下写入 grpc.endpoint: 0.0.0.0:4317http.endpoint: 0.0.0.0:4318
  2. processors.memory_limiter 中写入 check_interval: 1slimit_mib: 1638spike_limit_mib: 328。(以容器内存限制 2Gi 为基准)
  3. processors.k8sattributes 中写入 auth_type: serviceAccount,并在 extract.metadata 中加入 k8s.namespace.namek8s.deployment.namek8s.pod.namek8s.node.name 四项。
  4. processors 中创建 attributes/redact,并在 actions 中加入三项。对 http.request.header.authorization 执行 delete,对 user.email 执行 delete,对 db.query.text 执行 hash
  5. processors.batch 中写入 timeout: 5ssend_batch_size: 8192send_batch_max_size: 16384
  6. exporters 中定义三项。otlp/tempoendpoint 使用带 4317 端口的地址,otlp/gateway 也使用带 4317 端口的地址;prometheusremotewrite 使用以 /api/v1/push 结尾的 http URL,并添加 sending_queueenabled: truenum_consumers: 10queue_size: 5000)和 retry_on_failureenabled: trueinitial_interval: 5smax_elapsed_time: 300s)。
  7. extensions 中定义 health_check.endpoint: 0.0.0.0:13133zpages.endpoint: 0.0.0.0:55679,并将两个名称都加入 service.extensions
  8. service.pipelines 中写入三条管道。traces 使用 Processor [memory_limiter, k8sattributes, attributes/redact, batch] 和 Exporter [otlp/tempo]metrics 使用 [memory_limiter, k8sattributes, batch][prometheusremotewrite]logs 使用 [memory_limiter, k8sattributes, attributes/redact, batch][otlp/gateway]。三条管道的 Receiver 都是 [otlp]

参考

OTLP Receiver 的两个端口

创建 /root/otca-collector/config.yaml,在 receivers.otlp.protocols 下写入 grpc.endpoint: 0.0.0.0:4317http.endpoint: 0.0.0.0:4318

otlp Receiver 在 protocols 下分别包含 grpc 和 http。只开放其中一项时,不向该协议发送的 SDK 会直接连接失败,而且 Collector 指标中不会留下任何痕迹。在容器内应绑定所有接口,而不是 loopback。

计算 memory_limiter 的值

processors.memory_limiter 中写入 check_interval: 1slimit_mib: 1638spike_limit_mib: 328。(以容器内存限制 2Gi 为基准)

假设容器内存限制为 2Gi。惯例是将硬限制设为其 80%,将允许的峰值设为硬限制的 20%。如果设置得高于容器限制,内核会在 Processor 介入之前先终止进程。

附加 Kubernetes 元数据

processors.k8sattributes 中写入 auth_type: serviceAccount,并在 extract.metadata 中加入 k8s.namespace.namek8s.deployment.namek8s.pod.namek8s.node.name 四项。

此 Processor 以 Pod IP 为线索,从 API 服务器查找元数据并将其附加为资源属性。因此必须指定认证方式,并在 extract 中只列出所需项目,以减少负载。

删除和哈希敏感属性

processors 中创建 attributes/redact,并在 actions 中加入三项。对 http.request.header.authorization 执行 delete,对 user.email 执行 delete,对 db.query.text 执行 hash

在 Processor 名称中加入斜杠,可以创建同一类型的第二个实例。如果完全删除,之后就无法按相同值进行分组;因此,对于查询语句等需要分组的值,应进行哈希而不是删除。

batch 触发条件与上限

processors.batch 中写入 timeout: 5ssend_batch_size: 8192send_batch_max_size: 16384

send_batch_size 是“积累到这么多就立即发送”的触发条件,并不是批次大小的上限。必须用另一个键指定上限;如果不指定,批次可能远大于预期。

三个 Exporter 及队列与重试

exporters 中定义三项。otlp/tempoendpoint 使用带 4317 端口的地址,otlp/gateway 也使用带 4317 端口的地址;prometheusremotewrite 使用以 /api/v1/push 结尾的 http URL,并添加 sending_queueenabled: truenum_consumers: 10queue_size: 5000)和 retry_on_failureenabled: trueinitial_interval: 5smax_elapsed_time: 300s)。

sending_queue 会在后端短暂变慢时保留数据,retry_on_failure 会使用指数退避重试失败操作。如果两者都关闭,后端每次波动都会直接导致数据丢失。

health_check 与 zpages

extensions 中定义 health_check.endpoint: 0.0.0.0:13133zpages.endpoint: 0.0.0.0:55679,并将两个名称都加入 service.extensions

扩展仅定义并不会运行。还必须在 service 下列出名称才能启用。health_check 是 liveness/readiness 探针访问的端点,zpages 会显示近期 trace 和管道状态。

三条管道与 Processor 顺序

service.pipelines 中写入三条管道。traces 使用 Processor [memory_limiter, k8sattributes, attributes/redact, batch] 和 Exporter [otlp/tempo]metrics 使用 [memory_limiter, k8sattributes, batch][prometheusremotewrite]logs 使用 [memory_limiter, k8sattributes, attributes/redact, batch][otlp/gateway]。三条管道的 Receiver 都是 [otlp]

列出的顺序就是处理顺序。内存保护必须放在最前面,才能向上游传播 backpressure;batch 必须放在最后,才能避免拆开后再重新组合的浪费。附加元数据的 Processor 可能创建新属性,因此删除操作应在它之后。