土法炼钢兴趣小组的算法知识备份

【可观测性工程】网络可观测性:Cilium Hubble、Pixie、DeepFlow、Tetragon

文章导航

分类入口
architectureobservability
标签入口
#network-observability#cilium#hubble#tetragon#pixie#deepflow#ebpf#flow-log#service-topology#tls-decryption#http2

目录

网络可观测性(Network Observability)是可观测性工程中最靠近基础设施、却又越来越靠近业务语义的一个方向。传统运维视角下的网络监控,关注的是带宽、丢包、重传、路由这些链路层与传输层指标;而微服务时代的网络可观测性,更多是回答这样的问题:

要回答这些问题,单纯靠应用内埋点(即 APM)是不够的,因为很多问题根本不在应用的代码路径上;而只看传统的 SNMP、NetFlow 也不够,因为它们看不到 L7 协议语义,也看不到 Kubernetes 的容器上下文。

扩展可编程内核的伯克利包过滤器(eBPF,extended Berkeley Packet Filter)技术的成熟,使得”在内核中直接捕获网络事件、在采集点注入容器元数据、在用户态做 L7 协议解析”这条路径变得工程化可行。本文围绕这条主线,依次讲解:

网络可观测性分层与 eBPF 采集点

一、网络可观测性的层次

网络可观测性必须分层来看。每一层能回答的问题不同,采集成本、实现难度也不同。

1.1 分层视角

按照开放系统互连(OSI,Open Systems Interconnection)模型,网络可观测性一般聚焦三层:

三者并不是彼此替代的关系,而是互相补充。一个 5xx 错误爆发时,L7 指标会告诉你”哪个接口、哪个客户端、错误码是多少”,L4 指标会告诉你”是不是背后有大量连接被 RST 掉了”,L3 指标会告诉你”底层有没有物理丢包或路由黑洞”。

1.2 为什么 L7 对微服务最关键

单体架构时代,一次用户请求的路径基本就是:浏览器 → 负载均衡(LB)→ 应用服务器 → 数据库。监控这四个节点就基本看清了全貌。

微服务架构下,一次用户请求可能涉及几十次内部调用,调用之间通过 HTTP/gRPC/消息队列(MQ,Message Queue)串联。此时:

  1. L3/L4 指标即使全部正常,应用层也可能大量报错(例如服务端返回 400/500)。
  2. 出问题时,绝大多数问题定位需要 L7 的语义信息(“是哪个接口挂了”“是哪个下游返回了错误码”)。
  3. 调用链追踪(Tracing)虽然能补上这一块,但需要代码侵入式埋点,在异构语言栈、老系统、第三方组件里无法覆盖完全。

所以,L7 网络可观测性填补的恰恰是 APM 埋点覆盖不到的盲区:无侵入、面向东西向流量、以”网络行为”为第一视角来看服务间交互。

1.3 各层可回答问题对比

下面这张表是一个粗略的能力对比。

能力 L3(IP) L4(TCP/UDP) L7(应用)
网络是否通 间接
是否丢包 / 重传 有限
建连耗时 间接
请求耗时(应用视角) 近似
错误码 / 业务错误
区分用户、租户、接口
成本(CPU/存储)
是否需要协议解析
能否反映 TLS 内的细节 是(需要解密)

1.4 传统网络监控 vs eBPF 方案

传统网络监控的数据来源包括:

这些方案的共性局限:

  1. 拿不到容器 / Pod 上下文。NetFlow 只知道 IP,对 Kubernetes 来说,Pod IP 是朝生暮死的。
  2. 看不透 L7,或要靠深度包检测(DPI,Deep Packet Inspection)硬件盒子,价格昂贵。
  3. 对加密流量无能为力。

基于 eBPF 的方案则具备:

  1. 在内核中直接采集,开销可控。
  2. 通过挂载到 sched_process_execcgroup 相关钩子,可以在事件源头就带上容器元数据。
  3. 通过 uprobe 挂到 OpenSSL/Go crypto 等库,可以在加密前/解密后取明文。
  4. 可以做到无须在物理设备上架设旁路,采集、过滤、聚合都在主机侧完成。

这是本文所有工具的共同技术底座。

二、eBPF 网络数据采集机制

不同工具采用的 eBPF Hook 点差别不小,理解这些 Hook 点的语义,是看懂工具架构的前提。

2.1 套接字过滤器(Socket Filter,SK_FILTER)

套接字过滤器是最古老的 BPF 程序类型之一。程序被挂到一个套接字(socket)上,内核会把该 socket 上收到的数据包拷贝一份传给程序,程序返回保留多少字节(0 表示丢弃该副本)。

