☰
LinuxKit virtio/Hyper-V Socket 压力测试实战:从镜像构建到 Windows 端压测
2026/9/28 2:31:00 网站建设 项目流程
  • 操作系统
  • 云原生
  • 容器运行时

【免费下载链接】linuxkit

A toolkit for building secure, portable and lean operating systems for containers

项目地址:https://gitcode.com/gh_mirrors/li/linuxkit
点击查看免费下载

导读:本文围绕 LinuxKit 仓库中 test/pkg/virtsock/README.md 所述的压力测试方案展开,讲解如何构建一个内置 virtio socket 与 Hyper-V socket 服务端的 LinuxKit 镜像,并在 Windows 宿主机的 Hyper-V 虚拟机中完成大规模并发连接压测。读完本文,你将掌握该测试容器的构建链路(Dockerfile、镜像配置)、服务端/客户端角色划分、完整的 Windows 端操作步骤,以及sock_stress系列工具的常见参数用法。

一、测试目标:验证 VM 与宿主之间的 socket 通道

LinuxKit 构建出的极简操作系统常以虚拟机形态运行(如 Hyper-V、HyperKit、QEMU 等)。当 guest 虚拟机与宿主机需要通信时,除了网络接口之外,还有一种更轻量的通道:virtio socket(vsock)与 Hyper-V socket(HvSocket / AF_HYPERV)。前者用于 virtio 类虚拟化平台,后者用于微软 Hyper-V 平台。

test/pkg/virtsock/README.md 所描述的就是一套针对这两类 socket 的**压力测试(stress test)**方案:

  • 目录内文件用于构建并运行一个容器,容器中装有 socket 压力测试程序;
  • 测试采用典型的server/client(服务端/客户端)模型:服务端运行在虚拟机内部,客户端运行在宿主机上(本文场景为 Windows);
  • 客户端会创建大量并发连接并向服务端发送随机数据,服务端回显数据,以此检验 virtio/Hyper-V socket 通道在高并发、短连接场景下的稳定性与吞吐表现。

二、测试套件在仓库中的组成

该测试套件由以下文件构成:

文件作用
test/pkg/virtsock/Dockerfile多阶段构建,产出内置压力测试程序的最小容器镜像
test/pkg/virtsock/build.ymlLinuxKit 包构建元数据,声明镜像名、架构与网络需求
test/pkg/virtsock/README.md使用说明(本文依据的原始文档)

从 README 的原始描述看,构建脚本原指向../../cases/test-virtsock-server.yml(按仓库根路径换算即test/cases/test-virtsock-server.yml),该 YAML 的作用是构建一个在虚拟机内启动服务端的镜像;不过在当前仓库树中该用例文件并未包含,镜像构建的实际可执行证据以 test/pkg/virtsock/build.yml 为准。build.yml 内容非常简洁:

image: test-virtsock network: true arches: - amd64

它声明了:

  • image: test-virtsock:构建出的镜像名;
  • network: true:镜像在构建/运行阶段需要网络能力(Dockerfile 中需要联网git clone源码);
  • arches: [amd64]:当前仅针对 amd64 架构构建(Hyper-V 场景通常为 x86_64 宿主)。

三、服务端镜像的构建链路:Dockerfile 深度解析

test/pkg/virtsock/Dockerfile 采用 LinuxKit 常见的多阶段构建模式,完整还原了服务端二进制sock_stress的产出过程:

第一阶段mirror(基础运行环境):

FROM linuxkit/alpine:7f3944798557de5518a56e3437d7ed982701f224 AS mirror RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/ RUN apk add --no-cache --initdb -p /out \ tini RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache
  • 基于 LinuxKit 官方 Alpine 基础镜像;
  • 仅安装tini(极简 init 进程,用于正确回收僵尸进程),并将 apk 元数据复制到/out,随后清理缓存,得到一个最小化的可运行根文件系统。

