饮墨

子安饮墨馀三斗,留与卿儿作赋来

eBPF 正在重塑 Kubernetes 可观测性:从内核追踪到零侵入监控实战

传统 Kubernetes 监控靠 Sidecar 注入、应用埋点、日志采集三板斧。但 Sidecar 吃资源、埋点改代码、日志延迟高——能不能不改一行应用代码,直接从内核层拿到网络延迟、系统调用、DNS 解析全链路数据?eBPF 给出了答案。


痛点:K8s 可观测性的三个老大难

  1. Sidecar 资源开销大——Istio Envoy sidecar 每个 Pod 占 50-100MB 内存,千级 Pod 集群光 sidecar 就吃掉几十 GB
  2. 应用埋点侵入性强——接入 OpenTelemetry SDK 要改代码、重新构建镜像,老系统改不动
  3. 网络层问题难定位——Pod 之间延迟高,kubectl logs 看不出原因,tcpdump 在容器网络里抓包又复杂

eBPF(extended Berkeley Packet Filter)直接在 Linux 内核里运行沙盒程序,不改应用、不加 Sidecar,就能采集 L3/L4/L7 网络流量、系统调用、文件 IO 等数据。2026 年,Cilium、Tetragon、Pixie 等工具已经让 eBPF 在 K8s 场景落了地。


方案概览

本文用 Cilium + Hubble 组合实操,覆盖三个核心场景:

  • 网络流量可视化(替代 Sidecar 级别的流量监控)
  • 零侵入的 HTTP/gRPC 黄金指标采集
  • DNS 解析异常自动检测

实操步骤

Step 1:安装 Cilium 作为 CNI(替换默认网络插件)

# 前提:K8s 集群已就绪,kubectl 可用
# 安装 Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --fail https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz \
  | sudo tar xz -C /usr/local/bin

# 安装 Cilium(启用 Hubble 可观测层)
cilium install --version 1.16.5 \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --set hubble.metrics.enableOpenMetrics=true \
  --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload}"

# 验证安装
cilium status --wait

Step 2:用 Hubble 观测 Pod 间流量

# 安装 Hubble CLI
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/main/stable.txt)
curl -L --fail https://github.com/cilium/hubble/releases/download/${HUBBLE_VERSION}/hubble-linux-amd64.tar.gz \
  | sudo tar xz -C /usr/local/bin

# 端口转发 Hubble Relay
cilium hubble port-forward &

# 实时观测 default 命名空间的所有流量
hubble observe --namespace default --follow

# 只看被 DROP 的流量(排查网络策略问题)
hubble observe --namespace default --verdict DROPPED

# 过滤 HTTP 流量,查看请求延迟
hubble observe --namespace default --protocol http --output json | \
  jq '{src: .source.labels, dst: .destination.labels, latency: .l7.latency_ns, status: .l7.http.code}'

效果: 不用进容器、不装 sidecar,直接看到哪个 Pod 在跟谁通信、延迟多少、有没有被 NetworkPolicy 拦截。

Step 3:Hubble Metrics 对接 Prometheus + Grafana

Hubble 自动暴露 Prometheus 格式的指标,直接刮取:

# prometheus-scrape-config.yaml(添加到 Prometheus 配置)
scrape_configs:
  - job_name: 'hubble'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_k8s_app]
        regex: hubble
        action: keep
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: (.+)
        replacement: ${1}:9965

核心指标(Grafana Dashboard 重点关注):

# HTTP 请求速率(按服务拆分)
sum(rate(hubble_http_requests_total{destination_workload!=""}[5m])) by (destination_workload, http_status)

# HTTP 请求延迟 P99
histogram_quantile(0.99, sum(rate(hubble_http_request_duration_seconds_bucket[5m])) by (le, destination_workload))

# DNS 解析失败率
sum(rate(hubble_dns_responses_total{rcode!="No Error"}[5m])) by (source_workload, rcode)
  /
sum(rate(hubble_dns_responses_total[5m])) by (source_workload, rcode)

# TCP 连接重置率(排查连接异常)
sum(rate(hubble_tcp_flags_total{flag="RST"}[5m])) by (source_workload, destination_workload)

Step 4:用 Tetragon 追踪安全敏感的系统调用

Cilium Tetragon 是 eBPF 安全可观测性工具,能追踪进程级行为:

# 安装 Tetragon
helm repo add cilium https://helm.cilium.io
helm install tetragon cilium/tetragon -n kube-system

# 查看容器内的敏感文件访问
kubectl exec -n kube-system ds/tetragon -c tetragon -- \
  tetra getevents --namespace default -o compact | \
  grep -E "open|write|exec"

运维价值: 容器里有人执行了 curl 下载可疑文件?Tetragon 实时告诉你进程名、PID、参数、调用栈——不用进容器排查。


避坑指南

坑 1:eBPF 程序的内核版本依赖

Cilium 要求 Linux Kernel ≥ 4.19,完整 L7 可观测性需要 ≥ 5.10。解法: 部署前检查 uname -r,EKS/GKE 默认内核版本通常满足,自建集群注意升级。

# 检查内核是否支持 eBPF
uname -r  # 需要 >= 5.10
bpftool feature probe | grep "map_type\|program_type" | wc -l  # 越多越好

坑 2:Hubble Metrics 基数爆炸

开启所有 label(source_ip, destination_ip)会导致 Prometheus 时间序列爆炸。解法: 只保留 workload 级别的 label,在 Cilium Helm values 里限制 labelsContext

hubble:
  metrics:
    enabled:
      - "httpV2:labelsContext=source_namespace,destination_namespace,destination_workload"
      # 不要加 source_ip, destination_ip

坑 3:与现有 CNI 冲突

Cilium 作为 CNI 会替换现有的 Flannel/Calico。不想换 CNI?可以用 Cilium CNI Chaining 模式或独立部署 Hubble(有限功能)。


总结

传统方案 eBPF 方案 优势
Sidecar 代理(Envoy) Cilium + Hubble 零 Sidecar,节省 50%+ 内存
应用埋点(OTel SDK) eBPF L7 自动采集 不改代码,即插即用
tcpdump 手动抓包 Hubble observe 实时流过滤,结构化输出
auditd 审计日志 Tetragon 进程级追踪,延迟更低

落地建议: 新集群直接用 Cilium 作 CNI + Hubble 做可观测,老集群先在测试环境跑一轮兼容性验证。eBPF 不是银弹,但在 K8s 网络可观测性这个领域,它已经是 2026 年的最优解。

您还没有登录,请登录后发表评论。