特点:

典型使用者:tcpdump(libpcap 会生成 cBPF 程序)、BCC 工具链里的一些抓包脚本。

/* 伪代码:一个最朴素的 socket filter,保留所有 TCP 报文 */
SEC("socket")
int sk_filter_prog(struct __sk_buff *skb) {
    if (skb->protocol != __constant_htons(ETH_P_IP))
        return 0;
    __u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
    if (proto != IPPROTO_TCP)
        return 0;
    return -1;  /* -1 表示全部保留 */
}

在网络可观测性产品中,socket filter 通常不是主力,因为它的副本开销在高吞吐场景偏大。

2.2 流量控制挂钩(TC Hook)

Linux 流量控制(Traffic Control,简称 TC)子系统提供了 clsact 这个特殊 qdisc,允许把 eBPF 程序分别挂到入向(ingress)和出向(egress)。

特点:

Cilium 对 TC Hook 的使用最为激进:策略执行、服务负载均衡、可观测性采集都通过 TC 程序实现。Cilium Hubble 的流日志,主力来源就是挂在 TC ingress/egress 上的程序。

SEC("tc")
int tc_ingress(struct __sk_buff *skb) {
    struct flow_key key = {};
    parse_l3_l4(skb, &key);
    struct flow_stats *st = bpf_map_lookup_elem(&flow_map, &key);
    if (!st) {
        struct flow_stats zero = {};
        bpf_map_update_elem(&flow_map, &key, &zero, BPF_ANY);
        st = bpf_map_lookup_elem(&flow_map, &key);
    }
    if (st) {
        __sync_fetch_and_add(&st->rx_packets, 1);
        __sync_fetch_and_add(&st->rx_bytes, skb->len);
    }
    return TC_ACT_OK;
}

2.3 快速数据路径(XDP,eXpress Data Path)

XDP 是 Linux 网络栈中最早的可编程点,挂在网卡驱动(甚至网卡硬件,如部分 Mellanox 网卡)上。

特点:

因此 XDP 并不适合直接用来做 L7 可观测性,但它可以承担:

Cilium 在 XDP 层做过负载均衡加速;Tetragon、Hubble 在可观测路径上主要还是靠 TC 与 kprobe。

2.4 内核函数探针(kprobe)

kprobe 允许在任意内核函数入口/返回处挂探针。网络可观测性里常用的几个:

kprobe 的优点是灵活:没有 TC 程序那么严格的限制,能直接拿到内核结构体字段。缺点是与内核版本强绑定,函数签名或内部结构变动会打破程序。

一站式编译一次到处运行(CO-RE,Compile Once – Run Everywhere)和 BPF 类型格式(BTF,BPF Type Format)缓解了这个问题,Hubble 和 DeepFlow 都以 CO-RE 方式分发 eBPF 程序。

2.5 用户态函数探针(uprobe)与 TLS 库

应用层流量越来越多使用传输层安全协议(TLS,Transport Layer Security)加密。从 TC/socket filter 这种”网卡之后、应用之前”的位置看,拿到的是密文,无法解析 HTTP 等应用协议。

解决思路是在用户态库里挂 uprobe:

这样在不拿到服务端私钥、不做中间人代理的前提下,就能在源进程与目的进程两端的用户态”明文位置”采集到 HTTP/gRPC 明文。DeepFlow、Pixie、Hubble 的 L7 TLS 解析都采用这条路径。

三、Cilium Hubble 架构

Cilium 是基于 eBPF 的 Kubernetes 容器网络接口(CNI,Container Network Interface)实现,Hubble 则是在 Cilium 之上构建的网络与安全可观测性层。

3.1 Cilium 简介

Cilium 的核心理念:

从可观测性视角看,Cilium 在每个 Pod 的 veth 上挂了 TC 程序,这些程序天然能看到每个数据包,且已经持有了”来自哪个 Pod、去往哪个 Pod”的身份信息。这是 Hubble 得以低成本生成 L3/L4/L7 流日志的基础。

3.2 Hubble 组件

Hubble 的组件从节点到集群呈三级结构:

+--------------+      +--------------+      +--------------+
|  Hubble UI   |<---->| Hubble Relay |<---->| Hubble Daemon| (node A)
+--------------+      |              |<---->| Hubble Daemon| (node B)
        ^             +--------------+      +--------------+
        |                                           ^
        | gRPC                                      | eBPF Map
        |                                           |
   hubble CLI ----------> Hubble Relay         Cilium Agent