第二阶段build(编译 sock_stress):

FROM linuxkit/alpine:7f3944798557de5518a56e3437d7ed982701f224 AS build RUN apk add --no-cache go musl-dev git make ENV GOPATH=/go PATH=$PATH:/go/bin GO111MODULE=off ENV VIRTSOCK_COMMIT=f1e32d3189e0dbb81c0e752a4e214617487eb41f RUN mkdir -p $GOPATH/src/github.com/linuxkit && \ cd $GOPATH/src/github.com/linuxkit && \ git clone https://github.com/linuxkit/virtsock.git WORKDIR $GOPATH/src/github.com/linuxkit/virtsock RUN git checkout $VIRTSOCK_COMMIT RUN make bin/sock_stress.linux && \ cp -a bin/sock_stress.linux /sock_stress
  • 安装 Go、musl-dev(静态链接所需)、git 与 make;
  • 将VIRTSOCK_COMMIT固定到具体 commit(f1e32d3...),保证构建可复现——这是 LinuxKit 一贯的可复现构建实践;
  • 从 linuxkit/virtsock 仓库克隆源码并检出该 commit;
  • 执行make bin/sock_stress.linux编译出 Linux 端压力测试二进制,复制为/sock_stress。

第三阶段scratch(最终镜像):

FROM scratch COPY --from=mirror /out/ / COPY --from=build sock_stress usr/bin/sock_stress CMD ["/sbin/tini", "/usr/bin/sock_stress", "-s", "-v", "1"]
  • 基于scratch,仅包含 mirror 阶段的运行时文件与编译产物;
  • 最终容器启动命令为:tini sock_stress -s -v 1,其中-s表示使用**短连接(short-lived connections)**模式,-v 1表示输出级别/详细程度为 1;
  • 最终镜像内默认以服务端角色启动(sock_stress 不加-c即作为 server 监听)。

四、sock_stress 工具能力与参数说明

sock_stress是一个灵活的 socket 压力测试程序,从仓库内另一处脚本 test/pkg/ns/runc-net.sh 的注释与用法可以确认其能力边界:

"a flexible stress program for UDP/TCP/virtio/Hyper-V/Unix Domain sockets"

即它支持UDP / TCP / virtio socket / Hyper-V socket / Unix Domain Socket五类协议,且支持:

  • 多并发连接:多个连接同时建立;
  • 可配置数据量:客户端向服务端发送数据,服务端原样回显(echo);
  • 短连接 vs 长连接:通过配置每次连接传输的数据量,可以制造大量短生命周期连接(压测连接建立/拆除路径),默认则是随机且相对较大的数据量;
  • 角色可互换:服务端默认跑在容器/VM 内、客户端在外部,也可通过-r反转。

在 test/pkg/ns/runc-net.sh 中体现的sock_stress参数如下(该脚本主要用于网络命名空间压测,但参数语义与 virtsock 场景一致):

参数含义默认值
-p协议:tcp/udp/unixtcp
-ipIP 版本:4或64
-c并发连接数1
-s使用短连接(每个连接最多约 4 KiB 数据)关闭(长连接默认最多约 8 GiB/连接)
-i迭代次数20
-l单轮测试最长运行秒数,超时后杀掉进程10
-r反转角色(客户端放进容器/VM)关闭

从该脚本还可以看到短/长连接的数据量界定逻辑:

[ "$ARG_SHORT" = "1" ] && MAX_LEN=4096 || MAX_LEN=8388608

即:短连接模式下每个连接最多传输 4 KiB 数据,长连接模式最高可达 8 MiB(8388608 字节),从而可以构造"海量短连接"或"少量大流量"两类截然不同的压力形态。这正是 README 中"发送随机数据后拆除连接"这一行为的底层实现逻辑。

五、Windows 端完整操作步骤

原文档给出了在 Windows 宿主机(Hyper-V)上从零开始执行整套压测的完整流程,以下步骤逐条继承并补充说明。

