ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kata Containers Dragonball vCPU 管理机制解析:配置、状态机与热插拔实现

Kata Containers Dragonball vCPU 管理机制解析:配置、状态机与热插拔实现 云原生容器运行时【免费下载链接】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 仓库中 src/dragonball/docs/vcpu.md 为核心深入剖析 Dragonball 轻量级 VMM 的 vCPU 子系统从VcpuConfig的 CPU 数量与拓扑配置、vPMU 特性开关到四态 vCPU 状态机running/paused/waiting_exit/exited的运行逻辑再到基于 upcall 直连通道实现 vCPU 热插拔/热移除的原理与范围约束。读完本文你将掌握 Dragonball vCPU 的配置字段含义、生命周期状态流转路径以及如何通过 API 触发运行时 CPU 弹性伸缩。Kata Containers 的 Dragonball 是一套基于 Rust 实现的轻量级虚拟化监控程序VMM其 vCPU 子系统位于 src/dragonball/src/vcpu 目录由三个模块协同构成vcpu_manager.rsvCPU 管理器负责引导启动与 CPU 热插拔、vcpu_impl.rs单个 vCPU 的实现封装 KVM 交互与状态机运行、sm.rs通用状态机抽象。本文档对应的设计说明即仓库中的 vcpu.md。一、vCPU Manager全局调度中枢vCPU Manager 负责管理所有与 vCPU 相关的动作。其核心数据结构是 VcpuManager主要成员包括vcpu_infos: VecVcpuInfo按max_vcpu_count预分配的 vCPU 信息槽位每个VcpuInfo记录该 CPU 的Vcpu对象、VcpuFd、VcpuHandle线程句柄与线程tidvcpu_config: VcpuConfig整机 vCPU 配置见下文vcpu_state_event: EventFd与vcpu_state_sender: SenderVcpuStateEventvCPU 状态事件通知通道用于把 guest 侧返回的热插拔结果回传给 VMM 事件循环reset_event_fd当 vCPU 被复位时写入的 EventFdsupport_immediate_exit: bool是否支持 KVMImmediateExit扩展通过kvm_context.kvm().check_extension(Cap::ImmediateExit)探测action_sycn_tx与vcpus_in_action记录当前正在进行的热插拔/热移除动作及其涉及的 CPU 列表防止并发 resize 操作在同时启用hotplug与dbs-upcall特性时还持有upcall_channel: OptionArcUpcallClientDevMgrService这是运行时 CPU 热插拔的通信通道。从源码结构看VcpuManager 的职责可以概括为创建/启动/暂停/恢复/退出 vCPU并在运行期通过 upcall 通道完成 CPU 数量调整。VcpuManager 在初始化时会校验max_vcpu_count不超过 KVM 允许的上限超出即返回MaxVcpuLimitation错误见 vcpu_manager.rs#L286-L294。1.1 vCPU 配置VcpuConfigVcpuConfig定义于 src/dragonball/src/vcpu/mod.rs#L21-L39用于配置 guest 的整体 CPU 信息各字段含义如下字段类型含义boot_vcpu_countu8初始 vCPU 数量即虚拟机启动时创建的 CPU 数max_vcpu_countu8最大 vCPU 数量作为 CPU 热插拔功能的上边界threads_per_coreu8CPU 拓扑每个核的线程数超线程cores_per_dieu8CPU 拓扑每个 die 的核数dies_per_socketu8CPU 拓扑每个 socket 的 die 数socketsu8CPU 拓扑socket 数量vpmu_featureVpmuFeatureLevelvPMU虚拟性能监控单元特性等级在 VcpuManager::new 中这些字段由VmConfigInfo即vm_config_info.vcpu_count、max_vcpu_count以及cpu_topology各分量转换而来。VcpuConfig的字段类型全部为u8因此单机可配置的 vCPU 数量上限为 255。1.2 vPMU 特性等级vpmu_feature使用VpmuFeatureLevel枚举描述三个等级见 mod.rs#L34-L38 的注释DisabledvPMU 功能关闭默认值LimitedlyEnabled仅支持最少的 vPMU 计数器cycles 和 instructionsFullyEnabled支持全部 vPMU 计数器。配置映射逻辑位于 vcpu_manager.rs#L310-L324整数值1映射为LimitedlyEnabled2映射为FullyEnabled其余值含 0映射为Disabled。需要特别注意的是 aarch64 平台源码中当 aarch64 上请求LimitedlyEnabled时会打印告警并回退为Disabled即aarch64 目前只支持 Disabled 与 FullyEnabled 两个等级这一点与原文档aarch64 vCPU 支持仍在开发中的描述互相印证。二、vCPU 状态机四态生命周期vCPU 状态机共有四个状态running、paused、waiting_exit、exited。状态机的通用抽象StateMachineT位于 src/dragonball/src/vcpu/sm.rs每个状态对应一个状态处理函数StateFnT该函数返回下一个StateMachineT从而显式定义状态迁移StateMachine::run从起始状态开始循环执行直到进入end_state为止。四个状态的处理函数实现在 vcpu_impl.rs 中2.1 状态流转全景创建 → pausedvCPU 创建后其线程从StateMachine::run(self, Self::paused)进入paused状态见 vcpu_impl.rs#L675-L677。此时 vCPU 线程阻塞等待事件。paused → running当 VMM 中 vCPU 资源准备就绪后VMM 通过VcpuHandle::send_event向 vCPU 线程发送Resume事件同时用SIGRTMIN信号踢醒线程见 vcpu_impl.rs#L276-L288。paused状态处理函数收到Resume后回复Resumed响应并迁移到running见 vcpu_impl.rs#L782-L787。runningvCPU 线程持续执行run_emulation()循环即KVM_RUNVMM 捕获 vCPU 退出exit事件并根据退出原因执行不同逻辑IoIn/IoOut/MmioRead/MmioWrite交给io_mgr完成 PIO/MMIO 仿真x86_64 上的 IOAPIC 区间则由irq_manager处理Hlt/Shutdown/FailEntry/InternalError等不可处理退出返回错误并迁移到waiting_exitSystemEventKVM_SYSTEM_EVENT_RESET/KVM_SYSTEM_EVENT_SHUTDOWN标记Stopped并迁移到waiting_exit若 KVM 运行返回EINTR被信号打断则读取事件通道处理Pause/Exit/Gettid/RevalidateCache/SaveState等外部事件后回到running。running → waiting_exit当 VMM 捕获到无法处理的退出原因时状态迁移到waiting_exit。waiting_exit → exited进入waiting_exit后vCPU 线程首先向自己的exit_evtEventFd写入 1见 vcpu_impl.rs#L834-L839。exit_evt的变化被事件管理器EventManager检测到后会将 VMM 的exit_evt_flag置为 1VMM 事件循环中负责检查exit_evt_flag的线程发现标志位为 1 后即停止 VMM。随后 vCPU 线程等待Exit事件收到后迁移到exited。当 VMM 停止/销毁时vCPU 状态最终变为exited状态机到达终点StateMachine::finish。2.2 状态迁移矩阵当前状态事件下一状态pausedResumerunningpausedExit / 通道关闭exitedrunningPausepausedrunningExit / 通道关闭exitedrunning未处理的 KVM 退出 / SystemEvent(Reset/Shutdown)waiting_exitwaiting_exitExit / 通道关闭exitedexited终点状态—2.3 与 VMM 停止流程的联动waiting_exit状态体现了 vCPU 与 VMM 生命周期解耦的设计vCPU 不直接关闭 VMM而是通过exit_evt通知事件管理器再由事件管理器置位exit_evt_flag最终由 VMM 事件循环线程统一执行停机。这一机制在 vcpu_impl.rs 的waiting_exit处理函数与 VMM 事件循环代码中均有体现。三、vCPU 热插拔基于 upcall 的直连通道3.1 为什么不用 ACPIDragonball Sandbox 不虚拟化 ACPI 系统因此无法走传统的 ACPI 表 SCI 中断路径触发 CPU 热插拔。取而代之的是upcall机制通过 VSOCK 在 VMM 与 guest 之间建立一条直接通信通道触发 guest 内核执行 CPU 热插拔/热移除。upcall 的客户端实现位于 src/dragonball/crates/dbs_upcall其设计说明见 dbs_upcall/README.md。采用 upcall 的直接收益是避免虚拟化 ACPI 带来的虚拟开销最小化虚拟机运行时成本。3.2 服务端与客户端架构服务端guest 内核侧upcall 服务端是 guest 内核中的一个驱动VSOCK 端口固定为0xDB常量SERVER_PORT见 lib.rs#L29。VSOCK 连接建立后注册 upcall 相关服务并创建内核服务线程服务线程先发送Connect类型消息与客户端握手随后进入循环持续接收并处理请求。当前支持的服务是设备管理器device manager可处理 CPU 热插拔/热移除、virtio-mmio 设备热插拔/热移除等请求源码中DevMgrMsgType枚举定义了AddCpu/DelCpu/AddMem/DelMem/AddMmio/DelMmio/AddPci/DelPci等操作码见 dev_mgr_service.rs#L26-L36。客户端VMM 侧UpcallClientDevMgrService通过 UDS 与 VSOCK 通信工作在一个独立线程中。客户端状态机包含WaitingServer→WaitingService→ServiceConnected三个阶段连接失败会自动重连重连间隔 10ms最大重连次数 500见 lib.rs#L30-L31发送请求后状态变为ServiceBusy此状态下不再处理其他请求见 dbs_upcall/README.md 的客户端设计说明。3.3 消息格式upcall 请求消息由消息头 消息负载组成回复消息由消息头 结果 消息负载组成消息头DevMgrMsgHeader请求与回复相同magic_versionu32用于标识 upcall 与服务的魔数版本msg_sizeu32消息负载大小msg_typeu32消息类型如AddCpumsg_flagsu32保留字段。CPU 热插拔请求负载CpuDevRequestcount热插拔/热移除 CPU 数量u8、apic_verAPIC 版本x86_64、apic_ids[256]APIC ID 数组x86_64。aarch64 平台下CpuDevRequest仅有count字段见 dev_mgr_service.rs#L71-L100。回复语义结果result 0表示操作成功非 0 表示错误码CPU 热插拔回复负载包含apic_index成功热插拔的 CPU 索引。3.4 内核补丁与使用前提使用 upcall 需要为 guest 内核打补丁。本仓库在 tools/packaging/kernel/patches 下按内核版本5.10.x / 6.1.x / 6.12.x 等提供了dragonball-experimental系列补丁其中包括0001-upcall-establish-upcall-server.patch建立 upcall 服务端0002-upcall-introduce-device-manager-upcall-service.patch引入设备管理器 upcall 服务0003-upcall-add-cpu-hotplug-hot-unplug-into-device-manage.patch在设备管理器中加入 CPU 热插拔/热移除0004-upcall-add-virtio-mmio-hotplug-hot-unplug-into-devic.patchvirtio-mmio 设备热插拔/热移除0005-upcall-dragonball-devmgr-suppots-cpu-hotplug-on-arm6.patchaarch64 上的 CPU 热插拔支持0008-upcall-add-pci-hotplug-hot-unplug-support.patchPCI 设备热插拔/热移除。此外tools/packaging/kernel/configs/fragments/build-type/dragonball-experimental/upcall.conf 提供了对应的内核配置片段可通过 tools/packaging/kernel/build-kernel.sh 构建带 upcall 支持的 guest 内核。原文档说明会提供开箱即用的 guest 内核二进制供试用。3.5 热插拔流程源码级热插拔的入口是 VMM 的ResizeVcpu动作见 vmm_action.rs#L1081-L1106该动作要求 VM 已初始化UpdateNotAllowedPreBoot错误防护且仅在启用hotplug与dbs-upcall特性时可用。完整流程如下计算目标差值VcpuManager::resize_vcpu 比较目标数量与当前在线数量相等则无需调整目标更大则执行do_add_vcpu热插拔更小则执行do_del_vcpu热移除。热插拔do_add_vcpu先通过create_vcpus创建 vCPU不超过max_vcpu_count否则返回ExpectedVcpuExceedMax再经activate_vcpus启动并恢复运行激活失败时会对已启动的 vCPU 做回滚随后构造DevMgrRequest::AddVcpu(CpuDevRequest)通过 upcall 发送给 guest。热移除do_del_vcpuvCPU 0 不允许被移除返回Vcpu0CanNotBeRemoved通过calculate_removable_vcpus取得可移除 CPU 列表当前在线 CPU按级联顺序从高编号开始倒序截取待移除数量构造DevMgrRequest::DelVcpu(CpuDevRequest)发送给 guest可移除 CPU 不足时返回LackRemovableVcpus。等待 guest 确认send_upcall_action注册回调guest 侧回复DevMgrResponse::CpuDev后通过vcpu_state_sender发送VcpuStateEvent::Hotplug((result, cpu_index))并写vcpu_state_eventEventFd通知 VMM。事件循环收尾VcpuEpollHandler::process_cpu_state_event读取该事件见 vcpu_manager.rs#L1172-L1183若结果为成功热插拔则直接同步完成热移除则调用stop_vcpus_in_action退出被移除的 vCPU 线程最后清空进行中的动作并同步结果。3.6 热插拔范围约束vCPU 热插拔/热移除的有效范围是[1, max_vcpu_count]超出该范围的操作一律无效目标数量小于 1即移除到 0→Vcpu0CanNotBeRemoved目标数量大于max_vcpu_count→ExpectedVcpuExceedMax热插拔进行中再次发起 resize →VcpuIsHotplugging未配置 upcall 通道时运行期 resize →UpdateNotAllowedPostBoot见 vcpu_manager.rs#L1007-L1009。3.7 测试验证源码提供了针对上述机制的单元测试位于 vcpu_manager.rs 的 tests 模块可作实现事实的印证test_vcpu_manager_config验证vcpu_infos按max_vcpu_count预分配、boot_vcpu_count/max_vcpu_count与配置一致、reset_event_fd正确设置test_vcpu_manager_boot_vcpus验证引导 vCPU 的创建与启动x86_64 创建 1 个aarch64 创建全部max_vcpu_count个test_vcpu_manager_operate_vcpus验证创建超过上限报ExpectedVcpuExceedMax、present_vcpus的递增序列等test_vcpu_manager_pause_resume_vcpus验证暂停/恢复及非法 CPU ID 报VcpuNotFoundtest_vcpu_manager_save_restore_states验证 vCPU 状态保存/恢复需先暂停运行态保存返回SaveStateNotAllowedtest_vcpu_manager_resize_cpu验证 resize 在热插拔进行中报VcpuIsHotplugging、无 upcall 通道报UpdateNotAllowedPostBoot、移除 vCPU 0 报Vcpu0CanNotBeRemoved等边界行为。四、架构差异与开发状态说明原文档明确提到 aarch64 vCPU 支持仍在开发中。结合源码可以补充两点事实启动时创建全部 vCPUaarch64 上 KVM 不允许在 VM 启动后调用KVM_CREATE_VCPU受 VGIC 检查限制因此在create_boot_vcpus中 aarch64 会直接按max_vcpu_count创建全部 vCPU fd见 vcpu_manager.rs#L404-L414后续热插拔只做激活而非新建 fdx86_64 则按boot_vcpu_count创建。这也解释了为何测试中 aarch64 的present unstart vcpus数量等于max_vcpu_count如 3而 x86_64 等于boot_vcpu_count1。vPMU 差异aarch64 暂不支持LimitedlyEnabled等级请求该等级时自动回退为Disabled。从源码结构看这些差异在#[cfg(target_arch x86_64)]/#[cfg(target_arch aarch64)]条件编译中分别实现见 vcpu_impl.rs#L37-L49 的架构模块选择。五、小结与延伸阅读Dragonball 的 vCPU 子系统以VcpuConfig为配置入口、以四态状态机驱动每个 vCPU 线程、以 upcall 直连通道实现运行时 CPU 弹性伸缩三者共同支撑了 Kata Containers 轻量级虚拟机对 CPU 的高效虚拟化与动态管理。核心代码位置汇总如下设计文档src/dragonball/docs/vcpu.mdvCPU 管理器与热插拔逻辑src/dragonball/src/vcpu/vcpu_manager.rs单 vCPU 实现与状态机处理函数src/dragonball/src/vcpu/vcpu_impl.rs状态机抽象src/dragonball/src/vcpu/sm.rsvCPU 配置结构src/dragonball/src/vcpu/mod.rsupcall 通道实现与设计src/dragonball/crates/dbs_upcall/src/lib.rs、src/dragonball/crates/dbs_upcall/src/dev_mgr_service.rs、src/dragonball/crates/dbs_upcall/README.mdguest 内核 upcall 补丁tools/packaging/kernel/patches/5.10.x/dragonball-experimental以及 6.1.x、6.12.x 对应目录resize API 入口src/dragonball/src/api/v1/vmm_action.rs注aarch64 vCPU 支持仍处于开发完善阶段原文档提及 issue #4445本文中涉及 aarch64 的行为描述均以当前仓库源码为准后续合并runtime-rs到 master 后相关支持会进一步完善。赞分享云原生容器运行时【免费下载链接】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 Dragonball VMM 设备模型深解析dbs-device 的 MMIO/PIO 陷阱处理、IO 分发与热插拔机制Kata Containers Dragonball VMM 设备模型深解析dbs device 的 MMIO/PIO 陷阱处理、IO 分发与热插拔机制 本篇云原生容器运行时Kata Containers 3.0 runtime-rs 虚拟 CPU 容量规划与热插拔处理机制全解析Kata Containers 3.0 runtime rs 虚拟 CPU 容量规划与热插拔处理机制全解析 导读 本文基于 Kata Containers 仓库云原生容器运行时Kata Containers 内置 VMM Dragonball API 配置指南BootSource 与虚拟机配置详解Kata Containers 内置 VMM Dragonball API 配置指南BootSource 与虚拟机配置详解 Kata Containers 在云原生容器运行时上一篇终极HsMod插件指南55项功能轻松解锁炉石传说高级玩法下一篇PaddleSpeech TIMIT Transformer ASR 复现与解码方式对比从 RESULTS.md 读懂音素识别实验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表