3.3 流日志(Flow Log)格式

Hubble 的流事件由 flow.Flow Protobuf 定义,主要字段:

{
  "time": "2026-04-22T09:12:31Z",
  "verdict": "FORWARDED",
  "source": {
    "identity": 18432,
    "namespace": "frontend",
    "pod_name": "web-7c8f6d9f6b-abc12",
    "labels": ["app=web", "version=v1"]
  },
  "destination": {
    "identity": 24815,
    "namespace": "order",
    "pod_name": "order-svc-5f9c8d7b6-xyz34",
    "labels": ["app=order-svc"]
  },
  "l4": {
    "TCP": {"source_port": 51234, "destination_port": 8080}
  },
  "l7": {
    "type": "REQUEST",
    "http": {"method": "POST", "url": "/api/v1/orders", "protocol": "HTTP/1.1"}
  }
}

3.4 Hubble 指标

Hubble 提供两类指标:

典型指标:

这些指标默认不会全部开启,需要通过 Cilium 配置显式启用,因为 L7 维度的高基数(High Cardinality)指标会显著放大 Prometheus 的成本。

3.5 Hubble CLI 实战

以下命令在实际运维中高频使用。

# 查看最近的流事件,带 Kubernetes 上下文
hubble observe --namespace order

# 仅看 L7 HTTP 流量,且状态码 >= 500
hubble observe --protocol http --http-status '5..'

# 查看丢包事件,按丢包原因分组
hubble observe --verdict DROPPED --output json | jq '.drop_reason' | sort | uniq -c

# 查看某 Pod 的出入流量
hubble observe --pod order/order-svc-5f9c8d7b6-xyz34

# 按服务标签过滤
hubble observe --to-label app=payment --from-label app=web

# 查看 DNS 查询
hubble observe --protocol dns

典型输出:

Apr 22 09:12:31.517  frontend/web-...abc12:51234 -> order/order-svc-...xyz34:8080 HTTP/1.1 POST /api/v1/orders FORWARDED
Apr 22 09:12:31.519  order/order-svc-...xyz34:8080 -> frontend/web-...abc12:51234 HTTP/1.1 500 Internal Server Error (12.3ms) FORWARDED

3.6 服务拓扑图

Hubble UI 基于累积的流事件自动生成服务依赖图:节点是 Pod/Service/Workload,边是观察到的调用方向,边的属性包含请求速率、错误率、时延。

这张图的工程价值在于:

3.7 网络策略可视化

Cilium 使用 CiliumNetworkPolicy(CNP)描述网络策略。Hubble 可以清楚展示:

这在灰度收紧零信任网络(Zero Trust Network)策略时非常关键:你可以先把策略跑在”审计模式”,用 Hubble 观察会被拒绝哪些流量,再真正开启强制执行。

3.8 部署与 Prometheus/Grafana 集成

以下是最小化的 Cilium + Hubble Helm 部署片段。

# values.yaml
kubeProxyReplacement: strict
k8sServiceHost: kube-apiserver.cluster.local
k8sServicePort: 6443

hubble:
  enabled: true
  metrics:
    enabled:
      - dns:query;ignoreAAAA
      - drop
      - tcp
      - flow
      - icmp
      - http
  relay:
    enabled: true
  ui:
    enabled: true

对应安装:

helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium \
  --namespace kube-system \
  -f values.yaml

# 访问 Hubble UI
cilium hubble ui

Prometheus 侧,给 Hubble Relay / Daemon 加 ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: hubble
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: hubble
  endpoints:
    - port: hubble-metrics
      interval: 30s

Grafana 侧,Cilium 官方提供了一整套仪表盘,覆盖 L3/L4/L7 指标与策略审计。

四、Tetragon:安全与可观测融合

Tetragon 同样出自 Isovalent(Cilium 团队),但关注点不同:它不是为了做流量分析,而是为了做运行时安全可观测。

4.1 Tetragon 定位

4.2 TracingPolicy 示例

下面这条策略,观测并记录所有对 /etc/shadow 的读取,且来自容器内进程的操作会被杀死:

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: audit-etc-shadow
spec:
  kprobes:
    - call: "security_file_permission"
      syscall: false
      args:
        - index: 0
          type: "file"
        - index: 1
          type: "int"
      selectors:
        - matchArgs:
            - index: 0
              operator: "Equal"
              values:
                - "/etc/shadow"
          matchActions:
            - action: Sigkill

