公司动态
hcsshim实时迁移原理详解:跨主机无缝移动容器的实现机制
hcsshim实时迁移原理详解跨主机无缝移动容器的实现机制【免费下载链接】hcsshimWindows - Host Compute Service Shim项目地址: https://gitcode.com/gh_mirrors/hc/hcsshimhcsshimHost Compute Service Shim是微软开源的 Windows 容器运行时核心组件负责把 containerd 与宿主机上的 HCSHost Compute Service对接起来。而 hcsshim实时迁移Live Migration则是它最具黑科技色彩的能力在不停止服务的前提下把一个正在运行的 LCOW 沙箱——包括整台工具虚拟机Utility VM和其中的所有容器——从一台宿主机完整地搬运到另一台宿主机。本文将从源码层面拆解这套跨主机无缝移动容器的实现机制。什么是 hcsshim 实时迁移传统方案要迁移容器只能先停掉、打包、拷走、再启动服务必然中断。而实时迁移的目标是让应用感觉不到自己被搬了家迁移期间虚拟机内进程继续运行只有最后一小段切机窗口内会短暂冻结随后在目标主机上无缝恢复。这套机制的核心代码集中在两个位置internal/controller/migration/迁移会话控制器负责编排整个迁移生命周期pkg/migration/migration.proto对外暴露的 ttrpc 迁移服务接口定义实时迁移的完整流程源端与目标端如何协作一次 hcsshim实时迁移由**源端SOURCE和目标端DESTINATION**两套 shim 协同完成调用顺序如下步骤源端 shim目标端 shim1PrepareAndExportSandbox初始化迁移、导出快照等待2等待ImportSandbox导入快照重建 shim 状态3等待NewTask逐容器修补资源路径4等待PrepareSandbox创建 HCS 计算系统但不启动5CreateDuplicateSocketCreateDuplicateSocket6TransferSandbox内存传输TransferSandbox内存传输7FinalizeSandboxFinalizeSandbox8CleanupCleanup可以看到两端先各自备料再在传输阶段汇合最后按各自角色收尾。整个调用契约定义在pkg/migration/migration.proto的Migration服务中。关键机制一不透明快照与资源路径修补迁移的第一步是导出状态。源端调用PrepareSource让 HCS 把正在运行的虚拟机置为migrating状态此后不再接受普通修改再由ExportState收集完整的内存态快照。有意思的是这个快照对调用方是不透明的ExportState把 VM 状态和每个 Pod 状态各自打包成google.protobuf.Any包络再统一塞进一个带schema_version的版本化外壳见internal/controller/migration/save/payload.proto由调用方原样转交给目标端。好处是各控制器可以独立演进版本互不干扰。目标端拿到快照后调用ImportState重新水合rehydrateshim 状态。但此时快照里的资源路径还指向源主机的磁盘路径必须通过PatchResourcePaths逐容器修补——每个容器执行一次NewTask把源容器 ID 重绑为目标 ID并修正 VHD 等资源的路径。只有全部容器修补完成PrepareDestination才被允许创建目标端的 HCS 计算系统注意创建但不启动启动要留到传输阶段。相关实现见internal/controller/migration/controller_destination.go。关键机制二套接字复制与内存传输两端备料完成后就进入最核心的内存传输阶段。这里有一个非常巧妙的设计套接字复制Socket Duplication。调用方先在每台宿主机上创建迁移传输套接字然后把序列化的WSAProtocolInfo描述符交给 shim。shim 调用WSASocket在自己的进程内重建出一个重复的套接字句柄见internal/controller/migration/socket.go并用SO_CONNECT_TIME验证它确实已连接。为什么非要复制而不是直接用原套接字注释给出了答案把传输通道与 containerd 进程的生命周期解耦。一旦重复套接字就绪即使 containerd 中途崩溃shim 也能独立把迁移跑完这大大提升了容错性。随后TransferSandbox在两端同时发起基于这个套接字流式搬运虚拟机内存直到目标端内存镜像追平源端。会话 ID 还会通过 SHA-256 映射成一个稳定的 32 位整数确保两端对同一次会话的识别完全一致。迁移状态机一次会话如何精确推进如此复杂的多阶段流程如果没有严谨的状态管理极易出错。hcsshim 为此实现了一个显式的迁移状态机定义在internal/controller/migration/state.go源端与目标端走两条路径、最终汇合源端: Idle → SourcePrepared → SourceExported ─┐ ├→ SocketReady → Transferring → TransferCompleted → Finalized → Idle 目标端: Idle → DestinationImported → DestinationPrepared ─┘如果Transfer在套接字注册前就调用会进入SocketWaiting状态后台等待默认超时 10 分钟传输由后台 goroutine 驱动调用方立即返回进度与结果通过事件订阅通知而不是阻塞在 RPC 上状态机的核心价值在于每个状态只允许特定调用比如只有DestinationImported状态才能做资源修补只有所有容器修补完才能PrepareDestination非法调用会直接返回FailedPrecondition错误把错误尽早暴露。失败与取消迁移的安全网实时迁移的价值一半在成功路径另一半在失败处理。hcsshim 的收尾语义非常讲究——同一个Finalize动作在两端含义截然不同动作源端目标端STOP迁移成功拆除源端计算系统、释放资源迁移失败/取消丢弃目标端计算系统RESUME迁移失败/取消回滚并在源端继续运行迁移成功在目标端恢复运行也就是说停止和恢复由两端按自己角色反向理解配合Cancel中止进行中的迁移与Cleanup无论成败都执行的最终清理任何异常路径都能收敛回Idle状态。此外迁移过程中的进度、错误、超时、完成等事件会通过流式Notifications推送给订阅者见internal/controller/migration/notifications.go让上层容器编排系统可以实时感知迁移状态。总结hcsshim实时迁移的精彩之处在于它把正在运行的整台虚拟机连容器一起搬走这件复杂的事拆解成了源端导出、目标端重建、套接字复制、内存传输、双端收尾这样一套职责清晰、状态严谨的流程。不透明快照让组件独立演进套接字复制带来抗崩溃能力而精确定义的 STOP/RESUME 语义则让成功与失败路径都能优雅收场。理解了这些机制你就掌握了 Windows 容器在跨主机无缝移动场景下的底层运作逻辑。【免费下载链接】hcsshimWindows - Host Compute Service Shim项目地址: https://gitcode.com/gh_mirrors/hc/hcsshim创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考