3. Hubble架构解析:Relay、Observer、UI组件、数据流与gRPC接口
Hubble是Cilium生态中负责可观测性的核心组件,它将eBPF在内核层面采集的流数据、指标与事件,通过一套分层架构暴露给运维人员。理解Hubble的组件划分、数据流转以及gRPC接口设计,是进行流量可视化和配额校准故障排查的基础。
3.1 核心组件与职责
Hubble由三个主要组件构成:Observer Agent(通常简称为Observer)、Relay和Hubble UI。它们各自承担不同的职责,协同完成从数据采集到前端展示的全链路。
| 组件 | 部署位置 | 核心职责 | 关键特性 |
|---|---|---|---|
| Observer Agent | 每个Kubernetes节点(DaemonSet) | 通过本地Unix Socket与Cilium Agent通信,消费eBPF Map中的流事件;提供本地gRPC服务 | 低延迟、节点级数据源、直接访问内核事件 |
| Relay | 集群级Deployment(通常1-2个副本) | 聚合所有Observer Agent的数据;实现全局排序、去重与缓存;对外提供统一的gRPC查询接口 | 水平扩展、无状态、支持多集群联邦 |
| Hubble UI | 集群内Deployment或独立部署 | 基于React的前端应用;通过gRPC-web或REST代理连接Relay;提供服务依赖图、流量表格与时间线 | 实时刷新、交互式拓扑、支持L3/L4/L7过滤 |
排查要点: 在配额校准场景中,Observer Agent是数据真实性的第一道关口。如果节点上的eBPF Map被错误清理或Cilium Agent重启,Observer将输出不完整流记录,导致Relay聚合后的配额统计出现偏差。
3.2 数据流全景
数据从内核eBPF程序产生,到最终呈现在UI上,经历了四个主要阶段。下图展示了完整的端到端数据流路径。
故障排查关键点: 数据流中的任何一环出现断裂,都会导致UI上出现数据缺失或延迟。例如,如果Relay无法连接到某个节点的Observer Agent(通常由于网络策略或gRPC端口不通),该节点的所有流量将完全不可见,配额校准将漏算该节点的所有Pod流量。
3.3 gRPC接口详解
Hubble的组件间通信完全基于gRPC协议。Observer Agent和Relay各自暴露一组定义清晰的gRPC服务。理解这些接口的签名和调用方式,对于编写自定义排查工具或调试连接问题至关重要。
3.3.1 Observer Agent 本地gRPC接口
每个节点上的Observer Agent通过Unix Socket(默认路径 /var/run/cilium/hubble.sock)暴露以下核心服务:
- Observer:提供
GetFlows、GetAgentEvents、GetDebugEvents等RPC,用于拉取流数据和事件。 - Peer:提供
NotifyRPC,用于向Relay通知本节点的服务变更(如IP地址、服务端口)。
// 使用 hubble CLI 直接查询本地 Observer Agent 示例
# 通过 Unix Socket 获取最近 10 条流记录
hubble observe --server unix:///var/run/cilium/hubble.sock --last 10
# 获取当前节点的服务列表(Peer 服务)
hubble status --server unix:///var/run/cilium/hubble.sock
3.3.2 Relay 统一gRPC接口
Relay对外暴露与Observer Agent相同的 Observer 和 Peer 服务接口,但内部实现了多节点聚合。上层消费者(如Hubble UI或CLI)只需连接Relay,无需关心底层有多少个节点。
| RPC 名称 | 请求参数 | 响应流 | 典型用途 |
|---|---|---|---|
GetFlows |
FlowRequest(包含时间范围、过滤条件、黑名单) |
GetFlowsResponse 流 |
实时流量查询、历史回放、配额统计 |
GetAgentEvents |
AgentEventRequest |
GetAgentEventsResponse 流 |
监控Agent状态变更、启动/停止事件 |
GetDebugEvents |
DebugEventRequest |
GetDebugEventResponse 流 |
调试eBPF程序、捕获丢包或策略拒绝事件 |
GetNodes |
NodeRequest |
GetNodesResponse 流 |
获取集群中所有Hubble节点的状态和地址 |
配额校准常见陷阱: 使用
GetFlows 进行配额统计时,必须注意 FlowRequest 中的 time 字段。如果时间范围设置不当(例如跨越了Relay的缓存窗口),可能导致重复计数或遗漏。建议始终使用 since 和 until 明确指定时间边界,并配合 whitelist 过滤目标Pod的标签。
3.4 组件间通信与连接模型
Hubble的组件间通信采用拉取(Pull)与推送(Push)混合模式。Observer Agent主动从Cilium Agent拉取事件,Relay则通过gRPC Stream从各Observer Agent拉取数据。UI通过gRPC-web或Envoy代理向Relay发起查询。
排查连接问题: 当UI显示“No data”或“Connection refused”时,应首先检查Relay Pod的日志,确认其是否成功连接到所有节点的Observer Agent。使用
hubble status 命令可以快速查看Relay视角下的节点连接状态。如果某个节点显示为“Unreachable”,则需要检查该节点上的Observer Agent是否正常运行,以及集群网络策略是否允许Relay访问节点的gRPC端口(默认4244)。
3.5 架构设计对故障排查的影响
Hubble的分层架构在带来灵活性的同时,也引入了额外的故障排查复杂度。以下是几个关键影响点:
- 数据一致性窗口:Relay对来自不同节点的流事件进行排序和去重,但存在一个时间窗口(默认2秒),在此窗口内的事件可能乱序到达。配额校准查询应容忍微小的计数偏差。
- 单点故障转移:Relay是无状态的,支持多副本部署。如果某个Relay实例宕机,客户端应自动重连到其他实例。排查时需确认客户端是否配置了正确的负载均衡策略。
- gRPC流式传输:Observer Agent向Relay推送数据时使用gRPC Server-Sent Streaming。如果网络不稳定导致流中断,Relay会自动重连。但重连期间的数据可能丢失,导致配额统计出现缺口。
实战建议: 在进行eBPF配额校准前,建议先通过
hubble observe --server relay-service:4245 --last 1000 --output json 导出最近1000条流记录,与预期配额进行比对。如果发现计数偏差,应分别查询各节点的Observer Agent(通过 --server node-ip:4244),以定位是哪个节点的数据源出现了问题。