再来一个:监控对外发起的 TCP 连接,过滤非集群内的目的地址,辅助发现横向移动或 C2 外联。

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: egress-connect-monitor
spec:
  kprobes:
    - call: "tcp_connect"
      syscall: false
      args:
        - index: 0
          type: "sock"
      selectors:
        - matchArgs:
            - index: 0
              operator: "NotDAddr"
              values:
                - "10.0.0.0/8"
                - "172.16.0.0/12"

4.3 与 Falco 的差异

Falco 同样是运行时安全工具,但:

两者都有生产案例,选型看团队栈:以 Cilium 为底座,Tetragon 更顺滑;已有 Falco 生态则无必要切换。

4.4 与安全信息和事件管理系统(SIEM,Security Information and Event Management)集成

Tetragon 事件可以通过 JSON 流输出:

kubectl exec -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact

在生产中一般把事件通过 Fluent Bit / Vector 收敛到 Kafka,再入 SIEM(Splunk、Elastic、阿里云 SLS、腾讯 CLS 等)进行长期留存与关联分析。事件与 Hubble 的流事件可以用 Pod 身份、时间戳做 Join,把”安全事件”与”网络动作”串起来。

五、Pixie(New Relic)

Pixie 2019 年起由 Pixie Labs 开源,后被 New Relic 收购,现为云原生计算基金会(CNCF,Cloud Native Computing Foundation)沙箱项目。它的核心卖点是”零埋点、协议自动解析”。

5.1 架构

整体上 Pixie 强调”数据不出集群”:默认情况下原始事件、协议负载都只存在 PEM 的内存/本地盘中,出集群的只有用户通过 PxL 脚本结果显式导出的数据。

5.2 协议自动解析

Pixie 在内核 uprobe / kprobe 以及 socket 缓冲区上采集数据,在用户态 PEM 做协议识别与解析。目前内建支持:

识别使用”协议指纹”策略:从 socket 的第一批字节中,尝试匹配已知协议的起始模式(如 HTTP 的方法前缀、MySQL 的握手包结构),匹配成功后,给该 socket 打上协议标签,后续按对应的状态机解析。

5.3 PxL 脚本语言

Pixie 的数据查询语言叫 PxL,语法类似 Python + Pandas:

import px

df = px.DataFrame('http_events', start_time='-5m')
df = df[df.resp_status >= 500]
df.svc = df.ctx['service']
df.latency_ms = df.latency / 1e6
df = df.groupby(['svc', 'req_path', 'resp_status']).agg(
    count=('latency_ms', px.count),
    p99=('latency_ms', px.quantiles),
)
px.display(df, 'slow_requests')

脚本在 Vizier 上解析,下发到每个 PEM 并发执行。这种模式相当于”把查询推到数据侧”,避免把原始数据集中存储。

5.4 开销与限制

官方基准显示,Pixie 默认配置下:

限制:

5.5 与 OpenTelemetry 的协作

Pixie 提供 OTLP Exporter 相关能力(otel 插件及 px.export 接口),可以把 PxL 查询结果按 OpenTelemetry Metrics/Traces 协议发往外部后端。这样,Pixie 既可以作为独立观测平台使用,也可以作为 OpenTelemetry 生态里的”数据源”。

六、DeepFlow:国产开源的全栈网络可观测

DeepFlow 由云杉网络开源,是目前国内网络可观测领域最成熟的开源项目,在 CNCF Landscape 有登记。

6.1 项目定位

6.2 架构

+--------------------+             +--------------------+
|  deepflow-agent    |  gRPC(fb)   |  deepflow-server   |
|  (K8s DaemonSet) |<----------->|  (Go 集群服务)    |
|  - eBPF 采集        |             |  - 元数据同步        |
|  - AF_PACKET 采集   |             |  - 流 / 指标 / 跟踪   |
|  - L7 协议解析      |             |  - ClickHouse 写入    |
+--------------------+             +--------------------+
                                             ^
                                             | SQL
                                             v
                                       +-----------+
                                       | ClickHouse|
                                       +-----------+
                                             ^
                                             |
                                       +-----------+
                                       |  Grafana  |
                                       +-----------+

deepflow-agent 用 Rust 编写,eBPF 程序使用 CO-RE 形式分发。deepflow-server 用 Go 编写,存储基于 ClickHouse。Grafana 侧有官方的 DeepFlow 数据源插件,提供专用查询语言。

6.3 AutoTagging 与 AutoTracing

AutoTagging:agent 与 Kubernetes API、云平台 API 同步资源信息,给每条流/每条 L7 记录自动打上:

