饮墨

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

Kubeshark 实战:基于 eBPF 的 Kubernetes 集群实时流量抓包与分析

9 views

痛点:K8s 网络排障为什么这么难

Kubernetes 集群里微服务之间的调用链路错综复杂,一旦出现 5xx 错误、接口超时或数据不一致,传统排查手段几乎寸步难行:

  • tcpdump 抓不到:Pod 网络经过 CNI 虚拟化,你在 Node 上抓包看到的是 VXLAN/Geneve 封装后的数据,根本无法直接解析 HTTP 请求
  • kubectl logs 不够:日志只记录了应用自己打印的内容,中间件调用、DNS 解析、TLS 握手这些关键环节完全是黑盒
  • Istio/Envoy sidecar 太重:为了看流量装一套 Service Mesh,资源开销和运维复杂度直接翻倍
  • 临时 debug 容器有局限:kubectl debug 进去后只能看单个 Pod,无法跨服务关联

运维需要的是一个轻量级、全集群、实时可查的网络抓包工具。Kubeshark 正是为此而生。

方案:Kubeshark 是什么

Kubeshark 是一款基于 eBPF 的 Kubernetes 网络可观测工具(Apache-2.0 开源),可以理解为 "Kubernetes 版的 Wireshark"。核心能力:

能力 说明
内核级抓包 通过 eBPF 在内核层拦截流量,零侵入、无需 sidecar
L7 协议解析 自动解析 HTTP、gRPC、GraphQL、Redis、Kafka、DNS 等协议
TLS 自动解密 基于 eBPF 挂钩 SSL 库,无需证书、无需密钥管理即可看到明文
KFL 查询语言 类 CEL 语法的过滤语言,支持 Kubernetes 语义(Pod 名、Namespace、Label)+ API 语义(HTTP 方法、状态码)+ 网络语义(IP、端口)三层联合查询
服务拓扑图 自动生成服务间调用关系、流量占比、协议分布的可视化地图
PCAP 导出 支持按时间段、Workload、IP 维度导出 PCAP 文件,可用 Wireshark 离线分析
AI 集成 提供 MCP Server,支持 AI Agent 用自然语言查询流量数据

与同类工具对比:

维度 tcpdump Istio Kiali Kubeshark
部署复杂度 低(但无 K8s 语义) 高(需整套 Mesh) 低(一行 Helm)
L7 解析 需手动解码 仅 HTTP/gRPC 多协议自动解析
TLS 解密 需要密钥 Sidecar 自动处理 eBPF 自动解密
资源开销 几乎无 高(每 Pod 一个 sidecar) 每 Node 一个 DaemonSet Pod
全集群视图 无 有 有

实操:3 步部署 Kubeshark 并开始抓包

第 1 步:Helm 部署

# 添加 Helm 仓库
helm repo add kubeshark https://helm.kubeshark.com
helm repo update

# 安装到独立 namespace
helm install kubeshark kubeshark/kubeshark \
  --namespace kubeshark \
  --create-namespace \
  --set tap.resources.worker.limits.memory=512Mi \
  --set tap.resources.worker.limits.cpu=500m

验证部署状态:

kubectl -n kubeshark get pods
# 预期输出:每个 Node 一个 worker Pod + 一个 hub Pod + 一个 front Pod
# NAME                              READY   STATUS    RESTARTS
# kubeshark-hub-xxx                 1/1     Running   0
# kubeshark-front-xxx               1/1     Running   0
# kubeshark-worker-xxxxx            1/1     Running   0   (每节点一个)

第 2 步:访问 Dashboard

# 开发环境用 port-forward
kubectl -n kubeshark port-forward svc/kubeshark-front 8899:80

# 生产环境推荐配置 Ingress
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubeshark
  namespace: kubeshark
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: kubeshark-basic-auth
spec:
  ingressClassName: nginx
  rules:
  - host: kubeshark.internal.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubeshark-front
            port:
              number: 80
EOF

打开 http://localhost:8899,即可看到实时流量面板。

第 3 步:用 KFL 精准过滤流量

