OpenTelemetry Collector 高可用部署:Kubernetes 集群零丢数据实战
【免费下载链接】opentelemetry-collectorOpenTelemetry Collector项目地址: https://gitcode.com/GitHub_Trending/op/opentelemetry-collector
凌晨两点,你被电话叫醒:一台节点宕机,跑在它上面的 OpenTelemetry Collector 单 Pod 跟着消失,两个小时 1000 多万条 span 全丢。你翻了 40 分钟日志才确认——不是后端问题,是采集层单点挂了。这类事故根因基本一致:OpenTelemetry Collector 高可用部署没做。这篇带你把 Kubernetes 集群里的采集层,从"祈祷不挂"改成"自动恢复"。
核心方案:把单点 Collector 改成弹性采集层
选对部署模式
采集层拆成两层:节点上的 Agent 和平面上的 Collector。数据流如下:
Agent 贴着节点收数据,负责就近接入与批处理;Collector 跑在控制平面,负责聚合与高可用输出。因为节点数稳定,Agent 用 DaemonSet 每节点一份;因为吞吐波动大,Collector 用 Deployment + HPA 弹性伸缩,坏副本被 Service 自动摘除,链路不断。
| 模式 | 形态 | 适合 |
|---|---|---|
| Agent | DaemonSet,每节点一份 | 节点采集、就近批处理 |
| Collector | Deployment + HPA | 跨节点聚合、弹性输出 |
资源只动这两处:Agent 节点上跑,给小 request 防抢占,GOMEMLIMIT压在 limit 的 80%,让 Go 触发 GC 而不是被 OOM Kill;Collector 是聚合层,replicas生产至少 3,副本坏了 Service 继续把流量分给活着的。
# otel-agent(DaemonSet):节点数固定,每节点一份 resources: limits: { cpu: 500m, memory: 500Mi } requests: { cpu: 100m, memory: 100Mi } env: - name: GOMEMLIMIT value: 400MiB # ← limits 的 80%,触发 GC 而非 OOM # otel-collector(Deployment):聚合层,生产建议 3 副本 replicas: 3 minReadySeconds: 5 resources: limits: { cpu: 1, memory: 2Gi } requests: { cpu: 200m, memory: 400Mi } env: - name: GOMEMLIMIT value: 1600MiB # ← 同为 limits 的 80%配好关键参数
配置用"base + overlay"分层:base 是所有环境共用的默认值,overlay 按环境只写差异,CI 阶段合并成一份最终配置。因为这样改生产只动 overlay,不会误伤其他环境,diff 也只看得到真正变化。下面两段是两个源文件,构建时合并,不是同一份 YAML。
processors: # ← base 共用默认 memory_limiter: { limit_mib: 1500 } batch: { send_batch_size: 8192 } processors: # ← overlay/prod 只覆盖差异 memory_limiter: { limit_mib: 3000 } # ← 生产内存翻倍 batch: { send_batch_size: 16384 }memory_limiter必须放在 pipeline 第一个 processor,这样内存吃紧时能立刻给上游 receiver 回压;batch放在它后面,先背压再攒批,避免把内存打满。
设好扩缩容规则
扩容怕抖动误判、缩容怕误杀,所以scaleUp只等 60s 快速接住流量,scaleDown等 300s 确认低谷再缩,避免副本反复横跳。CPU 目标留 30% 余量,因为 span 突发来得快,余量不够就 OOM。
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: otel-collector spec: scaleTargetRef: { kind: Deployment, name: otel-collector } minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: { type: Utilization, averageUtilization: 70 } behavior: scaleUp: { stabilizationWindowSeconds: 60 } scaleDown: { stabilizationWindowSeconds: 300 }生产落地:数据不丢、连接不断、故障可发现
数据不丢:先落盘,再重试
后端抖动或 Collector 重启时,数据不能直接丢。因为内存队列掉电即失,所以用file_storage把待发请求落盘,重启后从磁盘续传;再配sending_queue给抖动留缓冲,retry_on_failure设重试窗口,超 300s 才放弃。
extensions: file_storage: directory: /var/lib/otelcol # ← 崩溃重启后从磁盘续传 exporters: otlp: endpoint: backend:4317 sending_queue: { enabled: true, queue_size: 100000 } # ← 抖动时先落盘不丢 retry_on_failure: { enabled: true, max_elapsed_time: 300s }连接不断:TLS 加密 + 最小权限 🔒
链路加密和访问控制要一起上。OTLP 端点默认走明文,因为生产里 span 含请求参数等敏感字段,所以强制 TLS、禁用insecure;再用 NetworkPolicy 把入口锁到只允许 Agent 进来,出口只允许写后端,任何多余 Pod 都碰不到 4317。证书用 cert-manager 托管,配一个 24h 短证书 + 6h 提前续期即可,不用手工轮转。
# OTLP 端点 TLS:禁明文 exporters: otlp: endpoint: backend:4317 tls: ca_file: /secrets/ca.pem min_version: TLS1.2 --- # NetworkPolicy:最小权限,只放 agent 进、只写后端 kind: NetworkPolicy spec: podSelector: { matchLabels: { component: otel-collector } } ingress: - from: [ { podSelector: { matchLabels: { component: otel-agent } } } ] ports: [ { port: 4317 } ]故障可发现:盯住这 5 个指标
Collector 自带 8888 端点暴露otelcol_前缀指标,Prometheus 抓它即可。下面 5 个最该设告警:
| 指标 | 告警阈值 |
|---|---|
| otelcol_receiver_refused_spans | 1 分钟 > 100 |
| otelcol_exporter_send_failed_spans | 1 分钟 > 100 |
| otelcol_exporter_queue_size | 持续 > 80% capacity |
| otelcol_receiver_accepted_spans | 5 分钟骤降 > 50% |
| process_resident_memory_bytes | > 容器 limits 的 80% |
灾难恢复:5 步把链路拉回来
整节点损坏、配置被改坏时,按这 5 步拉回:
- 拉取备份 PVC(含 otel-config 与 file_storage 目录)
- 用备份覆盖坏掉的 ConfigMap
- 滚动重启 Collector Deployment
- 验证
/ready探针与 8888 指标端点恢复 - 确认 file_storage 数据补推、队列水位清零
调优速查:改对 5 个参数 ⚡
参数只动这 5 个,其余保持默认:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| memory_limiter.limit_mib | 容器内存 80% | 硬限,触发拒绝 + GC |
| batch.send_batch_size | 8192 | 批触发阈值,压缩并降连接数 |
| sending_queue.queue_size | 100000 | 后端抖动时的落盘缓冲 |
| grpc.max_recv_msg_size_mib | 16 | 防超大 payload 撑爆内存 |
| HPA.averageUtilization | 70 | CPU 目标,留 30% 余量抗突发 |
调优前后对比:吞吐量5k → 25k spans/s(×5),P99 延迟120ms → 45ms(-62%),内存峰值1.2GiB → 800MiB(-33%)。因为batch攒批压低了连接次数、memory_limiter卡住了 OOM 上限、HPA 吃掉了流量尖峰,三个指标一起改善。
单点变集群,数据链路从"祈祷不挂"变成"自动恢复"。想核对指标语义,看 内部遥测文档。如果你的集群还在跑单 Pod Collector,现在就可以从 DaemonSet Agent 开始拆。
【免费下载链接】opentelemetry-collectorOpenTelemetry Collector项目地址: https://gitcode.com/GitHub_Trending/op/opentelemetry-collector
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考