AutoTracing:在 eBPF 层采集 TCP socket 的五元组、L7 请求响应对,同时记录进程/线程上下文。当一个进程”收到请求 A 后发出请求 B”时,可以通过时间相邻、socket 关联、线程局部存储(TLS,Thread Local Storage)的令牌传递(如 HTTP 头里的 X-Request-ID)推断 A 与 B 的调用关系,从而构造无埋点的调用链。

对没有显式 Trace ID 的应用,这种启发式推断不是百分百精确,但在工程上可以覆盖 80% 的场景,对于老系统的”第一张调用图”非常有价值。

6.4 查询语言

DeepFlow 的数据存于 ClickHouse,提供专用的 SQL 扩展:

SELECT
  request_resource,
  response_code,
  countIf(response_code >= 400) AS err_count,
  quantileTDigest(0.99)(response_duration) AS p99_ms
FROM flow_log.l7_flow_log
WHERE time >= now() - INTERVAL 5 MINUTE
  AND l7_protocol = 'HTTP'
  AND pod_ns = 'order'
GROUP BY request_resource, response_code
ORDER BY err_count DESC
LIMIT 50;

Grafana 插件将这些语义化的维度暴露为下拉框,上手门槛比手写 SQL 低。

6.5 部署示例

# deepflow-values.yaml (Helm)
global:
  image:
    repository: registry.cn-beijing.aliyuncs.com/deepflow-ce
grafana:
  enabled: true
  service:
    type: NodePort
deepflow-agent:
  clusterNAME: prod-cluster
  updateStrategy:
    type: RollingUpdate
  resources:
    requests:
      cpu: 500m
      memory: 500Mi
    limits:
      cpu: 2
      memory: 2Gi
helm repo add deepflow https://deepflowio.github.io/deepflow
helm install deepflow -n deepflow --create-namespace \
  deepflow/deepflow -f deepflow-values.yaml

6.6 与 Pixie/Hubble 的对比

维度 Hubble Pixie DeepFlow
定位 Cilium 可观测层 通用 K8s 可观测 全栈(云 + 云原生)
是否绑 CNI 是(Cilium)
L7 协议覆盖 HTTP/DNS/Kafka 等 HTTP/DB/MQ 等较多 HTTP/DB/MQ/Dubbo 等最多
存储 节点内存 + 指标后端 节点内存(列式) ClickHouse(集中)
调用链 有限 基于 L7 事件 AutoTracing
自定义策略语言 PxL SQL
数据是否出集群 可选 默认不 集中存储
生态 CNCF Graduated 一部分 CNCF Sandbox CNCF Landscape(国产)
社区语言 英文 英文 中英双语,国内活跃

DeepFlow 的突出优势是”既做网络包又做 eBPF,L7 协议覆盖广”;劣势是相比 Hubble,与 Cilium 的策略联动不那么深。

七、网络性能监控(NPM)与应用性能监控(APM)的边界

7.1 两者的关注点差异

7.2 L7 上的重叠

当 NPM 深入到 L7(以本文讨论的 Hubble/Pixie/DeepFlow 为例),它开始能够看见:

这恰恰是 APM 的传统地盘。但两者的视角仍然不同:

7.3 互补的典型案例

场景一:NPM 能抓到,APM 抓不到。

场景二:APM 能抓到,NPM 抓不到。

7.4 工程落地建议

八、TLS / HTTP/2 解析

8.1 TLS 解密挑战

HTTPS、gRPC、TLS-over-MySQL 等加密协议占比越来越高。对基于网络层/传输层采集的可观测系统来说,这意味着如果不做特殊处理,只能看到密文流、统计流量大小与连接生命周期,拿不到 L7 语义。

常见解密路径有三种:

  1. 旁路 + 私钥:传统 DPI 方案。要求部署方提供服务端私钥,设备中间解密。问题:
    • 对前向保密(PFS,Perfect Forward Secrecy)套件不适用,因为密钥是会话级的;
    • 企业合规上很多场景不允许拿私钥出设备;
    • 无法解密客户端互相访问的互联网方向流量。
  2. uprobe 在 TLS 库:在 SSL_read/SSL_write(以及 Go crypto/tls、Node/Python ssl 等)函数入口/返回点采集明文缓冲区。这是 Pixie、DeepFlow、Hubble L7 HTTPS 的主流做法。关键点:
    • 不需要私钥,与 TLS 1.3 和 PFS 套件兼容;
    • 必须在应用进程内挂探针,这意味着要能访问到进程的 /proc/<pid>/root/<libpath>
    • 对静态链接的 Go 二进制尤其棘手,需要从 DWARF/pclntab 找符号偏移。
  3. 内核态 TLS(kTLS)+ eBPF:Linux 4.13 引入 kTLS,加密可下放到内核。对使用 kTLS 的工作负载,eBPF 可以在 kTLS 缓冲前后读到明文。主流 Web 服务器(Nginx 从 1.13.5 起,部分版本需编译参数)可开启 kTLS。

