Files
cs-note/hhs/NETWORK/10-前沿与进阶/02-eBPF与ServiceMesh.md
T

297 lines
9.1 KiB
Markdown
Raw Normal View History

2026-05-24 11:42:38 +08:00
---
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 程序<br/>(C/BPF 汇编)"]
Map["bpf_map<br/>KV 存储<br/>hash/array/perf_event/..."]
Tool["bpftool<br/>BCC tools<br/>bpftrace"]
end
subgraph "内核态 (Kernel Space)"
Verifier["Verifier<br/>严格安全检查"]
JIT["JIT Compiler<br/>C → x86/arm/riscv 机器码"]
subgraph "Attachment Points"
KP["kprobe / kretprobe<br/>hook 任意内核函数入口/出口"]
TP["tracepoint<br/>内核预定义探测点"]
TC["Traffic Control<br/>qdisc classifier"]
XDP["XDP (eXpress Data Path)<br/>网卡驱动级别最快路径"]
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<br/>最快路径: 网卡驱动级别"]
TC["Traffic Control<br/>tc filter/qdisc"] -.->|中等路径| Stack["Linux Network Stack"]
Stack -.->|kprobe hook| Kprobe["kprobe/kretprobe<br/>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<br/>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 最常挂钩的地方