Linux cilium 的 Hubble flow filter 与 L7 协议可见性开启

1次阅读

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

Linux cilium 的 Hubble flow filter 与 L7 协议可见性开启

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 installcilium 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.httprules.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 的 toFQDNstoPorts.rules.http 做第一层收敛,比靠 Hubble filter 更可靠

真正卡住人的地方往往不是命令怎么写,而是没意识到:L7 字段从生成到显示,要跨 Cilium agent、Envoy、Hubble server、Hubble relay 四个组件,其中任意一个关了开关或没走对路径,字段就消失了 —— 查的时候得一段段确认,而不是只盯 hubble observe 的输出。

text=ZqhQzanResources