8.2 TLS 1.3 会话票据(Session Ticket)带来的影响

TLS 1.3 默认使用会话票据实现会话恢复,这意味着:

8.3 HTTP/2 连接复用问题

HTTP/2 在单条 TCP 连接上多路复用(Multiplexing)多个流(Stream),每个流用唯一的 Stream ID 标识。对协议解析器而言,这带来两个挑战:

  1. 一条 TCP 连接上会交织出现多个请求响应的二进制帧(HEADERS、DATA、WINDOW_UPDATE 等),解析器必须按 Stream ID 重组。
  2. 请求头使用 HPACK 压缩,需要维护连接级的动态表(dynamic table)。

在 eBPF 中完全实现 HPACK 解码并不现实(eBPF 指令数限制、无堆、无动态循环),主流做法:

这也是为什么 Pixie、DeepFlow 在用户态 Agent 占 CPU 不低:真正的协议解析成本都在那里。

8.4 gRPC over HTTP/2 的追踪

gRPC 使用 HTTP/2 作为传输,content-type 为 application/grpc,方法名放在 :path 伪头里(形如 /package.Service/Method),状态码在响应 Trailer 的 grpc-status 里。解析要点:

8.5 协议识别工程

对于”一个 socket 上跑的是什么协议”这个问题,常见识别策略:

  1. 基于端口的猜测:80 是 HTTP、6379 是 Redis。容器化环境下端口约定不可靠,只能作为候选。
  2. 基于首包指纹:HTTP 以 GETPOST 等方法开头;MySQL 以长度前缀 + 握手包;Redis 以 *<number>\r\n;Kafka 以 ApiKey。
  3. 失败回退:尝试多个解析器,若都失败则标为 unknown,避免误报。
  4. 状态机携带协议标签:识别成功后在 socket -> protocol 的 Map 中记录,后续跳过重复识别。

解析器本身要求:

九、服务拓扑自动发现

9.1 拓扑的价值

“这个系统里哪些服务在互相调用”,对新接手系统、对故障影响面分析、对安全基线审计,都是最先需要回答的问题。传统做法:

这些都难以跟上变化速度。基于网络流量自动发现服务拓扑,是网络可观测工具的天然能力。

9.2 聚合粒度

从原始流到服务拓扑图,需要多级聚合:

  1. 包级流级:将相同五元组(源 IP、源端口、目的 IP、目的端口、协议)的数据包聚合成一条流。
  2. 流级实例级:将 IP 映射为 Kubernetes Pod / 虚拟机实例。
  3. 实例级服务级:将 Pod 按 Workload、Service 聚合。
  4. 服务级应用级 / 域级:按业务线、命名空间、团队聚合。

每一级聚合都会失去细节,但对应不同的使用者:SRE 看应用级,开发看服务级,排障看实例级,取证看流级。

9.3 各工具的实现

9.4 Sidecar 场景

在 Istio / Linkerd 等基于 sidecar 的服务网格(Service Mesh)中,每个 Pod 旁边都有一个代理进程(Envoy / linkerd-proxy)。网络层看到的流量是:

app A -> envoy A -> envoy B -> app B

如果按 IP 聚合,会把 “app -> envoy” 的 127.0.0.1 回环流量与 “envoy -> envoy” 的跨节点流量都保留。拓扑图如果不做特殊处理,会出现大量”自己调自己”的边。

处理思路:

DeepFlow、Pixie、Hubble 都有针对 Istio 的”合并 sidecar”能力,但各家实现成熟度不同,部署前建议用灰度环境验证。

十、与 Service Mesh 的关系

10.1 Istio 与网络可观测性

Istio 基于 Envoy sidecar,天然会产生丰富的 L7 指标:

这些指标来自 Envoy 的 Prometheus 端点,经过 Istio 的 telemetry 配置塑形。也就是说:装了 Istio 并打开默认 telemetry,就已经有一套相当像样的 L7 观测数据了。

代价是 sidecar:每个 Pod 多出一个 Envoy 进程,资源占用(CPU 50m~200m、内存 50MiB~200MiB),延迟新增 1~3 毫秒。对大规模集群与对延迟敏感的负载,这是显著的成本。

eBPF 路径(Hubble/DeepFlow/Pixie)不需要 sidecar,资源开销通常只集中在 DaemonSet 上,但也有自己的代价:

