ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenTelemetry Collector K8s 高可用部署:四个决策与三条红线

OpenTelemetry Collector K8s 高可用部署:四个决策与三条红线 OpenTelemetry Collector K8s 高可用部署四个决策与三条红线【免费下载链接】opentelemetry-collectorOpenTelemetry Collector项目地址: https://gitcode.com/GitHub_Trending/op/opentelemetry-collector场景凌晨三点的 OOM 重启和一块数据空窗凌晨三点十四分告警群炸了。otel-gateway 的 Pod 当晚第七次被 OOMKilledTrace 大盘上出现了一块肉眼可见的空窗业务方开始追问。Pod 的内存限制是 2Gi但 GC 追不上晚高峰内核直接动手。排查后发现问题不在某一条配置而是一整套 OpenTelemetry Collector 高可用部署的决策没做对。本文只讲单集群节点 Agent 加中心 Gateway 的两级部署规模是几十台节点、峰值每小时百万级 span。多集群联邦、后端存储选型都不覆盖。拿到的东西很直接为什么拆两级、配置怎么写、跑起来之后盯什么。为什么拆成 Agent 和 Gateway先做部署形态决策一套 Collector 直接跑所有业务 Pod 都往里发也能跑。但有两个问题。一个是地址。每个业务 Pod 都要写死 Collector 的 Service 名扩容、迁移、换命名空间之后地址漂移排查一次要翻好几个工单。另一个是故障域。承载业务 Pod 的节点挂了或者某个副本正在重启这个窗口里的数据没人接也没有本地缓冲。拆成两级两个问题一起解。Agent 用 DaemonSet 跑每节点一个把 OTLP 端口绑在 Pod IP 上业务应用只指本地地址就行。Gateway 用 Deployment 跑负责批处理、重试和对外输出副本数和滚动更新都可以自由调度Agent 一侧完全无感。Gateway 为什么不再用 DaemonSet它的数据流不依赖特定节点放到每台节点上只是重复占资源。真要换输出后端DaemonSet 得全节点滚动Deployment 只改几个副本。两层职责分开出事时也容易定位是哪一段断的。拓扑简化成七个节点图中 Gateway 画了三个副本后端是任意 OTLP 兼容存储。箭头走 gRPC 端口 4317业务如果走 HTTP 就换成 4318。Collector Gateway最小可用部署怎么写下面这份 Deployment 解决Collector 第一次进集群的问题只保留必须对的三处。apiVersion: apps/v1 kind: Deployment metadata: name: otel-gateway namespace: observability spec: replicas: 3 minReadySeconds: 5 # 新 Pod 初始化完再切流量 template: spec: containers: - name: collector image: otel/opentelemetry-collector:0.150.0 # 固定版本 args: [--config/conf/gateway.yaml] resources: requests: {cpu: 500m, memory: 1Gi} limits: {cpu: 1, memory: 2Gi} ports: - containerPort: 4317 # OTLP gRPC - containerPort: 4318 # OTLP HTTP - containerPort: 8888 # 内部遥测minReadySeconds: 5防止 Service 把流量切给还没初始化好流水线的 Pod。8888 是 Collector 默认暴露内部指标的端口Prometheus 格式。把命名空间、资源数值、镜像版本换成你自己的就能直接 apply。跑通之后更新策略上两个数字maxSurge: 1, maxUnavailable: 0。滚动更新时旧 Pod 扛着流量等新副本就绪才下线配合 Agent 端的缓冲配置变更基本不丢数据。探针这里有个容易踩的坑。核心发行版没有独立的 HTTP 健康端点那是 contrib 发行版里的扩展组件。可靠的做法是给 4317 做 TCP 探针或者如果已经有 Prometheus直接抓 8888 的 metrics 接口返回 200 就算就绪。别对着不存在的路径写 httpGet。跑起来之后要盯的三件事数据不丢打开导出器的队列和重试不处理这条后端宕机两分钟这两分钟的数据就是永久空窗。下面这段是导出器内置的缓冲加重试是第一道防线exporters: otlp: endpoint: backend:4317 sending_queue: queue_size: 10000 # 内存中最多缓存多少条 num_consumers: 4 # 消费协程并发数 retry_on_failure: enabled: true initial_interval: 5s max_elapsed_time: 300s # 5 分钟还没成功就放弃queue_size 是内存缓冲上限retry 会一直按指数退避重试到 max_elapsed_time之后数据丢弃并计入失败指标。Agent 到 Gateway 这一跳用同一份配置单个 Gateway 副本挂了数据缓存在 Agent 侧被其他副本接管。判断标准盯otelcol_exporter_send_failed_spans。瞬时尖峰正常持续上涨不回落说明后端挂了或者队列写满了。资源不爆GOMEMLIMIT 与 Collector HPA 扩缩容配置不处理这条流量一高峰就整池 OOM或者 Agent 把业务 Pod 的资源挤掉。下面这段配置把内存红线卡在两个层面GC 层和接收层。# Deployment 的 env 段 env: - name: GOMEMLIMIT value: 1600MiB # 约为 2Gi 限制的 80% --- # Collector 配置 processors: memory_limiter: limit_mib: 1500 # 熔断阈值 spike_limit_mib: 512 # 额外允许的突发 check_interval: 5s两层是互补的。Go 运行时默认 GC 目标约为容器限制的一半Collector 往往在撞到限制之前就被内核杀了。GOMEMLIMIT 把它抬到限制的八成给 GC 留出反应时间。官方 K8s 示例正是这个比例2Gi 限制的 Pod 配 1600MiB500Mi 的 Agent 配 400MiB。memory_limiter 则在接收层做保险丝超了阈值就用 503 拒掉新数据好过整个进程被杀。实测加上这两层之后原来一天 OOM 重启几次的 2Gi Pod 在峰值期不再重启。副本数交给 HPAHorizontalPodAutoscalerK8s 里根据负载自动增减副本数的控制器apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: otel-gateway spec: scaleTargetRef: {kind: Deployment, name: otel-gateway} minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: {type: Utilization, averageUtilization: 70}CPU 目标 70% 给重试风暴留了余量。想按吞吐量扩把 metrics 换成 Pods 类型用otelcol_receiver_accepted_spans做每副本均值目标。Agent 是每节点固定的参考值 requests 100m/100Mi、limits 500m/500Mi节点上业务 Pod 多就调大 limit。判断标准8888 导出的进程内存长期贴着 limit先怀疑后端变慢、数据在积压再考虑加副本。安全不裸奔OTLP 端到端加密与 NetworkPolicy不处理这条集群里任意 Pod 都能读到 TraceGateway 到后端的流量也能被嗅探。下面这段把加密和访问控制一次配齐Gateway 到后端加密接收端口只对 Agent 开放。# Collector 的 exporter 段 exporters: otlp: endpoint: secure-backend:4317 tls: min_version: VersionTLS12 cert_file: /secrets/client.crt key_file: /secrets/client.key ca_file: /secrets/ca.crt --- # NetworkPolicy apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: gateway-ingress spec: podSelector: {matchLabels: {app: otel-gateway}} policyTypes: [Ingress] ingress: - from: - podSelector: {matchLabels: {app: otel-agent}} ports: - {protocol: TCP, port: 4317} - {protocol: TCP, port: 4318}证书从 Secret 挂载。用 cert-manager 签发时把有效期设短、提前续期Collector 会自动加载新证书不用重启。判断标准随便 exec 进一个业务 Pod尝试连 Gateway 的 4317拒绝连接才算合格。下周就要上线先做这几件事✅ 镜像标签从 latest 换成固定版本配置跑一遍校验✅ 每个 Collector Pod 加上 GOMEMLIMIT约限制的 80%和 memory_limiter✅ 导出器打开 sending_queue 加 retry_on_failuremax_elapsed_time 要盖过后端最长恢复时间Gateway 的接收端口用 NetworkPolicy 锁死只允许 Agent 访问把otelcol_exporter_send_failed_spans加进告警别只盯 CPU 和内存五条做完这条链路才敢接生产流量。完整的示例清单在仓库的 examples/k8s/otel-config.yamlAgent、Gateway、Service 和配置都在里面可以直接拿来做基线。【免费下载链接】opentelemetry-collectorOpenTelemetry Collector项目地址: https://gitcode.com/GitHub_Trending/op/opentelemetry-collector创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表