5.1 构建服务端镜像

在 Linux 构建机上执行:

linuxkit build tests/cases/test-virtsock-server.yml

说明:

  • 该命令会依据 YAML 构建出可引导的镜像产物(其中包含test-virtsock容器镜像);
  • 产物中包括可用于 Hyper-V 引导的ISO 文件(test-virtsock-server.iso),这是因为 LinuxKit 会为 Hyper-V 平台输出 EFI 引导的 ISO 镜像。

注意:README 原文的构建入口指向tests/cases/test-virtsock-server.yml;当前仓库树中该文件未随本测试目录一并保留,若仓库版本与此 README 存在差异,请以仓库实际文件为准。test-virtsock镜像本身由 test/pkg/virtsock/build.yml 描述。

5.2 复制 ISO 到 Windows

将上一步产出的test-virtsock-server.iso拷贝到 Windows 系统上,供 Hyper-V 虚拟机挂载。

5.3 创建 Type 1 Hyper-V 虚拟机

在 Windows 上创建一台Type 1(第 1 代)Hyper-V 虚拟机,命名为virtsock,并注意以下要点:

  • 不需要磁盘(No Disk);
  • 不需要网络(No network required);
  • 将 ISO 挂载到CDROM 设备;
  • 为COM1(串口)启用命名管道,管道名称为virtsock。

命名管道的作用:LinuxKit 默认将内核与系统日志输出到串口,通过命名管道可将这些调试输出重定向到宿主机,便于观察 VM 内服务端的启动状态与运行日志。

5.4 启动虚拟机

在 Hyper-V 管理器中启动名为virtsock的虚拟机。VM 引导后,容器内的sock_stress会以服务端模式(-s -v 1)自动开始监听 virtio/Hyper-V socket 端口。

5.5 连接串口控制台获取调试输出

用 PuTTY 连接命名管道,观察 VM 内部调试输出:

putty -serial \\.\pipe\virtsock
  • -serial表示使用串口模式;
  • \\.\pipe\virtsock是上一步为 COM1 创建的命名管道路径;
  • 连接后即可看到 LinuxKit 启动日志以及 sock_stress 服务端的运行输出。

5.6 在宿主机运行压力客户端

打开 PowerShell,先取得 VM 的 ID(GUID),再运行编译好的 Windows 端客户端virtsock_stress.exe:

$vmId = (get-vm virtsock).Id .\virtsock_stress.exe -c $vmId -v 1 -c 1000000 -p 10

参数解读(结合原文档描述):

  • 第一个-c $vmId:指定连接目标,即 Hyper-V 虚拟机virtsock的 VM GUID(Hyper-V socket 以 VM GUID 作为寻址标识);
  • -v 1:输出详细程度;
  • 第二个-c 1000000:创建 1,000,000(一百万)个连接;
  • -p 10:使用 10 个并发线程/并发度。

该命令的效果是:由 10 个线程向 VM 发起总共 100 万次连接,每次连接建立后随机传输一定量的数据,随后拆除连接。原文档明确说明 "There are more options to change the behaviour",即客户端还有更多可调选项(连接数、线程数、数据量、输出级别等)。

六、压测背后的原理与预期行为

结合 test/pkg/virtsock/Dockerfile 与 test/pkg/ns/runc-net.sh 的实现,可以梳理出整套测试的数据流:

  1. VM 引导后,tini拉起sock_stress -s -v 1,进程进入监听状态(server 模式,短连接语义);
  2. Windows 宿主机上的virtsock_stress.exe通过 Hyper-V socket 通道向 VM 的 socket 端口发起连接;
  3. 客户端在每条连接上写入随机长度的数据,服务端读取并回显(echo);
  4. 数据传输完毕后连接被拆除,客户端继续创建下一条连接,直至完成设定的连接总数。