所以现实中不少团队选择共用:Istio 负责服务治理与 L7 基线指标,Hubble/DeepFlow 负责网络层排障与安全。

10.2 Cilium Service Mesh

Cilium 提供了”无 sidecar”的服务网格方案:

优势:

劣势:

选型上:追求简洁、绝对性能、统一 eBPF 栈 → Cilium Service Mesh;需要复杂流量治理与成熟生态 → Istio。

十一、大流量下的工程挑战

11.1 内核环形缓冲区(Ring Buffer)溢出

eBPF 程序把事件送到用户态主要靠两种机制:

在大流量下,用户态消费速度跟不上内核生产速度,缓冲区会溢出,事件丢失。工程上常见应对:

11.2 采样策略

高吞吐链路上,采全量流日志既不经济也没必要。常见策略:

11.3 聚合 vs 原始流存储

对指标(计数、直方图)用 BPF Map 内聚合,仅周期性导出,可降低几个量级的数据量。对需要排障的原始事件,则必须尽量保全。工程上常用的分层策略:

11.4 L7 解析的 CPU 开销

一旦进入 HPACK 解码、MySQL 协议解码这些工作,CPU 开销会显著上升。经验数据(参考 Pixie/DeepFlow 官方测试):

生产部署一定要给 Agent 预留 CPU,并在高峰做压力测试。

11.5 连接跟踪内存

要把 TCP 连接的全生命周期串起来,必须维护一张”连接 -> 状态”的表。高峰时连接数可能达到百万级,相应 BPF Map 需要按连接条目大小 ×连接数做预留,常见配置:

超时清理策略:

十二、国内落地案例

12.1 DeepFlow 在国内运营商

云杉网络在电信、移动、联通的多个省级 IT 系统里都有 DeepFlow 部署案例,典型规模:

12.2 中国移动大规模 K8s 网络可观测

中国移动公有云 / 私有云的大规模 Kubernetes 平台(万级节点)在 2023~2024 年陆续把网络可观测栈从传统 NetFlow 迁移到 eBPF 方案:

12.3 腾讯云 TCOS / 自研 eBPF 栈

腾讯内部的容器平台(腾讯云操作系统 TCOS、TKE)在多个场景下使用 eBPF 做网络可观测:

公开资料上,腾讯 TKE 也提供”网络可观测”增值功能,底层是基于 eBPF 的流日志 + 服务拓扑。

12.4 金融行业的网络安全可观测

国内多家大型银行在生产网与开发测试网推行零信任改造,网络可观测是其中关键一环:

这里的工程挑战不是技术不够,而是合规与留痕要求极高,任何漏采都可能在监管检查中出问题。

十三、工程坑点

13.1 TLS 解密覆盖不全

13.2 HTTP/2 多路复用极端场景

13.3 高包速下的内核丢包

当单节点 PPS 超过 100 万级,即便 eBPF 程序很精简,perf_event 或 ringbuf 仍可能丢事件。判断方法:

应对:先在采集侧过滤(丢弃控制面流量、本地回环等),再上采样。

13.4 Hubble 数据量

默认 Hubble 仅在节点上保留最近几万条流事件(环形缓存)。要长期存储,需要:

忽略这一点的团队,事后排障时经常发现”事件已经被 Hubble 自己的环形缓存覆盖了”。

13.5 DeepFlow Agent 资源

DeepFlow agent 默认资源请求较低,但在高流量节点实际占用可能远超请求,触发 OOMKilled。部署清单务必:

13.6 Pixie 的 K8s 依赖

Pixie 不支持非 Kubernetes 部署。混合环境(Kubernetes + 虚拟机 + 裸机)下,Pixie 只能覆盖一部分。这类场景下,DeepFlow 通常是更好的选择。

13.7 各 Agent 时钟同步

流事件的时间戳来自节点本地时钟,多节点合并分析时,时钟偏差会导致拓扑边乱序、P99 计算不准。建议:

13.8 命名空间歧义

同名 Namespace(如多个集群都有 order 命名空间)聚合时会撞车。工程上建议:

13.9 BPF verifier 失败

eBPF 程序上线时会被内核验证器校验。大的 L7 解析程序经常撞上:

CO-RE 工具链可以缓解,但复杂协议解析仍然要尽量把工作推到用户态。

十四、选型建议与落地清单

14.1 选型决策矩阵

