尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

INT与gRPC网络遥测:精细化运维实战指南

INT与gRPC网络遥测:精细化运维实战指南 简介这份PDF文档面向HPC与下一代数据中心网络的运维工程师及架构设计人员聚焦如何借助Network Telemetry技术打破“网络黑盒”解决大规模复杂网络中流量精细可视、可控以及端到端秒级故障定位的难题。资源包共1个PDF文件大小约603KB内容围绕INT与gRPC两大核心技术展开系统讲解交换机主动推送Buffer Usage、CPU、内存等状态信息的机制以及通过INT在报文路径中嵌入MetaData实现转发路径与时延可视化的完整方案。文档还结合TCP Incast微突发流、交换机缓存容量与带宽升级不匹配等真实场景剖析传统SNMP监控的局限并给出丢包端口快速定位、缓存实时监控、端到端时延测量等运维能力的实现思路。目前已有320人学习适合希望深入理解网络遥测原理、构建可视化运维体系的技术人员参考可帮助读者掌握从技术选型到方案落地的关键要点。1. 网络遥测不是新概念但 INTgRPC 这套组合拳值得你花时间拆一遍如果你正在维护一个 25G/100G 的 HPC 或 AI 训练集群大概率遇到过这种场景业务侧反馈训练任务间歇性卡顿你登上核心交换机display interface看了一圈端口没有 CRC 错包CPU 和内存也正常SNMP 监控大盘上更是一片绿。但业务就是慢丢包就是发生了你根本不知道是哪台交换机的哪个端口、在哪个微秒级的时间窗口把包丢了。这不是你技术不行是传统监控手段的颗粒度根本够不着这个场景。这份《网络遥测Network Telemetry技术精细化网络运维实践》讲的就是怎么把网络从“黑匣子”变成“玻璃房”。核心思路两条线一条是 gRPC让交换机主动把 Buffer 使用率、CPU、内存、丢包事件推给监控服务器解决“设备状态实时可见”的问题另一条是 INTIn-band Network Telemetry让报文自己携带路径上每一跳的入端口、出端口、时间戳、设备 ID解决“转发路径和逐跳时延可见”的问题。适合谁看数据中心网络运维工程师、HPC 集群网络负责人、以及正在做网络可观测性选型的架构师。如果你还在用 SNMP 轮询那套东西排查微突发丢包这份材料会告诉你差距在哪。2. 为什么 SNMP 和 NetFlow 在这个场景下不够用从 TCP Incast 说起2.1 缓存增长跑不过带宽增长微突发丢包是结构性问题先看一组硬数据。1Gbps 接口时代主流交换芯片缓存大约 4MB10Gbps 时代涨到 16MB到了 25Gbps缓存只有 32MB。接口速率翻了 25 倍缓存只翻了 8 倍。按全端口公平使用缓存来算可用缓存时间反而下降了 65%。这意味着什么25G 网络下的 TCP Incast 现象比 10G 严重得多。TCP Incast 的典型场景是这样的一台 Master 节点向一组 Slave 节点发起计算任务请求所有 Slave 几乎同时返回结果。对 Master 的上联端口来说瞬间就是一个多打一的微突发流。如果这个突发量超过了出接口缓存能吸收的上限尾部丢弃就发生了。应用层检测到丢包触发 TCP 重传端到端时延进一步恶化。更麻烦的是这种丢包是微秒级的SNMP 默认 5 分钟轮询一次根本抓不到。提示判断你的网络是否存在 Incast 风险可以看业务侧是否出现“周期性卡顿 重传率升高 交换机端口无持续拥塞”的组合特征。2.2 SNMP 的轮询模型和 NetFlow 的采样模型各有硬伤SNMP 的问题在于它是“拉”模型。监控服务器周期性去问设备你现在的状态是什么这个周期最短也就 15 秒到 1 分钟对于微突发场景来说等你问到的时候拥塞早就发生并结束了。而且 SNMP 能拿到的 OID 有限Buffer 的实时占用、端口的瞬时队列深度这些细粒度数据标准 MIB 里根本没有。NetFlow 和 sFlow 确实能推送流量采样信息但它们推的是原始 IP 报文格式的采样数据不是规范化的数据模型。你要自己解析、自己聚合数据量还特别大。一个中等规模的数据中心NetFlow 采集器每天处理几十亿条流记录是常态扩展性很难跟上。更关键的是NetFlow 只告诉你“谁和谁在通信”不告诉你“报文在每一跳经历了什么”。转发路径、逐跳时延、Buffer 占用这些它都不管。2.3 gRPC 和 INT 分别补上了哪块拼图gRPC 补的是“设备自身状态实时推送”这块。交换机作为 gRPC 客户端主动向监控服务器gRPC 服务端建立 HTTP/2 通道周期性推送 Buffer Usage、CPU、Memory 等数据。当 Buffer 不足导致丢包时交换机实时上报丢包事件。注意这里是交换机主动推不是监控服务器去拉。时效性从分钟级提升到秒级甚至亚秒级。INT 补的是“报文转发路径和逐跳时延”这块。它的工作方式是在报文里插入遥测元数据。首节点匹配到采样策略后镜像报文并在四层头部后插入 INT 头把入端口 ID、出端口 ID、入端口时间戳、出端口时间戳、设备 ID 封装成 MetaData 插进去。中间每一跳匹配到 INT 头后继续追加本跳的 MD。最后一跳插完 MD 后在外面封装一个 ERSPAN IP 头外层目的 IP 是监控服务器地址把整个 INT 报文转发过去。这样监控服务器就拿到了一条完整的路径画像报文从哪进、从哪出、每一跳花了多少时间、经过哪些设备。两者结合一个管设备状态一个管路径状态合起来就是整网流量可视化。3. 动手拆解 gRPC 推送配置从交换机侧到监控服务器侧3.1 交换机侧 gRPC 客户端配置的关键参数不同厂商的配置命令有差异但核心参数就那几个。下面以常见的数据中心交换机 CLI 风格为例展示 gRPC 客户端的关键配置项。注意这里不是让你照抄是让你理解每个参数控制什么。# 开启 gRPC 功能指定监控服务器的 IP 和端口 grpc enable grpc server ip 192.168.10.100 port 50051 # 配置推送周期单位毫秒这里设为 1000ms 即 1 秒推一次 grpc push interval 1000 # 配置需要推送的遥测数据类型 grpc sensor-path buffer-usage enable grpc sensor-path cpu-usage enable grpc sensor-path memory-usage enable grpc sensor-path packet-drop-event enable # 配置丢包事件的触发阈值Buffer 使用率超过 80% 开始上报 grpc threshold buffer-usage 80 # 指定 gRPC 通道使用 TLS 加密如果监控服务器侧启用了 TLS grpc tls enable逻辑说明grpc enable是总开关。grpc server ip指定监控服务器地址和端口交换机作为客户端主动向这个地址发起 HTTP/2 连接。grpc push interval控制周期性数据的推送频率设得太短会增加交换机和监控服务器的负担设得太长会丢失微突发细节一般 500ms 到 1s 是常见起点。grpc sensor-path系列命令决定推什么数据Buffer、CPU、Memory 是基础三件套丢包事件是重点。grpc threshold是丢包事件的触发门限Buffer 使用率超过设定值才上报避免正常波动产生大量无效告警。参数怎么改如果你的监控服务器处理能力有限先把push interval放到 2000ms只开buffer-usage和packet-drop-event两个 sensor-path跑稳了再逐步加。TLS 如果监控服务器侧没配交换机侧开了也连不上两边要一致。3.2 监控服务器侧 gRPC 服务端的最小实现监控服务器侧需要起一个 gRPC 服务端来接收交换机推送的数据。下面用 Python 写一个最小可运行的接收端基于grpcio和protobuf。实际生产中你会用更完整的框架但理解这个最小实现有助于排查连接问题。import grpc from concurrent import futures import telemetry_pb2 import telemetry_pb2_grpc class TelemetryServicer(telemetry_pb2_grpc.TelemetryServiceServicer): def PushTelemetry(self, request, context): # request 里包含设备 ID、数据类型、时间戳、具体数值 device_id request.device_id data_type request.data_type timestamp request.timestamp value request.value # 丢包事件单独处理触发告警 if data_type packet_drop_event: print(f[DROP] device{device_id} time{timestamp} detail{value}) # 这里可以接入告警系统比如写入 Kafka 或调用 webhook else: print(f[DATA] device{device_id} type{data_type} value{value}) return telemetry_pb2.PushResponse(code0, messageok) def serve(): server grpc.server(futures.ThreadPoolExecutor(max_workers10)) telemetry_pb2_grpc.add_TelemetryServiceServicer_to_server( TelemetryServicer(), server ) # 监听 50051 端口与交换机侧配置一致 server.add_insecure_port([::]:50051) server.start() print(gRPC telemetry server started on port 50051) server.wait_for_termination() if __name__ __main__: serve()逻辑说明TelemetryServicer类实现了PushTelemetry方法交换机每次推送数据都会调用这个方法。request对象里携带了设备 ID、数据类型、时间戳和具体数值。丢包事件通过data_type区分单独走告警逻辑。grpc.server创建服务端实例add_insecure_port监听端口要和交换机侧grpc server ip配的端口一致。参数说明max_workers10控制并发处理线程数交换机数量多的时候要适当调大。add_insecure_port是不加密通道如果交换机侧开了 TLS这里要换成add_secure_port并加载证书。生产环境建议至少把接收到的数据写入消息队列不要直接在 gRPC 回调里做重逻辑否则会阻塞后续推送。3.3 验证 gRPC 通道是否建连成功配置完之后第一件事是确认交换机有没有成功连上监控服务器。在交换机侧执行# 查看 gRPC 客户端状态 display grpc client status # 预期输出示例 # Server IP: 192.168.10.100 # Server Port: 50051 # Connection State: CONNECTED # Last Push Time: 2025-01-15 10:23:45 # Push Count: 1523如果Connection State显示DISCONNECTED或CONNECTING按这个顺序排查先ping监控服务器地址确认三层可达再telnet 192.168.10.100 50051确认端口开放然后检查监控服务器侧 gRPC 服务端是否真的在监听netstat -tlnp | grep 50051最后看两边 TLS 配置是否一致。常见翻车点是防火墙只开了 ICMP 没开 TCP 50051或者监控服务器侧服务端绑定了127.0.0.1而不是0.0.0.0。4. INT 逐跳元数据插入从首节点到监控服务器的完整链路4.1 INT 头的封装格式和 MetaData 字段含义INT 的核心是在报文里插入逐跳的遥测数据。每个参与转发的交换机都会在 INT 头后面追加一层 MetaData。MetaData 里包含哪些字段直接决定了你能看到什么粒度的信息。常见字段如下表字段名长度含义运维用途Device ID4 字节设备唯一标识定位是哪台交换机Ingress Port ID2 字节入端口编号定位从哪个口进来Egress Port ID2 字节出端口编号定位从哪个口出去Ingress Timestamp8 字节入端口时间戳计算入向处理时延Egress Timestamp8 字节出端口时间戳计算出向转发时延Queue Depth4 字节出队列深度判断是否发生拥塞这些字段不是每个厂商都全支持具体支持哪些要看芯片能力。比如有些芯片不支持纳秒级时间戳只能用微秒级。但 Device ID、入端口、出端口这三个是基础一般都有。4.2 首节点、中间节点、尾节点的处理差异INT 的处理流程分三种角色配置和逻辑都不一样。首节点Ingress Switch报文进入网络的第一台交换机。它需要匹配采样策略决定哪些报文要插 INT 头。匹配到之后镜像报文在四层头部后插入 INT 头然后封装本跳的 MetaData。配置示例# 定义 INT 采样策略匹配源 IP 为 10.0.0.0/24 的流量 int sample-policy policy1 match source-ip 10.0.0.0/24 action mirror-and-insert-int # 在入接口应用采样策略 interface Ethernet1/1 int sample-policy policy1 # 指定 INT 元数据要采集的字段 int metadata device-id enable int metadata ingress-port enable int metadata egress-port enable int metadata ingress-timestamp enable int metadata egress-timestamp enable中间节点Transit Switch报文经过的中间交换机。它不需要重新匹配采样策略只需要识别 INT 头然后在 INT 头后面追加本跳的 MetaData。配置相对简单# 全局开启 INT 透明传输和元数据追加 int transit enable int metadata device-id enable int metadata ingress-port enable int metadata egress-port enable int metadata ingress-timestamp enable int metadata egress-timestamp enable尾节点Egress Switch报文离开网络的最后一台交换机。它追加完本跳 MetaData 后需要在报文外面封装一个 ERSPAN IP 头外层目的 IP 是监控服务器地址然后把整个 INT 报文转发给监控服务器。配置示例# 配置 ERSPAN 目的地址为监控服务器 int erspan destination 192.168.10.200 int erspan source 192.168.10.1 # 在出接口应用 INT 尾节点处理 interface Ethernet1/49 int egress-role enable逻辑说明首节点的sample-policy决定了采样范围不要全量采样否则监控服务器会被海量 INT 报文打爆。一般按业务网段或特定五元组采样。中间节点只需要int transit enable不需要重复配采样策略。尾节点的erspan destination指向监控服务器erspan source是尾节点自己的一个可达 IP。参数怎么改采样率是核心参数。如果监控服务器处理能力有限先把采样率降到 1:1000 甚至 1:10000只采关键业务流。int metadata字段按需开启时间戳字段对芯片有额外开销如果只关心路径不关心时延可以先不开时间戳。4.3 监控服务器侧解析 INT 报文并还原路径监控服务器收到 ERSPAN 封装的 INT 报文后需要解封装、提取 MetaData、还原路径。下面用 Python 的 scapy 库写一个解析示例from scapy.all import sniff, Ether, IP, GRE, Raw import struct def parse_int_packet(pkt): # 剥掉外层 ERSPAN 封装通常是 GRE 或 UDP if pkt.haslayer(GRE): inner pkt[GRE].payload else: return # 定位 INT 头这里假设 INT 头紧跟在 TCP/UDP 之后 # 实际偏移量取决于具体封装格式需要根据厂商文档调整 raw_bytes bytes(inner) # 简化处理假设 INT 头从固定偏移开始 int_offset 42 # 以太头14 IP头20 TCP头8仅作示例 int_data raw_bytes[int_offset:] # 解析 MetaData 列表每层 MD 固定长度 md_length 28 # DeviceID 4 InPort 2 OutPort 2 InTS 8 OutTS 8 QueueDepth 4 hop_count len(int_data) // md_length path [] for i in range(hop_count): md int_data[i*md_length:(i1)*md_length] device_id struct.unpack(!I, md[0:4])[0] in_port struct.unpack(!H, md[4:6])[0] out_port struct.unpack(!H, md[6:8])[0] in_ts struct.unpack(!Q, md[8:16])[0] out_ts struct.unpack(!Q, md[16:24])[0] queue_depth struct.unpack(!I, md[24:28])[0] path.append({ device_id: device_id, in_port: in_port, out_port: out_port, in_ts: in_ts, out_ts: out_ts, queue_depth: queue_depth, hop_latency_ns: out_ts - in_ts }) # 打印路径 for i, hop in enumerate(path): print(fHop {i}: device{hop[device_id]} fin{hop[in_port]} out{hop[out_port]} flatency{hop[hop_latency_ns]}ns fqueue{hop[queue_depth]}) # 监听 ERSPAN 流量假设走 GRE 协议 sniff(filterproto gre, prnparse_int_packet, store0)逻辑说明sniff抓取 GRE 封装的 ERSPAN 报文parse_int_packet剥掉外层封装后定位 INT 头。md_length是每层 MetaData 的固定长度按字段定义累加得到。循环解析每一跳的 Device ID、入端口、出端口、时间戳、队列深度计算逐跳时延。最后按顺序打印路径。参数说明int_offset是 INT 头相对于内层报文起始位置的偏移量这个值取决于具体封装格式不同厂商实现不一样需要根据实际抓包调整。md_length也要和交换机侧实际开启的字段对齐如果没开 Queue Depth长度要减 4。sniff的 filter 表达式按实际 ERSPAN 封装协议调整有的用 GRE有的用 UDP 4790。5. 避坑与排查INTgRPC 落地时最容易翻车的五个点5.1 交换机 gRPC 连接频繁断开重连现象display grpc client status显示 Connection State 在 CONNECTED 和 DISCONNECTED 之间反复跳变监控服务器侧日志看到大量连接建立和断开记录。原因最常见的是 gRPC 服务端max_workers设得太小交换机数量一多并发推送请求把线程池打满新连接被拒绝。其次是网络中间有防火墙或负载均衡设备对 HTTP/2 长连接有空闲超时超时后静默断连。解决把监控服务器侧max_workers调到交换机数量的 2 到 3 倍。在交换机侧开启 gRPC keepalive定期发送心跳包维持连接。如果中间有防火墙把空闲超时调到 300 秒以上。5.2 INT 报文到了监控服务器但解析出来全是乱码现象tcpdump 能看到 ERSPAN 报文但解析脚本提取的 Device ID、端口号全是异常值路径完全对不上。原因INT 头的偏移量算错了。不同厂商在四层头部后插入 INT 头的位置有差异有的在 TCP 头之后有的在 UDP 头之后还有的会跳过选项字段。另外MetaData 的字段顺序和长度也可能和文档不一致需要以实际抓包为准。解决先用 Wireshark 打开一个 INT 报文手动逐字节对照厂商文档确认偏移量和字段布局。把int_offset和md_length改成实际值。建议先在测试环境用单条流验证确认解析正确后再上生产。5.3 Buffer 使用率推送正常但丢包事件一直不上报现象gRPC 通道正常Buffer Usage 数据每秒都在推但packet-drop-event从来没触发过业务侧却确实有丢包。原因丢包事件的触发阈值设得太高。比如设了 80%但实际丢包发生在 Buffer 使用率 60% 的时候因为芯片的缓存分配策略不是全局共享某些端口组可能提前耗尽。另外有些芯片的丢包事件上报需要额外开启硬件计数器默认是关闭的。解决把grpc threshold buffer-usage先降到 50% 观察确认能触发后再逐步调回合理值。检查芯片是否支持丢包事件上报如果不支持只能靠周期性推送的 Buffer Usage 数据做趋势判断无法做到实时告警。5.4 INT 采样率过高导致监控服务器 CPU 打满现象监控服务器 CPU 持续 90% 以上gRPC 数据接收延迟增大INT 解析脚本处理不过来Kafka 积压严重。原因采样率设得太激进。比如 1:1 全量采样每条流都插 INT 头监控服务器收到的报文量等于全网转发量任何单机都扛不住。另外INT 元数据字段开太多也会增加报文长度和处理开销。解决把采样率降到 1:1000 或更低只采关键业务流。INT metadata 只开 Device ID、入端口、出端口三个基础字段时间戳和队列深度按需开启。监控服务器侧用多线程或异步处理解析和存储分离解析完直接扔消息队列不要在原地做重逻辑。5.5 尾节点 ERSPAN 封装后报文被上游设备丢弃现象首节点和中间节点都正常插入了 INT 头但监控服务器就是收不到 ERSPAN 报文。在尾节点上抓包能看到封装后的报文但发出去就没了。原因ERSPAN 封装后的外层 IP 是监控服务器地址但尾节点到监控服务器之间的路径上某些设备可能不认识 ERSPAN 协议或者 ACL 把 GRE/UDP 4790 封装的报文拦了。另外如果外层 IP 的源地址不可达回程路由也会有问题。解决确认尾节点到监控服务器三层可达ping通。检查路径上所有设备的 ACL放行 ERSPAN 封装协议GRE 或 UDP 4790。int erspan source配一个尾节点上实际存在的、有路由的 IP 地址不要随便配一个不存在的地址。6. 把 INT 和 gRPC 数据拼起来用一个端到端故障定位的实操技巧前面几章分别讲了 gRPC 和 INT 的配置与解析但真正体现这套方案价值的地方是把两类数据关联起来用。我一般会这么做在监控服务器侧把 gRPC 推送的 Buffer Usage 和丢包事件按设备 ID 和时间戳建索引同时把 INT 解析出来的逐跳路径也按设备 ID 和时间戳建索引。当业务侧报障时先根据时间窗口找到对应的丢包事件拿到设备 ID 和端口号再去 INT 路径库里查同一时间段经过该设备的流还原出完整的转发路径和逐跳时延。这个关联查询用 SQL 就能做不需要上复杂的图数据库。下面是一个简化示例-- 查询指定时间窗口内发生丢包的设备及其端口 WITH drop_events AS ( SELECT device_id, port_id, drop_time, buffer_usage FROM grpc_drop_events WHERE drop_time BETWEEN 2025-01-15 10:23:00 AND 2025-01-15 10:23:10 ), -- 查询同一时间窗口内经过这些设备的 INT 路径 int_paths AS ( SELECT flow_id, device_id, in_port, out_port, hop_latency_ns, queue_depth, int_timestamp FROM int_hop_records WHERE int_timestamp BETWEEN 2025-01-15 10:23:00 AND 2025-01-15 10:23:10 ) SELECT d.device_id, d.port_id AS drop_port, d.buffer_usage, p.flow_id, p.in_port, p.out_port, p.hop_latency_ns, p.queue_depth FROM drop_events d JOIN int_paths p ON d.device_id p.device_id AND d.port_id p.out_port ORDER BY p.hop_latency_ns DESC;逻辑说明drop_eventsCTE 从 gRPC 丢包事件表里捞出指定时间窗口的丢包记录拿到设备 ID 和端口号。int_pathsCTE 从 INT 逐跳记录表里捞出同一时间窗口的路径数据。然后按设备 ID 和出端口做 JOIN把丢包事件和经过该端口的流关联起来。最后按逐跳时延降序排列时延最大的那跳就是最可疑的拥塞点。参数说明时间窗口不要开太大10 秒左右比较合适太大数据量会爆炸。d.port_id p.out_port这个 JOIN 条件是关键因为丢包发生在出端口方向。如果 INT 记录里没有出端口字段这个查询就跑不了所以前面配置 INT metadata 时出端口字段必须开。这个查询跑出来的结果直接告诉你哪台交换机的哪个端口在什么时间发生了丢包当时 Buffer 使用率是多少哪些流经过了那个端口每一跳的时延和队列深度是多少。拿着这个结果去定位问题比盲目登设备看 counter 高效得多。从那以后我每次上 INT 新版本或者调整采样策略都会先跑一遍这个关联查询确认丢包事件和 INT 路径能对上再放开到全量业务。这个习惯帮我省了很多事后排查的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表