基于 eBPF 的网络问题分析实战:kyanos 从流量抓取到内核级时延定位完整指南

发布时间:2026/9/18 20:40:23
基于 eBPF 的网络问题分析实战:kyanos 从流量抓取到内核级时延定位完整指南 基于 eBPF 的网络问题分析实战kyanos 从流量抓取到内核级时延定位完整指南【免费下载链接】kyanosKyanos is a networking analysis tool using eBPF. It can visualize the time packets spend in the kernel, capture requests/responses, makes troubleshooting more efficient.项目地址: https://gitcode.com/GitHub_Trending/ky/kyanos导读kyanos 是一款基于 eBPF 的网络问题分析工具它把传统抓包tcpdump Wireshark耗时费力的排查流程压缩成一条命令既能按进程/容器/协议字段精确过滤并捕获 HTTP、Redis、MySQL、Kafka、MongoDB、RocketMQ、DNS 请求又能直接看到数据包在内核中各节点网卡、Socket 缓冲区、进程的耗时分布还支持对海量请求做多维聚合统计stat与单命令外部依赖总览overview。读完本文你将掌握 kyanos 的安装、三大子命令的完整用法、全部过滤选项以及从源码层面理解其时延指标与数据通路的实现原理。kyanos 是什么kyanos 是一个基于 eBPF 的网络流量分析工具能够实时捕获主机的入站与出站流量并自动解析为「请求-响应」记录。它覆盖了 HTTP、Redis、MySQL、RocketMQ、Kafka、MongoDB、DNS 七类常见协议协议解析器位于 agent/protocol 目录从protocol.go、http.go、redis..go等文件可看到每个协议的解析与过滤实现。围绕「快速定位网络问题」这一目标README 与 docs/what-is-kyanos.md 给出了 kyanos 的五大核心能力强大的流量过滤除传统的 IP/端口过滤外还支持按进程/容器、L7 协议信息、请求/响应字节大小、时延等维度过滤# 按 PID 过滤 ./kyanos watch --pids 1234 # 按容器 ID 过滤 ./kyanos watch --container-id abc # 按 Redis key 过滤 ./kyanos watch redis --keys my-key1,my-key2 # 按响应字节大小过滤 ./kyanos watch --resp-size 10000高级聚合分析能力与 tcpdump 只能做细粒度抓包不同kyanos 支持把捕获的请求跨多种维度做指标聚合快速给出排查最需要的结论。例如 HTTP 服务带宽突然被打满时一条kyanos stat http --bigresp就能找出向哪些远端 IP 发送了最大的响应体并查看具体请求与响应指标。内核级时延细节kyanos 能提供从请求/响应到达网卡、进入内核 Socket 缓冲区、再到应用进程读到的全过程内核埋点以可视化方式展示精确定位到底哪个阶段产生了延迟。从源码结构看这类「节点耗时」由 agent/analysis/stat.go 中的事件归集逻辑syscall 事件、网卡事件、Socket 事件计算得出。轻量无依赖几乎零依赖——单个二进制文件、一条命令所有结果直接在命令行终端展示。自动 SSL 流量解密捕获到的请求与响应均以明文呈现SSL 层探测逻辑见 agent/uprobe 与 bpf 目录下的gotls.bpf.c、各 openssl 版本探针。为什么不用 tcpdump传统抓包排查存在几个明显痛点见 docs/what-is-kyanos.md难以按协议信息过滤例如按特定 HTTP path 抓包很困难通常要 Wireshark/tshark 二次过滤难以按进程/容器过滤单机部署多个进程或容器时无法只抓某个进程/容器的包排查效率低生产环境 tcpdump 抓包生成 pcap、再下载到本地用 Wireshark 分析耗时巨大分析能力有限iftop、netstat 等传统监控工具粒度太粗难以定位根因无法分析加密流量SSL 等加密协议无法直接看到明文。kyanos 正是针对上述场景设计过滤能力强、秒级出结论、命令行直接呈现结果。环境要求与安装内核与架构要求kyanos 基于 eBPF 工作对内核版本有明确要求详见 docs/quickstart.mdamd643.x需 3.10.0-957 及以上4.x需 4.14 及以上5.x、6.x完全支持arm64需 5.5 及以上。可用uname -r查看当前内核版本。从 bpf/custom-archive 目录可看到项目为 CentOS 7/8、Ubuntu 18.04/20.04 的大量历史内核版本预置了 BTF 文件用于在低版本内核上启动 kyanos。下载与运行从 release 页面下载与 amd64/arm64 架构兼容的静态链接二进制tar xvf kyanos_vx.x.x_linux_amd64.tar.gz然后以root 权限运行sudo ./kyanos watch如果出现如下表格界面说明 kyanos 已成功启动权限检查kyanos 对运行权限有硬性要求。从 agent/agent.go 的启动逻辑SetupAgent可以看到启动时会依次检查内核是否启用了 BPFcommon.IsEnableBPF()进程是否具备CAP_BPF能力ac.HasPermission()不具备时会提示 Kyanos requires CAP_BPF to run. Please run kyanos with sudo or run container in privilege mode终端是否支持 256 色不支持时 UI 可能显示异常。因此生产环境建议以sudo运行容器内则需以特权模式运行。watch 命令抓取请求-响应与时延详情watch是 kyanos 最核心的子命令负责按指定条件捕获网络流量并解析为请求-响应记录。最简用法捕获当前支持的所有协议流量sudo ./kyanos watch执行后看到的是实时刷新的表格见 docs/watch.md列名说明示例id表格中的序号—Connection该请求-响应所属的连接10.0.4.9:44526 169.254.0.4:80Proto协议类型HTTPTotalTime请求-响应总耗时毫秒—ReqSize请求大小字节—RespSize响应大小字节—Net/Internal作为客户端发送时为网络时延作为服务端接收时为内部处理时间—ReadSocketTime客户端从 Socket 缓冲区读取响应的时间服务端则为从缓冲区读取请求的时间—交互方式按数字键对列排序用↑/↓或k/j上下移动浏览记录按Enter进入某条记录的详情视图。默认情况下 watch 最多收集 100 条请求-响应记录可用--max-records调整该默认值在 cmd/watch.go 中定义watchCmd.PersistentFlags().IntVar(maxRecords, max-records, 100, ...)。详情视图Latency Details按Enter进入详情页后第一部分是时延详情Latency Details。每个色块代表数据包经过的一个「节点」——例如进程、网卡、Socket 缓冲区色块下方的时延值表示从前一个节点到当前节点所花费的时间。你可以清晰地看到请求从进程发出到网卡、响应从网卡复制到 Socket 缓冲区、再被进程读取的完整过程以及每一步的耗时如果希望进一步看到网卡到 TCP 缓冲区复制以及缓冲区到进程读取两个环节的时延可以给 watch 加上--trace-socket-event选项时延图中会多出一个 Socket 节点。对应的 Socket 层事件采集开关定义在 cmd/watch.go--trace-socket-event默认关闭而--trace-dev-event默认开启。第二部分是请求与响应的基本信息包括请求和响应的起止时间、大小等。第三部分是请求与响应的具体内容分 Request 与 Response 两段展示。内容超过1024字节会被截断显示可通过--max-print-bytes调整上限。如何过滤请求与响应默认情况下 kyanos 捕获所有已支持协议的流量但实际场景往往需要更精确的过滤。kyanos 的过滤体系分为四层详见 docs/watch.md 的 How to Filter 章节并且stat命令支持 watch 的全部过滤选项。按 IP 和端口过滤L3/L4 层过滤条件命令行参数示例本地连接端口local-ports--local-ports 6379,16379只观察本地 6379、16379 端口上的请求-响应远端连接端口remote-ports--remote-ports 6379,16379只观察远端 6379、16379 端口上的请求-响应远端 IP 地址remote-ips--remote-ips 10.0.4.5,10.0.4.2只观察来自这些远端 IP 的请求-响应客户端/服务端side--side client/server只观察作为客户端发起连接或作为服务端接收连接时的请求-响应这些全局过滤参数在 cmd/root.go 中通过rootCmd.PersistentFlags()注册--pids、--comm、--remote-ports、--local-ports、--remote-ips等因此对watch、stat、overview全部子命令生效。按进程/容器过滤过滤条件命令行参数示例进程 PID 列表pids--pids 12345,12346多个 PID 用逗号分隔进程名comm--comm curl容器 IDcontainer-id--container-id xx容器名container-name--container-name foobarKubernetes Pod 名pod-name--pod-name nginx-7bds23212-23s1s.default格式为NAME.NAMESPACE关于容器/K8s 过滤agent/common/options.go 提供了佐证FilterByContainer()判断ContainerId/ContainerName/PodName是否非空getPodNameFilter()会把NAME.NAMESPACE拆分容器运行时端点分别支持 Docker默认unix:///var/run/docker.sock、containerd默认/run/containerd/containerd.sock以及 CRI runtime默认按候选端点逐个探测。值得一提的是kyanos 还会展示容器网卡与宿主机网卡之间的时延即timedetail.jpg中的可视化效果。按请求-响应通用信息过滤过滤条件命令行参数示例请求-响应时延latency--latency 100只观察时延超过 100ms 的请求-响应请求大小字节req-size--req-size 1024只观察请求大于 1024 字节的记录响应大小字节resp-size--resp-size 1024只观察响应大于 1024 字节的记录从 cmd/common.go 的initLatencyFilter/initSizeFilter可以看到--latency被解析为protocol.LatencyFilter{MinLatency}--req-size/--resp-size被解析为protocol.SizeFilter{MinReqSize, MinRespSize}——即这三个参数都是「下限」过滤语义。按协议特定信息过滤把协议名作为子命令即可只捕获该协议的流量当前支持的协议为http、redis、mysql、rocketmq、kafka、mongodb、dns完整列表见 cmd/watch.go 中的supportedProtocols。例如只捕获 path 为/foo/bar的 HTTP 请求kyanos watch http --path /foo/barHTTP 协议过滤参数解析见 cmd/http.go最终组装为protocol.HttpFilter过滤条件命令行参数示例请求路径path--path /foo/bar只观察 path 为/foo/bar的请求请求路径前缀path-prefix--path-prefix /foo/bar只观察以/foo/bar开头的路径请求路径正则path-regex--path-regex \/foo\/bar\/.*只观察匹配该正则的路径请求 Hosthost--host www.baidu.com只观察 Host 为www.baidu.com的请求请求方法method--method GET只观察 GET 方法注意 cmd/http.go 中说明多个过滤 flag 之间是AND与关系--path-regex会在 Go 层用regexp.Compile预编译非法正则直接报错退出。Redis 协议过滤见 cmd/redis.go组装为protocol.RedisFilter过滤条件命令行参数示例请求命令command--command GET,SET只观察 GET 和 SET 命令请求 keykeys--keys foo,bar只观察 key 为foo、bar的请求key 前缀key-prefix--key-prefix foo:bar只观察 key 以foo:bar开头的请求RocketMQ 协议过滤预览见 cmd/rocketmq.go过滤条件命令行参数示例请求 coderequest-codes--request-codes 10,11只观察 code 为 10、11 的请求语言languages--languages Java,Go只观察 Java、Go 应用发出的请求Kafka 协议过滤预览见 cmd/kafka.go组装为kafka.NewKafkaFilter(apikeys, topic, producer, consumer)过滤条件命令行参数示例Topic 名topic--topic quickstart-events生产者producer--producer观察生产者请求指定 topic 时默认为 true消费者consumer--consumer观察消费者Fetch请求默认 trueAPI Keysapikeys--apikeys 10,11只观察 Kafka APIKEY 10 和 11DNS 协议过滤预览见 cmd/dns.go组装为dns.NewDNSFilter(host)过滤条件命令行参数示例域名host--host example.comMongoDB / MySQL目前支持协议捕获但按条件过滤仍在开发中。组合过滤以上所有选项可以自由组合例如./kyanos watch redis --keys foo,bar --remote-ports 6379 --pid 12345这种组合能力让你能把流量捕获精确裁剪到最相关的请求-响应数据上。stat 命令多维聚合分析watch提供的是单条请求-响应的细粒度视图适合底层问题分析但有些场景需要更宏观的结论详见 docs/stat.mdHTTP 请求变慢或超时是所有服务器都慢还是某一个特定服务器慢有人向 Redis 发送了大量GET请求导致带宽打满是哪个客户端 IP干的stat命令正是为回答这类问题设计的——它把大量请求-响应按维度聚合后给出统计指标。基本用法只需想清楚关心的指标即可。例如要回答「HTTP 请求慢是哪个远端服务器的问题」关心的指标是远端服务器remote-ip的响应时间./kyanos stat --metric total-time --group-by remote-ip--metric设为total-time表示分析请求-响应的总耗时--group-by设为remote-ip表示按每个远端 IP 分组聚合。kyanos 会把相同remote-ip的请求-响应聚在一起给出该指标的相关统计。更短的等价写法./kyanos stat -m t -g remote-ip其中-m是--metric的简写、t是total-time的简写、-g是--group-by的简写。stat命令支持watch命令的所有过滤选项可先过滤再聚合。结果解读执行后得到聚合表格第一列 id第二列是--group-by指定的维度如remote-ip后续是max、avg、p50等列表示该指标此处为 total-time的最大值、平均值、50 分位值等。同样支持数字键排序、↑/↓/k/j移动。按Enter可以下钻到该remote-ip的每一条具体请求-响应记录视图与watch一致可继续查看单条记录的时延与内容。支持的指标--metric指标短标志长标志总耗时ttotal-time响应大小prespsize请求大小qreqsize网络时延nnetwork-time内部处理时间iinternal-timeSocket 读取时间ssocket-time这些取值在 cmd/stat.go 的SUPPORTED_METRICS_SHORT与SUPPORTED_METRICS中定义并做合法性校验。源码细节值得注意当选择network-time时createAnalysisOptions中会强制Side ClientSide并启用BlackBoxDuration指标选择internal-time则强制Side ServerSide——因为「网络时延」只在客户端侧有意义「内部处理时间」只在服务端侧有意义。支持的分组维度--group-by分组维度取值按连接分组conn远端 IPremote-ip远端端口remote-port本地端口local-portL7 协议protocolHTTP 路径http-pathRedis 命令redis-command全部聚合none从 agent/analysis/common/types.go 看--group-by最终映射为ClassfierType分类器而协议特定的分类器在 cmd/stat.go 中被硬编码HTTP →HttpPath、Redis →RedisCommand、MySQL →RemoteIp未显式指定--group-by时默认聚合维度为Conn连接。快速分析slow / bigreq / bigresp记不住这么多参数也没关系stat提供三个一键分析选项--slow分析慢请求--bigreq分析大请求--bigresp分析大响应。它们会自动把聚合维度切到remote-ip并把指标切到对应项源码见 agent/analysis/common/types.go 的Init()SlowMode启用TotalDuration、BigRespMode启用ResponseSize、BigReqMode启用RequestSize且未指定分组时默认RemoteIp。配合--time指定采集时长例如--time 10表示采集 10 秒# 找出哪个远端 IP 的 HTTP 请求最慢 ./kyanos stat http --slow # 找出哪个远端 IP 发来的请求最大 ./kyanos stat http --bigreq # 找出哪个远端 IP 收到的响应最大 ./kyanos stat http --bigresp # 分析最近 5 秒内最慢的请求 ./kyanos stat --slow --time 5采集结束或按ctrlc提前停止后即展示聚合表格。当设置了--time时源码会启用「批处理模式」EnableBatchModel()返回TimeLimit 0并在采集完成时清空已聚合数据CleanWhenHarvest true。overview 命令一条命令总览外部依赖beta当你想知道「这台机器到底依赖了哪些外部资源、各自时延如何」时可以使用overview命令见 cmd/overview.go。它等价于按remote-ip/protocol-adaptive维度聚合的统计视图一条命令抓取当前机器依赖的全部外部资源及其时延sudo kyanos overview其实现细节是overview命令把groupBy设置为remote-ip/protocol-adaptivecmd/overview.go 中直接赋值利用 stat 的聚合能力输出依赖总览。JSON 输出让数据可编程消费预览如果需要对抓取结果做程序化处理可以使用--json-output标志详见 docs/json-output.md# 输出到终端 kyanos watch --json-outputstdout # 输出到文件 kyanos watch --json-output/path/to/custom.json每条请求-响应记录输出为一个 JSON 对象包含时延信息start_time/end_timeRFC3339Nano 格式、total_duration_ms、black_box_duration_ms客户端侧为请求离开到响应到达网卡的耗时服务端侧为请求到达进程到响应离开进程的耗时、read_socket_duration_ms、copy_to_socket_buffer_duration_ms连接信息protocol、side、local_addr、local_port、remote_addr、remote_port、pid、is_ssl内容信息req_size_bytes、resp_size_bytes、req_plain_text_size_bytes、resp_plain_text_size_bytes、request、response格式化后的明文内容事件明细req_syscall_events、resp_syscall_events、req_nic_events、resp_nic_events。一个完整的 JSON 输出示例{ start_time: 2024-01-01T12:00:00.123456789Z, end_time: 2024-01-01T12:00:00.234567890Z, protocol: HTTP, side: client, local_addr: 127.0.0.1, local_port: 54321, remote_addr: 192.168.1.1, remote_port: 80, pid: 12345, is_ssl: false, total_duration_ms: 111.111111, black_box_duration_ms: 50.505050, read_socket_duration_ms: 30.303030, copy_to_socket_buffer_duration_ms: 20.202020, req_size_bytes: 256, resp_size_bytes: 1024, req_plain_text_size_bytes: 256, resp_plain_text_size_bytes: 1024, request: GET /api/v1/users HTTP/1.1\r\nHost: example.com\r\n\r\n, response: HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\status\:\success\} }从源码理解 kyanos 的工作原理命令体系与启动流程kyanos 使用 cobra viper 构建命令行cmd/root.go。根命令kyanos command [flags]下挂载watch、stat、overview三个子命令且每个协议子命令http/redis/mysql/rocketmq/kafka/mongodb/dns会同时复制注册到watch与stat下见 cmd/http.go、cmd/redis.go 等文件底部的watchCmd.AddCommand(copy)/statCmd.AddCommand(copy2)因此同一套协议过滤参数在两种模式下都可用。启动链路cmd/common.go 的startAgent→ agent/agent.go 的SetupAgent大致为解析--side→ 按模式组装AgentOptionswatch 模式设置MaxRecordsstat/overview 模式设置AnalysisEnable与AnalysisOptions→ 初始化日志 → 检查 BPF/CAP_BPF/终端颜色 →conn.InitConnManager()初始化连接管理 →analysis.InitStatRecorder()初始化统计记录器 → 加载 eBPF 程序并开始采集。时延指标的计算kyanos 之所以能给出「请求从进程到网卡」「响应从网卡到 Socket 缓冲区再到进程」的分段时延核心在于它同时采集了多种内核事件并做时序关联agent/analysis/stat.gowriteSyscallEvents/readSyscallEvents读写系统调用事件sslWriteSyscallEvents/sslReadSyscallEventsSSL 读写事件配合 uprobedevOutEvents/nicIngressEvents网卡dev层出/入事件用于测量网络接口耗时对应--trace-dev-event默认开启userCopyEvents/tcpInEvents用户态拷贝与 TCP 入栈事件用于测量 Socket 层拷贝耗时对应--trace-socket-event默认关闭。CreateAnnotedRecord()为每条记录初始化TotalDuration、BlackBoxDuration黑盒/网络耗时、ReadFromSocketBufferDuration等指标随后由统计模块按分类器ClassfierType聚合成分位值p50/p90/p99 等见 agent/analysis/percentile.go。这也解释了 stat 表格中max/avg/p50/p90/p99/count各列的数据来源。eBPF 程序与内核版本适配bpf 目录下可以看到完整的 eBPF 程序与预编译产物pktlatency.bpf.c包时延跟踪、gotls.bpf.cGo TLS 探测、openssl_*.bpf.c按 openssl 1.0.2a 到 3.5.0 各版本的偏移适配配合 bpf/loader 的加载器与 BTF 文件bpf/custom-archive、bpf/vmlinux实现对不同内核版本与 SSL 库版本的兼容--btf全局参数允许在 BTF 缺失的内核上手动指定 BTF 文件。从源码编译构建如果希望从源码构建详见 COMPILATION.md环境要求为golang 1.23 及以上clang 10.0 及以上llvm 10.0 及以上。Ubuntu 20.04 可用项目根目录的 init_env.sh 一键初始化编译环境其他发行版需要额外安装linux-tools-common、linux-tools-generic、pkgconf、libelf-dev并克隆项目记得初始化子模块 libbpfgit clone https://gitcode.com/GitHub_Trending/ky/kyanos cd kyanos git submodule update --init --recursive本地开发测试构建make build-bpf make可执行文件生成在项目根目录。注意这种构建方式不包含 BTF 文件在低版本且无 BTF 的内核上可能无法启动。如需内嵌 BTF 的发行版产物可执行make btfgenx86_64 用make btfgen BUILD_ARCHx86_64 ARCH_BPF_NAMEx86arm64 用make btfgen BUILD_ARCHarm64 ARCH_BPF_NAMEarm64耗时可能超过 15 分钟btfgen.sh脚本与 bpf/custom-archive 中的 BTF 归档配合使用。如果内核未开启 BTF可先检查( zgrep CONFIG_DEBUG_INFO_BTF /proc/config.gz ; grep CONFIG_DEBUG_INFO_BTF /boot/config-$(uname -r) ) | uniq若结果不是CONFIG_DEBUG_INFO_BTFy则需要下载与内核版本对应的 BTF 文件并通过--btf选项指定。小结kyanos 把「抓包 → 下载 → 分析」的传统网络排查流程压缩为一条命令watch负责精细抓取并给出内核级分段时延stat负责多维聚合快速定位异常链路慢请求、大请求、大响应overview一条命令总览外部依赖。配合进程/容器/协议字段的灵活过滤、JSON 输出以及自动 SSL 解密它覆盖了从单条请求下钻到全局流量画像的完整排查路径。更深入的使用细节可继续阅读仓库内文档quickstart、watch 详解、stat 聚合分析、JSON 输出格式 与 5 分钟上手。【免费下载链接】kyanosKyanos is a networking analysis tool using eBPF. It can visualize the time packets spend in the kernel, capture requests/responses, makes troubleshooting more efficient.项目地址: https://gitcode.com/GitHub_Trending/ky/kyanos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询