通过"短连接 + 海量连接 + 随机数据量"的组合,可以重点暴露以下问题:

  • 大量连接建立/拆除时,vsock 通道的连接管理开销与稳定性;
  • 随机数据量下缓冲区与流量控制是否正确;
  • 高频并发下VM 内 sock_stress 服务端的吞吐与资源占用;
  • VM 内极简 init(tini)在大量短生命周期 socket 下的进程/资源回收是否正常。

七、与 linuxkit run hyperv 的关联

在 LinuxKit 主工具链中,src/cmd/linuxkit/run_hyperv.go 提供了linuxkit run hyperv命令,可直接在 Windows 上启动 Hyper-V 虚拟机。从该源码可以看到与 README 场景相互印证的设计:

  • 默认创建Generation 2(第 2 代)虚拟机(New-VM -Generation 2),且-NoVHD表示不预置磁盘;
  • 支持通过参数指定-SwitchName(虚拟交换机)与内存、CPU 等资源配置;
  • 该命令期望输入的是EFI ISO 文件路径,与 README 中"将 ISO 挂载到 CDROM"的操作一致。

也就是说,除了 README 中"手动创建 VM"的方式外,linuxkit run hyperv也提供了一条自动化的替代路径(当前仓库中该命令的实现面向 Generation 2 VM,而 README 手把手流程使用 Type 1 VM,两者引导方式不同,读者可按需选择)。

八、后续扩展方向(原文档 TODO)

原文档列出了该测试套件的四项后续工作,目前仍可作为演进参考:

  1. 增加自动创建 Hyper-V 虚拟机的脚本:当前 VM 创建依赖手工操作(New-VM / Set-VM / Add-VMDvdDrive 等 PowerShell 命令);
  2. 在linuxkit run(配合 HyperKit)中启用 virtio socket 支持:使 macOS 场景也能一键跑通 vsock 压测;
  3. 补充从 VM 连接宿主机的示例客户端 YAML:当前方案是"宿主机连 VM",反向场景(VM 内客户端连宿主机服务端)的示例尚未提供;
  4. 接入 CI:将 virtio(HyperKit)与 Hyper-V 两套环境的压测接入持续集成,回归验证 vsock 通道的稳定性。

九、相关仓库资源索引

如需进一步研究,可在本仓库中继续阅读:

  • 测试套件本体:test/pkg/virtsock/Dockerfile、test/pkg/virtsock/build.yml、test/pkg/virtsock/README.md
  • sock_stress 在另一类压测场景中的用法:test/pkg/ns/runc-net.sh
  • Hyper-V 虚拟机自动化启动实现:src/cmd/linuxkit/run_hyperv.go
  • Hyper-V 平台整体使用文档:docs/platform-hyperv.md

小结

LinuxKit 的 virtio/Hyper-V socket 压测方案是一条"构建最小镜像 → VM 内跑服务端 → 宿主机跑客户端 → 海量并发连接"的完整链路:服务端镜像由 test/pkg/virtsock/Dockerfile 以可复现的多阶段构建产出,客户端在 Windows 上通过 Hyper-V socket 直连 VM GUID,最终以百万级连接、多线程、随机数据量的组合检验 vsock 通道在高压力下的正确性与稳定性。无论是手动创建 Type 1 VM 走命名管道调试,还是借助linuxkit run hyperv自动化,其核心思路一致:用最小化的 LinuxKit 系统,聚焦验证一条主机与虚拟机之间的高速通信通道。

  • 操作系统
  • 云原生
  • 容器运行时

【免费下载链接】linuxkit

A toolkit for building secure, portable and lean operating systems for containers

项目地址:https://gitcode.com/gh_mirrors/li/linuxkit
点击查看免费下载

相关推荐

上一篇:深入理解svmjs的SMO算法实现:JavaScript机器学习的底层逻辑
下一篇:BELLE-开源生态系统:相关工具库与扩展项目汇总

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询