hubble flow Filter 默认不显示 http/dns 字段,因 l7 解析需显式启用 l7proxy.enabled 并配置匹配的 ciliumnetworkpolicy,且流量必须经过 envoy;否则字段不存在,filter 会静默失败。

Hubble flow filter 默认看不到 L7 协议字段(如 HTTP path、DNS query),因为 L7 解析默认关闭,且 filter 本身不触发解码 —— 必须显式启用 L7 可见性并确保流量路径经过支持的代理点。
为什么 hubble observe --filter 不显示 HTTP 或 DNS 字段
L7 解析不是 Hubble 的默认行为:Cilium 默认只在 eBPF 层抓取 L3/L4 元数据(源/目的 IP、端口、协议),hubble observe 的 filter 功能仅对已采集字段做筛选,不会“现场解包”L7 内容。
- HTTP/DNS 等字段只有在 Cilium 启用 L7 策略或显式开启 L7 可见性后,才由 Envoy(或内核中实验性 L7 解析器)注入到 flow 记录中
- 即使启用了 L7,如果流量绕过 Envoy(比如直通模式、hostNetwork Pod、或非策略匹配的连接),也不会产生 L7 字段
-
--filter 'http.path == "/api/users"'这类写法会静默失败(无报错,但不匹配任何 flow),因为字段根本不存在
如何开启 L7 协议可见性(Cilium v1.14+)
核心是两步:启用 L7 可见性开关 + 确保目标服务被 L7 感知路径覆盖。不是配 Hubble,而是配 Cilium 本身。
- 安装或升级时,在
helm install或cilium install中添加参数:--set hubble.relay.enabled=true --set hubble.ui.enabled=true --set l7Proxy.enabled=true - 必须启用
l7Proxy.enabled:这是 L7 解析的开关,它会部署 Envoy 实例并重定向匹配策略的流量 - 单独设置
hubble.enableL7Proxy=true已废弃(v1.13+),该配置项不再生效 - 验证是否生效:
kubectl -n kube-system get cm cilium-config -o yaml | grep -i "l7|proxy",确认输出含enable-l7-proxy: "true"
哪些流量能带 L7 字段?关键看策略和端口绑定
L7 字段只出现在明确被 Cilium L7 策略“捕获”的连接上 —— 没有策略,就没有解析;策略没匹配,也不解析。
- 必须存在至少一条
CiliumNetworkPolicy启用了rules.http或rules.dns,哪怕只是空规则({})也能触发解析 - 目标 Pod 的容器端口需在策略中显式声明为
port+protocol: TCP,且该端口未被标记为skip-port-mapping - NodePort / LoadBalancer 类型 Service 的外部流量,若未经过 Cilium 的 eBPF LB 路径(例如使用 kube-proxy iptables 模式),L7 字段将缺失
- 示例最小策略:
apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: enable-http-visibility spec: endpointSelector: matchLabels: app: backend ingress: - fromEndpoints: - matchLabels: app: frontend toPorts: - ports: - port: "8080" protocol: TCP rules: http: [] # 空列表即启用 HTTP 解析
filter 使用时的典型错误和绕过技巧
hubble observe --filter 对 L7 字段的支持有限,尤其在旧版本或 relay 模式下容易误判。
- 不要用
--filter 'http.method == "GET"'直接过滤 —— 若 Hubble Relay 未开启 L7 解析(即--set hubble.relay.l7ParsingEnabled=true未设),字段仍不可见 - Relay 默认不解析 L7,需额外加 Helm 参数:
--set hubble.relay.l7ParsingEnabled=true(注意:这会让 Relay 解析所有流,可能影响性能) - 更稳的做法是先用
hubble observe -o json | jq '.http'查看原始字段是否存在,再决定是否加 filter - 如果只关心某类 L7 流量,优先用 CiliumNetworkPolicy 的
toFQDNs或toPorts.rules.http做第一层收敛,比靠 Hubble filter 更可靠
真正卡住人的地方往往不是命令怎么写,而是没意识到:L7 字段从生成到显示,要跨 Cilium agent、Envoy、Hubble server、Hubble relay 四个组件,其中任意一个关了开关或没走对路径,字段就消失了 —— 查的时候得一段段确认,而不是只盯 hubble observe 的输出。