Kata Containers Tracing 全解析:基于 OpenTelemetry 实现 Runtime 与 Guest Agent 的全链路追踪
云原生容器运行时【免费下载链接】kata-containersKata 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/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载Kata Containers 的 runtime宿主机侧和 agent虚拟机内侧都能生成 OpenTelemetry trace span帮助管理员观察各组件的行为以及每个操作所花费的时间。本篇技术文章将围绕仓库中的 tracing 文档 展开先讲清 trace/span 的基础概念与 Kata 的 tracing 架构尤其是 agent 如何跨越 VM 边界把 span 送抵宿主机收集器再给出完整的启用配置、trace forwarder 的部署步骤与前提条件并结合源码深入剖析 VSOCK 传输协议、span 的生成与合并机制、agent 关闭行为等实现细节帮助读者掌握 Kata 全链路可观测性的配置与排障能力。1. 什么是 Trace 与 SpanOpenTelemetry 基础一个启用 OpenTelemetry 的应用会创建若干 trace span。每个 span 包含以下属性一个名字name一对时间戳记录某个操作开始与结束的时间对父 span 的引用parent span reference。所有 span 都必须被finish或称completeOpenTelemetry 框架才能生成最终的 trace 信息——其本质是闭合涵盖根 spanroot span及其全部子 span 的那笔事务。在 Kata 中根 span 代表的就是某个组件从启动到关闭所花费的总时间即 run time。这一点在 agent 源码中有直接印证在 src/agent/src/main.rs 中agent 启动时如果配置了config.tracing就会先调用tracer::setup_tracing()初始化 OpenTelemetry 提供者随后立即进入一个名为root-span的 spanif config.tracing { tracer::setup_tracing(NAME, logger)?; } let root_span span!(tracing::Level::TRACE, root-span); // XXX: Start the root trace transaction. // // XXX: Note that *ALL* spans needs to start after this point!! let span_guard root_span.enter();注释明确说明此后开始的所有 span 都挂在这个根事务之下。而到 agent 关闭阶段src/agent/src/main.rs会先drop(span_guard)、drop(root_span)强制 flush 所有 span再调用tracer::end_tracing()关闭全局 tracer 提供者。这解释了为什么span 必须完成trace 才完整。2. 整体架构宿主机 runtime 与 VM 内 agent 的追踪难题2.1 Runtime tracing 架构运行在宿主机环境中的 runtime 被改造为可选地生成 trace span并直接发送到宿主机的 trace 收集器collector。因为 runtime 与 collector 运行在同一上下文所以没有跨边界问题。从源码结构看Go runtime 的 tracing 采用 OpenTracing 接口 Jaeger collector 的方式shim 在加载完 runtime 配置后创建 tracer 并打开 root span见 src/runtime/pkg/containerd-shim-v2/create.go// create tracer // This is the earliest location we can create the tracer because we must wait // until the runtime config is loaded jaegerConfig : katatrace.JaegerConfig{ JaegerEndpoint: s.config.JaegerEndpoint, JaegerUser: s.config.JaegerUser, JaegerPassword: s.config.JaegerPassword, } _, err katatrace.CreateTracer(kata, jaegerConfig) ... // create root span rootSpan, newCtx : katatrace.Trace(s.ctx, shimLog, rootSpan, shimTracingTags)Rust runtimeruntime-rs则在 src/runtime-rs/crates/runtimes/src/tracer.rs 中用 OpenTelemetry SDK opentelemetry_jaeger实现维护一个全局ROOTSPAN在读取配置且config.runtime.enable_tracing打开时进入trace_setup收到 containerd 的 shutdown 请求时退出trace_end使整个 sandbox 生命周期内不直接运行在某个 span 之下的线程也能被追踪。其默认 endpoint 为http://localhost:14268/api/tracesJaeger HTTP Thrift 收集器。2.2 Agent tracing 架构trace forwarder 跨越 VM 边界OpenTelemetry 系统依赖 collector 从应用中收集 span。应用要使用 collector必须与 collector 运行在同一上下文。这对追踪 Kata agent 构成了难题agent 运行在虚拟机内部而 collector 通常在宿主机上。为此Kata 提供了 trace forwarder 组件kata-trace-forwarder。它运行在与 collector 相同的上下文中通常在宿主系统上通过VSOCK 通道监听 agent 生成的 trace再使用 OpenTelemetry ProtocolOTLP把它们转发给 trace 收集器。注意该设计使得 agent 追踪无需修改 guest 镜像即可实现因此使用 osbuilder 构建的自定义镜像同样能从 agent tracing 中获益。原文档中的架构示意宿主机、VM、forwarder 与 collector 的关系-------------------------------------------- | Host | | | | --------------- | | | OpenTelemetry | | | | Trace | | | | Collector | | | --------------- | | ^ --------------- | | | spans | Kata VM | | | ---------- | | | | | Kata | spans o ------- | | | | Trace |-----------------| Kata | | | | | Forwarder | VSOCK o | Agent | | | | ----------- Channel | ------- | | | --------------- | --------------------------------------------数据链路在源码中的对应实现agent 侧的出口是一个专门的 VSOCK exporter位于 src/agent/vsock-exporter/src/lib.rs其文件头注释把协议讲得很清楚默认向宿主机VMADDR_CID_HOST的10240 端口发起 VSOCK 连接DEFAULT_PORT: u32 10240与 forwarder 端的DEFAULT_KATA_VSOCK_TRACING_PORT常量严格对应见 src/tools/trace-forwarder/src/main.rs协议采用最简单的头 负载结构先发送一个 8 字节大端序的负载长度头再发送序列化后的 span 数据JSON。forwarder 依据头部知道要读多少字节才能完整消费一个 spanexporter 是懒连接首次export()时才建立 VSOCK 连接并缓存若连接断开NotConnected则丢弃连接、下次自动重连从而保证 forwarder 短暂重启时 agent 不崩溃。forwarder 端的setup_tracingagent 侧初始化src/agent/src/tracer.rs则把该 exporter 包装成 OpenTelemetry 的TracerProviderbatch exporter Tokio 运行时并通过tracing_opentelemetry层注册为全局 subscriber同时设置TraceContextPropagator作为 W3C 传播器。跨进程 span 关联的关键在于 ttrpc 调用链trace_rpc_call!宏src/agent/src/tracer.rs在 agent 处理每个来自 shim 的 RPC 时先从 ttrpc 请求元数据中提取上下文载体extract_carrier_from_ttrpc用全局 propagator 解析出父上下文然后为本 RPC 创建 span 并set_parent(parent_context)。也就是说runtime 发起 RPC 时注入的 trace context 会通过 ttrpc 元数据传入 guest使 agent 的 span 挂载为 runtime 对应 span 的子 span——这正是原文档所述collated合并效果的实现机制。3. Agent tracing 的前提条件要启用 agent 追踪需要满足必须有一个运行中的 OTLP 兼容 trace 收集器。虽然收集器通常运行在宿主机上也可以从 Docker 镜像中运行只需把相应端口暴露给收集器即可。常见的 OTLP 兼容收集器包括Jaegerv1.35OpenTelemetry CollectorGrafana Tempo运行 Jaeger all-in-one Docker 镜像v1.35是测试时启动收集器最快速、最简单的方式。请确保它配置为在 **4317 端口gRPC**或 **4318 端口HTTP**接受 OTLP 数据。如果要追踪 agent必须用正确的 OTLP endpoint 启动 trace forwarder。注意如果启用了 agent 追踪但 forwarder 没有运行agent 会记录一条错误日志表明它无法生成 trace span但功能继续正常运行trace forwarder 启动前要求有一个 OTLP 兼容收集器在运行。若收集器没有运行trace forwarder 会报错退出。4. 启用 tracing配置项与生效范围默认情况下所有组件的 tracing 都是关闭的。要启用任何形式的 tracing必须至少为某个组件打开enable_tracing选项。注意启用该选项后只对此后启动的容器生效。4.1 启用 runtime tracing[runtime] enable_tracing true配置字段定义在 src/libs/kata-types/src/config/runtime.rs除enable_tracing外[runtime]段还有配套的 Jaeger 端点参数Go runtime 使用参数类型默认值说明enable_tracingboolfalse是否让 runtime 生成 tracing spanjaeger_endpointstring空runtime-rs 侧默认为http://localhost:14268/api/tracesJaeger HTTP Thrift collector 的完整 URLjaeger_userstring空Jaeger 需要 basic auth 时的用户名jaeger_passwordstring空Jaeger 需要 basic auth 时的密码从 runtime-rs 的实现看src/runtime-rs/crates/runtimes/src/manager.rs只有config.runtime.enable_tracing为真时才会执行trace_setup即创建 Jaeger 收集管线并进入 ROOTSPAN若设置了密码但用户名为空tracing 会拒绝启用并告警verify_jaeger_config逻辑见 src/runtime-rs/crates/runtimes/src/tracer.rs。此外Kata 还支持通过 Kubernetes annotation 覆盖配置io.katacontainers.config.agent.enable_tracing常量定义见 src/libs/kata-types/src/annotations/mod.rs可在不改动 TOML 配置文件的情况下按 Pod 级别开启 agent 追踪这对在共享集群上临时排查问题非常方便。4.2 启用 agent tracing[agent.kata] enable_tracing true该字段的定义及官方注释在 src/libs/kata-types/src/config/agent.rs注释中明确了两条行为约束与原文档附录一致如果 runtime 也启用了 tracingagent 的 span 会关联到相应的 runtime 父 span启用后runtime 会等待容器关闭完成因此容器关闭时间会略有增加。4.3 两者同时启用span 的合并collation注意如果 agent tracing 和 runtime tracing 同时启用产生的 trace span 会被合并collated在 trace 收集器的 Web UI 中展开某个 runtime span可以看到由该 runtime 操作产生的 agent trace span。其机制即第 2.2 节所述的 ttrpc 上下文传播runtime 端在发起 CreateContainer/StartContainer 等 RPC 时把当前 span context 写入请求元数据agent 端用TraceContextPropagator解出父 span从而形成runtime 根 span → runtime 操作 span → agent RPC span → agent 内部 span的完整调用树。5. trace forwarder 实战按 Hypervisor 部署trace forwarder 的 README 给出了比主文档更细的运行步骤核心流程为启动 OTLP 兼容收集器如 Jaeger v1.35、OpenTelemetry Collector 或 Grafana Tempo以合适的 OTLP endpoint 启动 trace forwarder确认 Kata 配置文件中已启用 agent tracing照常创建 Kata 容器。OTLP endpointforwarder 默认使用http://localhost:4317gRPC。要指向其他端点使用--otlp-endpoint标志kata-trace-forwarder --otlp-endpoint http://my-collector:4317forwarder 的完整命令行参数可在 src/tools/trace-forwarder/src/main.rs 中核对--trace-name默认kata-agent、--otlp-endpoint、--socket-pathCloud Hypervisor/Firecracker 用、--vsock-cid默认any、--vsock-port默认10240、--log-level、--dump-only禁用转发、把 span 写到 stdout便于测试。5.1 QEMU标准 VSOCK非特权运行QEMU 以标准方式支持 VSOCK socket因此直接使用默认选项运行即可cargo run无需特殊权限。判断当前配置的 hypervisor 可以用kata-runtime env --json|jq .Hypervisor.Path5.2 Cloud Hypervisor / FirecrackerHybrid VSOCKCloud Hypervisor 和 Firecracker 使用 hybrid VSOCK——通过本地 UNIX socket 而非宿主机内核与 guest 通信因此需要指定 UNIX socket 路径。由于 forwarder 必须在 VMsandbox启动之前运行而 socket 路径是 sandbox 特定的需要先用env命令确定模板路径其中{ID}代表真实的 sandbox ID 或名称Cloud Hypervisor 示例$ socket_path_template$(sudo kata-runtime env --json | jq .Hypervisor.SocketPath) $ echo $socket_path_template /run/vc/vm/{ID}/clh.sockFirecracker 示例$ socket_path_template$(sudo kata-runtime env --json | jq .Hypervisor.SocketPath) $ echo $socket_path_template /run/vc/firecracker/{ID}/root/kata.hvsock注意不要依赖上面展示的路径——应自行执行命令获取这些路径可能会变化。确定模板路径后构建并安装 forwarderQEMU 场景无需此步、创建 sandbox 目录、再运行 forwarder# Build make # Install cargo install --path . sudo install -o root -g root -m 0755 ~/.cargo/bin/kata-trace-forwarder /usr/local/bin# 把 sandbox_id 改成你计划创建的容器sandbox名称 sandbox_idfoo socket_path$(echo $socket_path_template | sed s/{ID}/${sandbox_id}/g | tr -d ) sudo mkdir -p $(dirname $socket_path)sudo kata-trace-forwarder --socket-path $socket_path现在可以照常创建名为 foo 的 Kata 容器了。注意因为 forwarder 需要在 sandbox 目录中创建 socket而该目录属于root用户所以 hybrid VSOCK 场景下 forwarder 必须先用root启动。这是 hybrid VSOCK 的独有限制QEMU 下运行 forwarder 不需要特殊权限。为降低影响forwarder 启动后会降权到nobody用户继续运行对应 main.rs 帮助文本中的说明降权目标用户为server::NON_PRIV_USER。6. 前提、限制与性能影响6.1 Host 环境要求宿主机内核必须支持 VSOCK socket 类型。内核以CONFIG_VHOST_VSOCK选项编译时具备该能力。必须加载 VSOCK 内核模块sudo modprobe vhost_vsock6.2 Guest 环境要求guest 内核必须支持 VSOCK socket 类型内核以CONFIG_VIRTIO_VSOCKETS选项编译时可用。注意Kata Containers 默认 guest 内核提供该特性。6.3 Agent tracing 的完成时机Agent 追踪只有在工作负载和 Kata agent 进程都退出之后才算完成。虽然在工作负载和 agent 退出之前可以查看 trace 信息但它是不完整的。某些 trace 收集器的 Web UI 会将其显示为trace-without-root-span。如果工作负载仍在运行横跨整个 Kata agent 生命周期的 trace 事务就不会完成。要查看完整的 trace 细节请等工作负载结束或停止容器。这与源码中根 span 在 agent 关闭流程末尾才 drop 并 flush的实现src/agent/src/main.rs一致root span 不结束整笔 trace 事务就未闭合。6.4 性能影响OpenTelemetry 面向高性能设计它整合了前代项目OpenTracing 与 OpenCensus的优点并采用非常高效的机制来捕获 trace span。此外插入 agent 的 trace 点在编译时动态生成。这带来一个好处新版本 agent 会自动受益于追踪基础设施的改进。总体上启用 runtime 与 agent tracing 带来的影响应该极低。6.5 Agent 关闭行为正常操作下Kata runtime 管理 VM 关闭并执行若干优化以加速该过程。但如果启用了 agent 追踪由 agent 本身负责关闭 VM——这是为了确保所有 agent trace 事务都已完成。这意味着 agent 追踪开启时容器关闭会有小的性能影响因为 runtime 必须等待 VM 完全关闭。7. 搭建 tracing 开发环境如果你想调试、进一步开发或测试 tracing强烈建议先启用完整调试enable full debug。若要在 guest 内调试 agent还可以启用 debug 控制台set up a debug console以便进入 VM 环境。8. 小结一次完整的 span 生命周期综合文档与源码Kata 的 tracing 形成了一条清晰的跨边界链路runtime 侧shim 在配置加载后创建 tracer 并打开 root spanGo runtime 见 src/runtime/pkg/containerd-shim-v2/create.goRust runtime 见 src/runtime-rs/crates/runtimes/src/tracer.rs跨 VM 传播RPC 元数据携带 W3C trace context 进入 guestagent 端用trace_rpc_call!宏解析并挂接父 spansrc/agent/src/tracer.rsguest 侧导出agent 的 span 经 vsock-exporter 以8 字节长度头 JSON span的协议经 VSOCK 端口 10240 发往宿主机src/agent/vsock-exporter/src/lib.rs宿主机转发kata-trace-forwarder监听 VSOCK标准 VSOCK 或 hybrid UNIX socket按 OTLP 协议把 span 送到 Jaeger/OTel Collector/Temposrc/tools/trace-forwarder收尾agent 退出时 drop root span 并调用end_tracing()强制 flush保证 trace 事务完整闭合src/agent/src/main.rs。掌握以上链路后无论是排查 sandbox 创建慢在哪一步VM 冷启动、设备热插、guest 内挂载还是对比 runtime 与 agent 各操作的时间占比都可以直接在收集器 Web UI 中通过展开 span 树得到答案。赞分享云原生容器运行时【免费下载链接】kata-containersKata 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/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载相关推荐基于 OpenTelemetry 的 Agent 全链路追踪实战解读 mcp-agent 的 Agent Tracing 示例基于 OpenTelemetry 的 Agent 全链路追踪实战解读 mcp agent 的 Agent Tracing 示例 在构建多工具、多服务器的 MC人工智能AI AgentAgent 框架MCP ClientsAgent 工作流StarRocks 分布式 Tracing 实战基于 OpenTelemetry 与 Jaeger 追踪 FE/BE 全链路StarRocks 分布式 Tracing 实战基于 OpenTelemetry 与 Jaeger 追踪 FE/BE 全链路 本篇聚焦 StarRocks 的数据库OLAP数据仓库大数据湖仓一体数据分析Flux v2 OpenTelemetry Tracing 深度解析基于 Alert API 的 GitOps 全链路追踪RFC-0011Flux v2 OpenTelemetry Tracing 深度解析基于 Alert API 的 GitOps 全链路追踪RFC 0011 本文围绕 Fl云原生CI/CD容器编排DevOps上一篇如何在vscode-dark-islands中启用图标发光效果Seti Folder配置教程下一篇深入理解Ghostty-web的Buffer系统终端数据处理的核心机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →