- 云原生
- 容器运行时
【免费下载链接】kata-containers
Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/
Kata Containers 的 agent 运行在虚拟机(VM)内部,无法直接向宿主机的追踪收集器上报 OpenTelemetry 链路数据。本文聚焦 src/tools/trace-forwarder 目录下的kata-trace-forwarder组件,讲解它如何作为宿主机侧的"转发器",通过 VSOCK 通道接收 VM 内 agent 产生的 trace span,并以 OTLP 协议导出到 OpenTelemetry 兼容收集器。读完本文,你将掌握该组件的运行原理、QEMU / Cloud Hypervisor / Firecracker 三种 hypervisor 下的启动方式、OTLP 端点与 Kata 配置文件的联动配置,以及完整的 CLI 参数与排障要点。
组件定位:宿主机上的 Agent 追踪"摆渡人"
Kata Containers 运行时(runtime)和 agent 都能生成 OpenTelemetry trace span,用于观察各组件的行为与耗时。运行时运行在宿主机环境,可以直连宿主机上的 trace collector;但 agent 运行在 VM 内部,与 collector 不在同一上下文中,无法直接上报。
kata-trace-forwarder正是为解决这一隔离问题而设计的组件:它运行在宿主机上,与 collector 处于同一上下文,必须在容器(sandbox)启动之前启动,通过VSOCK通道监听 VM 内 agent 发出的 trace 数据,再使用 OpenTelemetry Protocol(OTLP)把 span 导出到默认运行在宿主机上的 OpenTelemetry 兼容收集器。
整体架构如下(参考 docs/tracing.md 的架构说明):
+--------------------------------------------+ | Host | | | | +---------------+ | | | OpenTelemetry | | | | Trace | | | | Collector | | | +---------------+ | | ^ +---------------+ | | | spans | Kata VM | | | +-----+-----+ | | | | | Kata | spans o +-------+ | | | | Trace |<-----------------| Kata | | | | | Forwarder | VSOCK o | Agent | | | | +-----------+ Channel | +-------+ | | | +---------------+ | +--------------------------------------------+说明:这种设计无需修改 guest 镜像即可支持 agent 追踪,自定义镜像(osbuilder 构建的镜像)同样能受益。
工作原理:VSOCK 通道与"头-负载"帧协议
追踪链路分为两端:
- VM 内(agent 侧):agent 通过
vsock-exporter(源码见 src/agent/vsock-exporter/src/lib.rs)把 trace span 发送给 forwarder。它默认连接 CID 为VMADDR_CID_HOST(宿主机)、端口为10240(源码中的DEFAULT_PORT),并采用最简单的帧协议:先是 8 字节(HEADER_SIZE_BYTES = size_of::<u64>())的头部,用大端序(NetworkEndian::write_u64)编码后续 payload 的字节数,然后才是序列化后的 span 数据(见write_span实现)。 - 宿主机(forwarder 侧):forwarder 在 VSOCK 端口上监听,handler.rs 中同样以 8 字节头部解析出 payload 长度,再完整读取 payload,从而逐条消费来自 agent 的 span。注释明确要求:头部大小常量必须与 agent 侧
vsock-exporter中同名变量的值保持一致。
两种 VSOCK 模式的差异决定了运行方式(该对照表也内置于--help的长帮助文本中,见 main.rs):
| Hypervisor | VSOCK 类型 | forwarder 运行身份 |
|---|---|---|
| Cloud Hypervisor (CLH) | Firecracker Hybrid(宿主机内核之外的本地 UNIX socket) | 需要 root |
| QEMU | Standard(宿主机内核原生 vsock) | 普通用户即可 |
| Firecracker (FC) | Firecracker Hybrid | 需要 root |
其中Hybrid VSOCK的实现细节值得注意:forwarder 传入的"master socket"路径本身并不会被直接使用,而是以该路径为前缀、追加_{端口号}后缀生成真正与 agent 通信的 socket 路径。这一逻辑实现在 utils.rs 的make_hybrid_socket_path中(例如/run/vc/vm/foo/clh.sock加端口后变为/run/vc/vm/foo/clh.sock_10240),并有对应的单元测试验证。
部署前置条件
内核与模块要求
宿主机内核需支持 VSOCK(
CONFIG_VHOST_VSOCK),并加载内核模块:sudo modprobe vhost_vsockguest 内核需支持 VSOCK(
CONFIG_VIRTIO_VSOCKETS),Kata Containers 默认 guest 内核已内置该特性。
追踪收集器必须先启动
- 必须有一个OTLP 兼容的 trace collector在运行。forwarder 启动前若 collector 未运行,forwarder 会报错退出。
- 常用收集器包括:Jaeger(v1.35+)、OpenTelemetry Collector、Grafana Tempo。测试时最快捷的方式是运行 Jaeger 的 "all-in-one" 镜像,并确保其在 4317(gRPC)或 4318(HTTP)端口接收 OTLP 数据。
在 Kata 配置文件中启用 agent 追踪
以 QEMU 配置模板 configuration-qemu.toml.in 为例,[agent.@PROJECT_TYPE@]段下的enable_tracing默认关闭:
[agent.kata] # Enable agent tracing. # (default: disabled) enable_tracing = true同样地,若要追踪运行时本身,可在[runtime]段开启(configuration-qemu.toml.in):
[runtime] enable_tracing = true注意:开启该选项只对之后启动的容器生效;若同时开启 runtime 与 agent 追踪,生成的 span 会被"拼接"(collated),在 collector Web UI 中展开某个 runtime span 即可看到对应的 agent span。
快速开始
按以下四步即可完成一次 agent 追踪的部署:
- 启动一个 OTLP 兼容收集器(如 Jaeger v1.35+、OpenTelemetry Collector 或 Grafana Tempo);
- 以合适的 OTLP 端点启动 trace forwarder;
- 在 Kata 配置文件中启用 agent 追踪(
[agent.kata]段的enable_tracing = true); - 照常创建 Kata 容器。
说明:若已启用 agent 追踪但 forwarder 未运行,agent 会记录一条错误日志(提示无法生成 trace span),但容器本身仍能正常工作。
OTLP 端点配置
forwarder 把 span 发送到 OTLP 端点,默认值为http://localhost:4317(gRPC),该默认值定义在 main.rs 的DEFAULT_OTLP_ENDPOINT常量中。如需指定其他端点,使用--otlp-endpoint参数:
kata-trace-forwarder --otlp-endpoint http://my-collector:4317常见 OTLP 端点:
| 收集器 | 端点 |
|---|---|
| Jaeger(v1.35+) | http://localhost:4317(gRPC)或http://localhost:4318(HTTP) |
| OpenTelemetry Collector | http://localhost:4317(gRPC)或http://localhost:4318(HTTP) |
| Grafana Tempo | 取决于其配置 |
在 tracer.rs 的create_otlp_trace_exporter中可以看到导出器的构建方式:使用opentelemetry-otlp的 tonic 实现(gRPC)创建SpanExporter,并通过SdkTracerProvider::with_batch_exporter以批量方式导出,资源属性包含service.name(默认kata-agent)与exporter=otlp。
根据 hypervisor 选择运行方式
先确认 Kata 配置的 hypervisor
查看配置文件,或直接运行:
kata-runtime env --json | jq '.Hypervisor.Path'QEMU:标准 VSOCK,默认参数直接运行
QEMU 以标准方式支持 VSOCK socket,因此使用默认选项即可。在 src/tools/trace-forwarder 目录下运行:
cargo run随后照常创建 Kata 容器即可,无需额外参数或特权。
Cloud Hypervisor / Firecracker:Hybrid VSOCK,需指定 UNIX socket 路径
CLH 与 Firecracker 都使用 "hybrid VSOCK"——通过本地 UNIX socket(而非宿主机内核)与 guest 通信,因此必须指定 UNIX socket 路径。由于 forwarder 必须在 VM(sandbox)启动前运行,而 socket 路径与具体 sandbox 绑定,需要先用env命令确定"模板路径",该路径包含代表真实 sandbox ID/名称的{ID}占位符。
配置的 hypervisor 为 Cloud Hypervisor 时:
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath') $ echo "$socket_path_template" "/run/vc/vm/{ID}/clh.sock"配置的 hypervisor 为 Firecracker 时:
$ socket_path_template=$(sudo kata-runtime env --json | jq '.Hypervisor.SocketPath') $ echo "$socket_path_template" "/run/vc/firecracker/{ID}/root/kata.hvsock"注意:不要依赖上面展示的路径——请务必自行运行命令获取,因为这些路径可能发生变化。
得到模板路径后,按以下顺序操作。
构建与安装
QEMU 场景无需此步骤;CLH / Firecracker 场景下,先安装好工具会更方便。
构建:
make安装:
cargo install --path . sudo install -o root -g root -m 0755 ~/.cargo/bin/kata-trace-forwarder /usr/local/binmake对应 Makefile 中的构建目标,实际执行的是cargo build -p kata-trace-forwarder。
创建 sandbox 目录
将下面的sandbox_id变量改成你计划在启动 forwarder 之后创建的容器(sandbox)名称:
sandbox_id="foo" socket_path=$(echo "$socket_path_template" | sed "s/{ID}/${sandbox_id}/g" | tr -d '"') sudo mkdir -p $(dirname "$socket_path")sed用于把模板中的{ID}替换成真实 sandbox ID,tr -d '"'用于去除env --json输出中 JSON 字符串的引号。
以 socket 路径启动 forwarder
sudo kata-trace-forwarder --socket-path "$socket_path"启动完成后,即可照常创建名为 "foo" 的 Kata 容器。
注意:因为 forwarder 需要在 sandbox 目录中创建 socket,而该目录归
root用户所有,所以 hybrid VSOCK 场景下 forwarder 也必须以root身份运行。这是 hybrid VSOCK 独有的要求——QEMU 场景下运行 forwarder 不需要任何特殊权限。为了降低影响,forwarder 启动(绑定 socket)后会立即降权,以nobody用户继续运行。
特权模型:root 启动与 nobody 降权
该行为在 server.rs 中有完整实现:
NON_PRIV_USER常量定义为"nobody"(见 server.rs);start_hybrid_vsock首先检查当前进程是否为 root(Uid::effective().is_root(),否则报 "You need to be root"),删除可能残留的 socket 文件后通过UnixListener::bind(socket_path)绑定,绑定成功后立即调用drop_privs;drop_privs先把工作目录切换到/,再通过privdropcrate 的PrivDrop::default().user("nobody").apply()降权(见 server.rs);- 标准 VSOCK 路径则直接以
VsockListener::bind(&SockAddr::new_vsock(cid, port))监听,无需特权。
完整 CLI 参数参考
除--otlp-endpoint外,main.rs 还定义了以下参数,运行cargo run -- --help可查看完整帮助:
| 参数 | 默认值 | 说明 |
|---|---|---|
--otlp-endpoint | http://localhost:4317 | OTLP 端点 URL(gRPC) |
--trace-name | kata-agent | 为 trace 指定的名称(不可为空) |
--socket-path | 无 | hypervisor socket 的完整路径(仅 CLH / Firecracker,需要 root) |
--vsock-cid | any | VSOCK CID 数字(或any,仅 QEMU),any对应内核常量VMADDR_CID_ANY |
--vsock-port | 10240 | VSOCK 端口号(仅 QEMU;hybrid 模式下作为 socket 路径后缀),不可为 0 |
--log-level/-l | info | 日志级别(支持运行时修改) |
--dump-only | 关闭 | 不转发 span,而是写入 stdout(用于测试) |
其中 VSOCK 端口默认值10240必须与 agent 侧vsock-exporter的DEFAULT_PORT(src/agent/vsock-exporter/src/lib.rs)保持一致,否则两侧无法建立连接。--vsock-cid、--vsock-port的解析与校验(空值、非数字、端口为 0 等错误场景)在 utils.rs 中有完整实现与单元测试覆盖。
--help中还内置了三种 hypervisor 的示例(after_help文本):
# QEMU $ kata-trace-forwarder --trace-name "kata-agent" # Cloud Hypervisor(sandbox 名称 foo) $ sandbox_id="foo" $ sudo kata-trace-forwarder --trace-name "kata-agent" --socket-path /run/vc/vm/foo/clh.sock # Firecracker(sandbox 名称 foo) $ sandbox_id="foo" $ sudo kata-trace-forwarder --trace-name "kata-agent" --socket-path /run/vc/firecracker/foo/root/kata.hvsock测试与调试
- 运行单元测试:
make test(对应 Makefile 中的cargo test -p kata-trace-forwarder -- --nocapture),测试覆盖了 hybrid / standard VSOCK 参数解析、端口与 CID 校验、socket 路径拼接等逻辑。 - 使用
--dump-only模式:forwarder 不再把 span 导出到 collector,而是把收到的原始字节打印到 stdout,便于在无收集器环境下验证 VM 内 agent 是否能成功发送数据。 - 从当前仓库源码看(handler.rs),handler 在读取 payload 后存在一处已知的状态限制:由于 OpenTelemetry 0.27 的
SpanData不再实现Deserialize,非 dump 模式下 forwarder 会输出一条警告(提示 agent 与 forwarder 的 OpenTelemetry 版本可能不兼容),dump 模式则仅记录接收字节数。使用该组件时建议留意此警告与两侧依赖版本的一致性。
注意事项与常见问题
- collector 必须先于 forwarder 启动:若收集器未运行,forwarder 会直接报错退出。
- forwarder 未运行时 agent 不受影响:agent 追踪开启但 forwarder 未运行时,agent 仅记录错误日志,正常工作不受阻。
- 不要硬编码 socket 路径:CLH / Firecracker 的 socket 模板路径以
kata-runtime env --json的实际输出为准,示例路径可能随版本变化。 - 混合 VSOCK 必须用 root 启动:但绑定 socket 后 forwarder 会自动降权为
nobody,无需常驻特权进程。 - 追踪完成时机:agent 的 trace 事务只有在 workload 与 agent 进程都退出后才算完成(可参考 docs/tracing.md 的说明);若 workload 仍在运行,collector 中可能看到
<trace-without-root-span>的不完整展示,需等待 workload 结束或停止容器后再查看完整 trace。 - 关闭行为变化:agent 追踪开启后,VM 关闭改由 agent 负责(以确保所有 trace 事务完成),容器关闭耗时会有轻微增加。
- 配置只对后续容器生效:修改
enable_tracing后,只有之后启动的容器才会带追踪能力。
综上,kata-trace-forwarder是打通"VM 内 agent → 宿主机收集器"追踪链路的关键组件。理解其 VSOCK 双模式与特权模型,按 hypervisor 选择正确的启动参数,即可快速为 Kata Containers 的 agent 建立完整的可观测性。
- 云原生
- 容器运行时
【免费下载链接】kata-containers
Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/
相关推荐
Kata Containers 追踪(Tracing)设计提案解析:从 Agent 静态追踪到 Trace Forwarder 采集架构
Kata Containers 追踪(Tracing)设计提案解析:从 Agent 静态追踪到 Trace Forwarder 采集架构 导读 本文以 Kata
云原生容器运行时Kata Containers Tracing 全解析:基于 OpenTelemetry 实现 Runtime 与 Guest Agent 的全链路追踪
Kata Containers Tracing 全解析:基于 OpenTelemetry 实现 Runtime 与 Guest Agent 的全链路追踪 Kat
云原生容器运行时Kata Containers 与 AWS Firecracker 集成指南:配置、部署与验证
Kata Containers 与 AWS Firecracker 集成指南:配置、部署与验证 本篇技术指南围绕 Kata Containers 官方文档中关于
云原生容器运行时
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考