--- tags: [计算机网络, eBPF, XDP, kprobe, Tracepoint, ServiceMesh, Istio, Envoy] create time: 2026-05-18 05:30 --- # eBPF 与 Service Mesh ## 概述 eBPF 让 Linux 内核变得可编程而不需要编译内核模块;Service Mesh(Istio/Linkerd)让微服务间的流量治理从代码中剥离到基础设施层。这两者代表了可观测性和流量治理的两个重要方向。 ## eBPF(extended Berkeley Packet Filter) ### 什么是 eBPF? eBPF 允许在**内核态安全地运行沙箱程序**,无需修改内核源码或加载内核模块。它最初是一个 packet filter 增强版,现在已扩展到 tracing、monitoring、security 等多个领域。 ``` 传统方案: eBPF 方案: ───────── ───────── 编译内核模块 (.ko) ↔ 编写 eBPF C 程序 手动符号导出 ↔ kprobe/kfunc/tracepoint 直接挂钩 系统重启加载 ↔ insmod bpf 即时生效 无类型安全检查 ↔ 内核验证器严格检查 (verifier) 崩溃影响全局 ↔ 沙箱隔离,失败不崩内核 无法卸载或调试 ↔ 可卸载,bpftool 可调试 ``` ### eBPF 的核心架构 ```mermaid flowchart TD subgraph "用户态 (User Space)" Prog["eBPF 程序
(C/BPF 汇编)"] Map["bpf_map
KV 存储
hash/array/perf_event/..."] Tool["bpftool
BCC tools
bpftrace"] end subgraph "内核态 (Kernel Space)" Verifier["Verifier
严格安全检查"] JIT["JIT Compiler
C → x86/arm/riscv 机器码"] subgraph "Attachment Points" KP["kprobe / kretprobe
hook 任意内核函数入口/出口"] TP["tracepoint
内核预定义探测点"] TC["Traffic Control
qdisc classifier"] XDP["XDP (eXpress Data Path)
网卡驱动级别最快路径"] end Map -->|"写入"| PerfEvent["perf event → 用户态采集"] end Tool -->|"加载"| Prog Prog -->|"提交"| Verifier Verifier -->|"验证通过"| JIT JIT -->|"注册到"| KP JIT -->|"注册到"| TP JIT -->|"注册到"| TC JIT -->|"注册到"| XDP ``` ### eBPF 在网络中的典型应用层级 ```mermaid flowchart LR NIC["Network Interface Card"] -.->|XDP 微秒级处理| XDP["XDP
最快路径: 网卡驱动级别"] TC["Traffic Control
tc filter/qdisc"] -.->|中等路径| Stack["Linux Network Stack"] Stack -.->|kprobe hook| Kprobe["kprobe/kretprobe
TCP/IP 栈钩子"] XDP -->|"drop/mirror/redirect"| NIC TC -->|"police/packet/cgroup"| Stack Kprobe -->|"tcp_connect/tcp_rcv_skb..."| App["可观测性工具"] style XDP fill:#FF6B6B,color:#fff style TC fill:#FFD700,color:#000 style Kprobe fill:#98FB98,color:#000 ``` | 挂载点 | 性能 | 用途 | 典型工具 | |--------|------|------|---------| | **XDP** | 微秒级,最快 | DDoS 过滤、L4 LB、镜像 | AF_XDP, cilium-hubble | | **tc (Traffic Control)** | 纳秒~微秒级 | qdisc 调度、带宽限制、重定向 | tc-bpf, polycube | | **kprobe/kretprobe** | 低开销 | 追踪任意内核函数 | bcc tcpconnect, bpftrace | | **tracepoint** | 极低开销 | 内核预定义事件 | perf trace | | **CGroup** | 进程级 | 网络隔离、限速 | cgroup-bpf | | **LSM** | 安全级别 | 强制访问控制 | libbpf-security | ### 常用 eBPF 工具实战 ```bash # === BCC Tools (Python-based eBPF 工具集) === # 追踪所有新建 TCP 连接 sudo ./tcpconnect PID COMM IP SADDR DADDR DPORT 1234 curl 4 192.168.1.10 93.184.216.34 443 # 查看 TCP 连接存活时间 sudo ./tcplife PID COMM FD LADDR:LADDR → RADDR:RADDR state msec 1234 chrome 42 192.168.1.10:54321→ 93.184.216.34:443 ESTAB 12345 # 查看 TCP 状态分布 sudo ./tcpstates Tracing TCP states... Output every 1 seconds. TIME_WAIT 42 ESTABLISHED 128 CLOSE_WAIT 0 # === bpftrace (一行脚本) === # 实时打印每个 TCP 包的大小 sudo bpftrace -e 'kprobe:tcp_sendmsg { @bytes[tid] = arg0; }' # 统计每秒 DNS 查询数 sudo bpftrace -e 'tracepoint:dns:dns_query { @count++; } interval:s:1 { print(@count); clear(@count); }' # === Cilium Hubble (Kubernetes 可观测性) === # 服务间流量可视化 hubble observe --namespace=default FLOW 08:23:45.123 DefaultPod → api-server (TCP NEW) DPT=8080 FLOW 08:23:45.125 api-server → DefaultPod (TCP FIN) # 按命名空间聚合 hubble observe --aggregate 5s ``` ### eBPF 监控网络问题的经典场景 ```bash # 场景 1: 哪个进程的 TCP 连接最多? sudo bpftrace -e ' kprobe:sock_alloc /@pids[comm]/++ ' # 场景 2: 慢连接诊断——每个 TCP 连接耗时多久? sudo bpftrace -e ' kprobe:tcp_v4_connect /arg0/ { @start[tid] = nsecs; } kretprobe:tcp_v4_connect /arg0 >= 0/ { $delta = (nsecs - @start[tid]) / 1000; @latency_us = hist($delta); delete(@start[tid]); }' # 场景 3: SYN Flood 检测 sudo bpftrace -e ' kprobe:tcp_v4_do_rcvd @syn_count["SYN_RECV"]++; interval:1s { print(@syn_count); clear(@syn_count); }' ``` ## Service Mesh (Istio / Linkerd) ### Sidecar 模式原理 ```mermaid flowchart LR Pod["Pod / VM"] -->|"app container"| App["my-service v1"] Pod -->|"proxy container"| Proxy["envoy sidecar"] Proxy -->|"xDS API"| CP["Istiod
Pilot(路由) + Citadel(mTLS)"] CP -->|"推送配置"| Proxy subgraph "Sidecar 自动接管:" MTLS["mTLS 双向认证"] Retry["重试/熔断/超时"] Tracing["分布式链路追踪 (Jaeger)"] Metrics["指标收集 (Prometheus)"] Canary["金丝雀/蓝绿发布"] Dashboard["流量仪表盘"] end Proxy -.-> MTLS Proxy -.-> Retry Proxy -.-> Tracing Proxy -.-> Metrics Proxy -.-> Canary Proxy -.-> Dashboard style Proxy fill:#DDA0DD,color:#000 style CP fill:#FFD700,color:#000 ``` ### Istio Traffic Management 核心资源 ```yaml # VirtualService: 路由规则 apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: my-service spec: hosts: ["my-service.default.svc.cluster.local"] http: - match: - headers: x-canary: {exact: "true"} route: - destination: {host: my-service, subset: v2} # canary 版 weight: 100 - route: - destination: {host: my-service, subset: v1} weight: 90 # 正式版 90% - destination: {host: my-service, subset: v2} weight: 10 # 金丝雀 10% timeout: 5s # 超时控制 retries: # 重试策略 attempts: 3 perTryTimeout: 2s retryOn: "5xx,reset,connect-failure,gateway-error" # DestinationRule: 定义 subset (版本分组) apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: my-service spec: host: my-service.default.svc.cluster.local trafficPolicy: tls: mode: ISTIO_MUTUAL # 自动 mTLS connectionPool: tcp: maxConnections: 100 # 连接池上限 http: h2UpgradePolicy: DEFAULT # 升级到 HTTP/2 http1MaxPendingRequests: 100 http2MaxRequests: 1000 subsets: - name: v1 # 打标签为 v1 labels: {app-version: v1} - name: v2 # 打标签为 v2 labels: {app-version: v2} # Gateway: 入站流量入口 apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: my-gateway spec: selector: {istio: ingressgateway} servers: - port: {number: 443, name: https, protocol: HTTPS} tls: {mode: SIMPLE, credentialName: my-cert} hosts: ["api.example.com"] ``` ### Istio 工作原理 ``` 开发者视角: ────────────── 我的代码完全不知道 Service Mesh 的存在! 不需要引入任何 SDK、注解或配置。 流量全部被 envoy sidecar 拦截和转发。 运维视角: ────────────── Istiod (control plane) 统一管理所有 envoy proxy ↓ 通过 xDS API (CDS/EDS/LDS/RDS) 推送路由规则、监听配置、集群发现给每个 sidecar ↓ sidecar 热更新配置,无需重启应用 ``` ```bash # 确认 sidecar 注入成功 kubectl get pods -n default NAME READY STATUS my-service-abc123-xk9qp 2/2 Running ← 2/2 = app + envoy sidecar # 检查 envoy 配置 kubectl exec -it my-service-abc123-xk9qp -c envoy -- \ envoy --admin-address-port localhost:15000 stats # istioctl 诊断 istioctl analyze # 分析配置正确性 istioctl proxy-status # sidecar 同步状态 istioctl proxy-config routes my-service-pod # 查看某 pod 的路由表 ``` ## 关联笔记 - [[hhs/NETWORK/QUIC协议深度解析]] — QUIC 也是用户态实现的协议 - [[hhs/NETWORK/WireGuardVPN原理与实践]] — WireGuard 同样在内核态运行 - [[hhs/NETWORK/01-SocketAPI与backlog详解]] — Socket API 是 eBPF kprobe 最常挂钩的地方