KFL(Kubeshark Filter Language)是 Kubeshark 的核心查询语言,支持三层语义联合过滤:

# 查看 payment namespace 下所有 5xx 错误
http and response.status >= 500 and dst.namespace == "payment"

# 抓取指定 Pod 的 Redis 调用,且响应时间 > 100ms
redis and src.pod.name == "order-service-xxx" and response.time > 100

# 查看所有 gRPC 调用中的特定方法
grpc and request.path == "/api.OrderService/CreateOrder"

# DNS 解析排查:查看解析失败的 DNS 请求
dns and response.code != 0

# 组合查询:特定 Label 的 Pod 发出的慢请求
http and src.pod.labels["app"] == "checkout" and response.time > 500

实战场景:用 Kubeshark 定位跨服务超时

真实案例:某电商平台下单接口 P99 延迟从 200ms 飙升到 3s,但 order-service 自身日志显示处理时间正常。

排查步骤:

# 1. 过滤 order-service 的所有出站 HTTP 调用
http and src.pod.labels["app"] == "order-service"

# 2. 在 Dashboard 按 response.time 降序排列,发现对 inventory-service 的调用耗时 2.8s

# 3. 进一步追踪 inventory-service 的出站流量
http and src.pod.labels["app"] == "inventory-service"

# 4. 发现 inventory-service 对 Redis 的调用出现大量超时
redis and src.pod.labels["app"] == "inventory-service" and response.time > 1000

最终定位:inventory-service 连接的 Redis 集群因内存碎片导致 used_memory_rss 远超 used_memory,触发了 swap,根因是未配置 activedefrag yes。

关键点:如果没有 Kubeshark,你需要逐个服务加日志、逐段抓包,这个排查链至少需要 2-3 小时。用 KFL 过滤,5 分钟锁定根因。

避坑指南

坑 1:生产环境内存失控

Kubeshark worker 默认会缓存大量流量数据。大流量集群若不限制资源,worker Pod 内存可能飙到几个 GB。

# values.yaml 关键配置
tap:
  resources:
    worker:
      limits:
        memory: 512Mi   # 根据集群流量调整
        cpu: 500m
  storagelimit: 500Mi    # 限制本地缓存大小
  # 只抓特定 namespace,避免全集群抓包
  namespaces:
    - production
    - staging

坑 2:eBPF 内核版本兼容

Kubeshark 的 eBPF 特性(尤其是 TLS 解密)要求 Linux 内核 ≥ 4.16,推荐 5.8+。如果你的 Node 还在跑老内核:

# 检查内核版本
uname -r

# 如果低于 4.16,TLS 解密功能不可用
# 可通过 Helm 禁用 eBPF TLS 挂钩
helm upgrade kubeshark kubeshark/kubeshark \
  --set tap.tls=false

坑 3:PCAP 导出文件过大

集群级别的 PCAP 很容易到 GB 级别。导出时务必用 KFL 过滤 + 时间窗口限制:

# 在 Dashboard 中设置过滤条件和时间范围后再导出
# 或使用 Kubeshark CLI
kubeshark tap --filter "http and response.status >= 500" \
  --set tap.storagelimit=200Mi

导出的 PCAP 建议上传到 S3/GCS/Azure Blob 做长期存档,Kubeshark 原生支持云存储集成。

总结

要点 建议
部署 Helm 一行安装,生产环境配 Ingress + Basic Auth
资源控制 限制 worker 内存/CPU,按 Namespace 过滤,设 storagelimit
排障核心 掌握 KFL 三层语义(K8s + API + Network)联合查询
TLS 解密 内核 5.8+ 开箱即用,低版本可降级关闭
长期存档 PCAP 快照导出到云存储,配合 Wireshark 离线分析

Kubeshark 填补了 Kubernetes 网络可观测的关键空白——在 Service Mesh 太重、tcpdump 太原始之间,提供了一个恰到好处的中间方案。尤其是 eBPF 免密钥 TLS 解密能力,让你在不改动任何业务代码的前提下,看到全集群的明文流量。对于微服务架构下的 API 排障、安全审计和性能分析,这是目前最轻量的生产级方案。

分享:

相关文章