eBPF 排查采集缺口与控制资源¶
流量曲线下降既可能来自业务,也可能来自采集或上报链路。先确认能力、快照覆盖、丢失与发送积压,再解释业务数据;资源扩容也应对应已经确认的瓶颈。
查询入口与场景导航见 网络排障实践总览。本篇的压力和积压数字为教学示例;资源与日志体积按默认预算估算,实际用量需按业务负载测量。
场景一:map 接近满,但尚未确认丢失¶
教学示例:一个 flow_faults map 的容量为 65536,使用 60000,约 91.6%;出现 map_pressure 日志,但同窗没有对应写入失败增量。
| 观测 | 判断 |
|---|---|
| 占用超过 90% | 容量风险,应跟踪是否持续增长 |
| 写入失败没有增加 | 不能仅凭占用认定已经丢失 |
| 对应写入失败增加,且来源证据为 partial | 有明确的采集缺口,需要定位具体 map/通道 |
| 仅唤醒通知丢失,累计 map 快照仍可读取 | 不能等同于业务字节已丢失 |
默认节点指标提供 map_pressure_total/capture_loss_total,摘要中的 entity.scope=collector 与 entity.service 指出来源。少量节点启用完整指标后,可查看 map_flow_faults_entries/map_flow_faults_capacity;其他 map 使用对应名称。map 压力观测次数不是失败连接数,累计采集损失也可能包含不同通道,先读来源说明再解释影响。
先区分连接并发超过设计容量、关闭连接清理不及时、用户态扫描延迟和内存限制。只有确认容量不足且资源允许时,才调整 高级容量参数;提高 map 上限会增加内核内存需求,并不修复探针缺口或上报阻塞。修复验收应同时查看占用回落、写入失败停止增加、证据覆盖改善和业务数据对齐。
场景二:来源能力缺失或扫描不完整¶
| 教学数据 | 可以说明什么 | 不能说明什么 |
|---|---|---|
tcp_queue_snapshots_available=false |
该节点不能提供已验证的 TCP 队列快照 | 队列值缺失或零值不等于没有排队 |
dns_capture_available=false |
DNS 抓包证据不可用 | 没有 DNS 日志不等于 DNS 正常 |
候选命名空间 150,本轮样本 128,namespace_full_scan_available=false |
本轮没有覆盖全部候选来源 | 不必然表示某 22 个命名空间永远不采集 |
namespace_counter_sample_at_ns 长时间不更新 |
来源采样可能过期或停止推进 | 历史零增量不能解释当前状态 |
TCP 队列、socket errno 和监听队列优先读取验证过的 BTF;没有 BTF 时启动会通过本地 TCP socket 自检验证可选偏移。自检失败、匹配有歧义或权限不足时,对应能力标为不可用,不会把推测的结构布局当作可靠数据。无 BTF 支持仍应逐节点检查能力,不能推广为所有厂商内核都具备相同证据。
网络栈来源来自已观测连接的候选命名空间及采集器自身,每 10 秒最多轮转 128 个命名空间、每个最多 32 个接口;不是所有空闲 Pod 的完整普查。namespace_counter_sample_at_ns 是节点层来源推进线索,不能证明每个候选来源都刚采样。完整指标模式还提供逐来源时间和年龄,用于检查目标来源的新鲜度。网卡点仅在错误或丢弃增量非零时输出;没有网卡点不能证明该接口已经扫描且正常,还要核对覆盖。
connection_evidence_complete 表示当前连接采集窗口的完整性判断。它不能替代 DNS 抓包、命名空间覆盖和端到端送达判断。读取日志还要看 evidence_partial、capabilities 和样本的可用性标志。并发写入可能让快照暂缓到下一轮,而累计值继续保留;不能把暂缓直接当作永久丢失。
NAT 后端缺失或关联冲突¶
dst_nat_ip=N/A 表示当前没有可靠的后端关联,不能据此认定连接没有经过 NAT。采集器按完整 tuple、来源网络命名空间和协议关联实际 conntrack;同一 tuple 出现多个 owner 时,只暂停该 tuple 的关联,其他连接继续采集。源版本和成员数稳定后可恢复,不需要通过重启清除整个 namespace 的历史判定。
跨 Pod 与宿主机的 DNAT 需要实际报文入口和经过双向核验的 veth 关系。缺少入口、权限不足、拓扑尚未发现,或者路径绕过相应钩子时,后端保持未知。采集器重启前已存在的长连接,需要再次产生经过 NAT 钩子的报文才能重新学习;不能把这一能力推广为所有 CNI 和流量卸载路径都已覆盖。
本地诊断可查询:
该地址使用现有 debug 监听,按实际配置调整。快照显示经过验证的 veth 来源、conntrack 所在 namespace、原始与后端端点、tuple 成员数,以及各类 map 写入失败计数;不显示内核指针,也不上报为新增平台数据。partial=true 表示达到采样边界或遇到并发变化,不能把样本为空解释为没有 NAT。可把 source_netns 与 netflow 的 netns 对齐,结合 destination_port/backend_port 判断入口关联缺失、tuple 冲突或 map 容量问题。
map_admission_failures 数组依次对应 tuple 索引、owner/版本记录、报文来源临时记录的写入失败。它们是累计次数,不能当作丢失连接数;应关注是否持续增长。正在并发写入的关联会做最多三次无等待重读,仍不稳定就保留未知。
生命周期删除和最终释放回收记录,另有有界 netlink 校准。校准失败或表过大时不会恢复缺少证据的关联,也不会因为长连接暂时空闲就删除其有效记录。异常摘要中的 entity.service=conntrack_dnat 与 evidence_partial 可提示采集缺口;相关容量参数会同时增加三个 HASH map 的内核内存,应先确认写入失败来源再扩容。
场景三:平台流量下降其实是上报积压¶
教学示例:业务请求量稳定,但节点的 netflow_pending_bytes=524288,netflow_queue_oldest_age_seconds=75;同窗采集损失没有增加,并出现来源为 netflow_output 的 output_backlog 摘要。
这些数据首先支持“待发送批次已经等待 75 秒”,不能支持“业务流量下降 50%”。应检查采集器至 DataKit、DataKit 至上游的连接、接收错误、限流和发送延迟;待发送队列也有容量限制,继续阻塞可能形成真正丢弃。
| 指标 | 需要区分的情况 |
|---|---|
netflow_pending_bytes/netflow_queue_oldest_age_seconds |
原有网络聚合上报积压 |
diagnostic_queue_bytes/diagnostic_queue_oldest_age_seconds |
诊断日志和指标的待发送积压 |
netflow_queue_full_points_total/netflow_rejected_points_total |
netflow 队列满或永久拒收 |
output_dropped_points_total/output_rejected_points_total |
诊断输出丢弃或永久拒收,包括超大编码记录 |
logs_limited_total |
摘要输出尝试被预算限制,不等于相同数量连接丢失 |
samples_omitted_total |
代表样本省略,不等于该组所有事实计数丢失 |
group_admission_failures_total |
新异常分组未被接纳,日志证据存在缺口 |
发送暂时失败时会保留编码批次并重试,不能承诺端到端 exactly-once。需要去重时使用日志的 collector_session + event_id。修复验收不仅看队列归零,还要看最老年龄、拒收/丢弃增量和恢复后的业务曲线;缺口不能通过插值伪装成真实观测。
用有界数据持续排障¶
推荐先在全节点保持默认节点指标和异常摘要,只在需要持续来源细节的少量节点开启 network_diagnostics_full_metrics=true。配置示例在现有 [[inputs.ebpf]] 中设置:
network_diagnostics_full_metrics = false
network_diagnostics_log_bytes_per_minute = 524288
network_diagnostics_log_points_per_minute = 240
| 项目 | 当前默认与边界 |
|---|---|
| 节点诊断指标 | 40 个固定字段;host/service 及稳定全局标签,不带 PID、端点、netns/interface 标签 |
| 异常日志 | 按类型、进程/服务/命名空间/服务端点归组,每组最多 3 个代表样本 |
| 日志频率 | 首次满足日志条件后通常 5 秒内入队;同组明确错误、DNS 及采集质量事件有新观测时每分钟更新,普通连接线索最多每 5 分钟更新;发送阻塞或预算不足会延后 |
| 持续日志预算 | 同时受 512 KiB/分钟与 240 条/分钟限制,任何一项耗尽就暂缓 |
| 短时突发 | 最多 2 MiB 与 960 条额度 |
| 单条日志 | 编码体积硬上限 16 KiB;不采集业务报文载荷,明文 DNS 可能包含查询名 |
| 本地状态 | 问题组/来源无新观测 30 分钟后清理;重启不回放;平台保留时长由存储策略决定 |
| 本地预算 | 分组记账 16 MiB;发送队列 8 MiB/2048 批;这些不是整个进程的 RSS 上限 |
单实例且主机和全局标签稳定时,1000 节点对应约 40000 条诊断指标时间线。完整模式会随命名空间、网卡及来源标签变化增加时间线;调整上报间隔可以减少点数,但不能消除标签组合带来的时间线。不要给诊断指标添加 PID、动态连接 ID 或远端端口作为全局标签。
512 KiB/分钟持续额度对应每节点每天约 720 MiB,240 条/分钟对应 345600 条;这是新日志入队预算的饱和值,另有初始突发、重试及传输开销,两项不会保证同时打满,也不包含 netflow 和指标。记录大小决定先耗尽哪项:例如平均 3 KiB 时,字节预算约允许 170 条/分钟;平均 1 KiB 时,条数预算先限制为 240 条/分钟。实际费用应根据试运行的编码量、条数及平台计费口径计算,不能把预算当作固定每日消费。
按业务负载验证资源与覆盖¶
短时测试的日志体积和采集结果不能代表所有生产负载。应按实际节点规模、内核、连接寿命和异常频率测量资源开销、数据量及证据覆盖,并检查采集损失、样本省略和输出拒收计数。
实践价值是把“没看到异常”与“异常证据不可用”分开,同时以固定节点时间线和受预算控制的摘要支持日常排障。扩大容量或预算前,应先用这些指标确认扩容能解决哪一条缺口。