场景 推荐方案
纯 Kubernetes、已用 Cilium Hubble(可加 Tetragon 做安全)
纯 Kubernetes、未用 Cilium,业务协议丰富 Pixie 或 DeepFlow
混合云:Kubernetes + VM + 裸机 DeepFlow(双数据面原生支持)
强安全合规要求 Tetragon + Hubble + SIEM
需要深度调用链且不想改代码 DeepFlow AutoTracing 或 Pixie PxL
研发主导、看重 SQL/脚本能力 DeepFlow(ClickHouse 内 SQL)或 Pixie(PxL)
追求极简、想让 NPM 与服务网格合一 Cilium Service Mesh + Hubble

14.2 生产部署清单

以下清单可作为上线 checklist:

  1. 集群规模评估:节点数、单节点 PPS、连接数、QPS。
  2. 内核版本:目标 5.10+(CO-RE、ringbuf 更友好),至少 4.19。
  3. 部署架构:agent DaemonSet、中心聚合、数据源下游(Prometheus/ClickHouse)。
  4. 资源画像:每节点 agent CPU/内存 request/limit;中心服务 CPU/内存/磁盘。
  5. 数据保留:原始流日志 N 小时、指标 N 天、聚合 N 月。
  6. 采样策略:错误全采、成功按比例、连接级一致性。
  7. 元数据接入:Kubernetes API、云 API、CMDB(Configuration Management Database)。
  8. 协议覆盖:列出业务使用的协议,确认工具覆盖情况(HTTP/gRPC/MySQL/Redis 等)。
  9. TLS 覆盖:列出主要 TLS 实现(OpenSSL/Go/Java/Node),逐一验证 uprobe 能采到。
  10. Service Mesh 兼容:如有 Istio,验证 sidecar 聚合、避免重复计费。
  11. 告警与仪表盘:错误率、丢包率、重传率、agent 健康、buffer 丢事件率。
  12. 与 APM 联动:TraceID 注入与传递、跨数据源 Join 方案。
  13. 安全事件流:Tetragon/Falco 事件 → SIEM 链路是否畅通。
  14. 升级回滚:eBPF 程序升级的金丝雀策略、agent 灰度。
  15. 故障演练:人为注入丢包、重传、5xx、DNS 超时等场景,验证工具能发现。

14.3 常见反模式

十五、参考资料

  1. Cilium 官方文档,https://docs.cilium.io/
  2. Hubble 项目 GitHub,https://github.com/cilium/hubble
  3. Tetragon 官方文档,https://tetragon.io/
  4. Pixie 官方文档,https://docs.px.dev/
  5. Pixie 源码,https://github.com/pixie-io/pixie
  6. DeepFlow 开源文档,https://deepflow.io/docs/zh/
  7. DeepFlow 源码,https://github.com/deepflowio/deepflow
  8. Brendan Gregg,《BPF Performance Tools》,Addison-Wesley,2019。
  9. Linux 内核文档:BPF and XDP Reference Guide,https://docs.cilium.io/en/stable/bpf/
  10. Liz Rice,《Learning eBPF》,O’Reilly,2023。
  11. CNCF TAG Observability,《Observability Whitepaper》,https://github.com/cncf/tag-observability
  12. IETF RFC 7540,HTTP/2 协议规范。
  13. IETF RFC 8446,TLS 1.3 协议规范。
  14. Google,《gRPC Protocol》,https://grpc.io/docs/
  15. 云杉网络博客,《DeepFlow 架构解析》系列。
  16. Isovalent 博客,《Hubble: Network, Service & Security Observability for Kubernetes》。
  17. New Relic 博客,《Introducing Pixie: Instant Kubernetes Observability》。
  18. 中国移动研究院,《云原生网络可观测性白皮书》,2024。
  19. CNCF Landscape,Observability & Analysis / Network 分类。
  20. Linux kernel bpf 子系统源码:kernel/bpf/net/core/filter.c

上一篇eBPF 可观测性全景:bcc、bpftrace、libbpf 的工程路径

下一篇Continuous Profiling:Parca、Pyroscope、Grafana Beyla

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-22 · architecture / observability

持续性能分析(Continuous Profiling):Parca、Pyroscope、Grafana Beyla

深入剖析持续性能分析(Continuous Profiling)的原理、架构与落地实践,覆盖 Parca、Pyroscope、Grafana Beyla 三大主流方案,包含 eBPF 采样、符号解析、火焰图、差异分析以及字节跳动、美团的生产案例与工程坑点。

2026-04-22 · architecture / observability

可观测性工程

从 Metrics、Logs、Traces 到 Profiling、eBPF、OpenTelemetry 与 SLO 治理,面向中国工程团队的可观测性系统化手册。


By .