This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
all-in-kingsoft/hhs/NETWORK/10-前沿与进阶/02-eBPF与ServiceMesh.md
T
2026-05-17 22:27:07 +08:00

9.1 KiB
Raw Blame History

tags, create time
tags create time
计算机网络
eBPF
XDP
kprobe
Tracepoint
ServiceMesh
Istio
Envoy
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 的核心架构

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 在网络中的典型应用层级

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 工具实战

# === 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 监控网络问题的经典场景

# 场景 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 模式原理

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 核心资源

# 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 热更新配置,无需重启应用
# 确认 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 的路由表

关联笔记