首页
/ Kubernetes Windows E2E 测试指南:从 [sig-windows] 用例集到密度测试的源码级解析

Kubernetes Windows E2E 测试指南:从 [sig-windows] 用例集到密度测试的源码级解析

2026-09-07 14:19:30作者:尤峻淳Whitney

本文基于 Kubernetes 仓库中的 test/e2e/windows/README.md,讲解如何在一套包含 Windows 节点的集群上运行 SIG-Window 端到端(E2E)测试:包括准备 KUBECONFIG 与测试镜像仓库清单 KUBE_TEST_REPO_LIST 等前置条件、使用 --ginkgo.focus 精确筛选 [sig-windows] 用例的完整命令行,以及这些 Windows 专属 E2E 测试在源码层面如何通过 Feature 标记、OS 分发跳过机制和密度测试(Density Test)实现“只在 Windows 节点上运行”的隔离逻辑。读完后,你可以独立搭好 Windows 节点 E2E 测试环境,并能定位到每个测试用例、跳过逻辑与性能阈值在仓库中的具体实现位置。

一、前置条件:KUBECONFIG 与测试镜像仓库清单

原文档给出的前置步骤是:

KUBECONFIG=path/to/kubeconfig
curl https://raw.githubusercontent.com/kubernetes-sigs/windows-testing/master/images/image-repo-list -o repo_list
export KUBE_TEST_REPO_LIST=$(pwd)/repo_list

这里做了三件事:

  1. KUBECONFIG 指向目标集群的 kubeconfig,该集群必须至少包含一个可调度 Windows Pod 的 Windows 节点(带 kubernetes.io/os=windows 标签)。后续所有测试框架的跳过判断都依赖这一点。

  2. 拉取 Windows 测试镜像清单curl 下来的 image-repo-list 是一份 YAML,用于将 E2E 测试所用镜像重定向到 Windows 可运行的镜像仓库(例如 mcr.microsoft.com 上的 Windows 版本 pause/agnhost 镜像)。

  3. 导出 KUBE_TEST_REPO_LIST:这是测试框架识别镜像重写配置的正式入口。可以在 test/e2e/framework/test_context.go#L361 看到对应 flag 的定义:

    flags.StringVar(&TestContext.KubeTestRepoList, "kube-test-repo-list", "",
        "A yaml file used for overriding registries for test images. " +
        "Alternatively, the KUBE_TEST_REPO_LIST env variable can be set.")
    

    也就是说 --kube-test-repo-list flag 与 KUBE_TEST_REPO_LIST 环境变量等价。更详细的镜像仓库重写机制说明见 test/images/README.mdrepo_list.yaml 中每行形如 promoterE2eRegistry: your-registry,E2E 测试在拉取镜像时会按该映射替换注册表前缀。

二、运行 Windows E2E 测试的命令

原文档给出的运行命令是:

./e2e.test --provider=local \
    --ginkgo.no-color \
    --ginkgo.focus="\[sig-windows\]|\[Feature:Windows\]" \
    --node-os-distro="windows"

各参数含义:

参数 作用
--provider=local 使用本地已有的 kubeconfig(即 KUBECONFIG)而非云上 provider 创建集群
--ginkgo.no-color 禁用彩色输出,便于 CI 日志收集
--ginkgo.focus Ginkgo 的正则焦点,只匹配描述中含 [sig-windows][Feature:Windows] 的用例
--node-os-distro=windows 告诉测试框架节点 OS 分发为 Windows,是 SkipUnlessNodeOSDistroIs 判断的数据来源

这个 focus 正则能精确命中,是因为 Windows 测试套件的每个用例都打上了这两个标签,二者分别来自:

  • [sig-windows]:由测试包的 SIGDescribe 注入,见 test/e2e/windows/framework.go#L31

    // sigDescribe annotates the test with the SIG label.
    var sigDescribe = framework.SIGDescribe("windows")
    
  • [Feature:Windows]:由 Ginkgo Feature 标签注入,Feature 定义在 test/e2e/feature/feature.go

    // Owner: sig-windows
    // Indicates that tests labeled with this feature depend on Windows and thus may only be run on Windows nodes.
    Windows = framework.WithFeature(framework.ValidFeatures.Add("Windows"))
    

    典型的用例注册方式(见密度测试 test/e2e/windows/density.go#L44):

    var _ = sigDescribe(feature.Windows, "Density", framework.WithSerial(), framework.WithSlow(),
        skipUnlessWindows(func() { ... }))
    

三、skipUnlessWindows:确保用例只在 Windows 节点上执行

framework.go 中的核心封装是 skipUnlessWindows

// skipUnlessWindows wraps some other Ginkgo callback such that
// a BeforeEach runs before tests defined by that callback which
// skips those tests unless the node OS is Windows.
func skipUnlessWindows(cb func()) func() {
    return func() {
        ginkgo.BeforeEach(func() {
            // all tests in this package are Windows specific
            e2eskipper.SkipUnlessNodeOSDistroIs("windows")
        })
        cb()
    }
}

它包了一层 BeforeEach,在每个用例开始前调用 SkipUnlessNodeOSDistroIs("windows")。该函数实现在 test/e2e/framework/skipper/skipper.go#L151-L156

func SkipUnlessNodeOSDistroIs(supportedNodeOsDistros ...string) {
    if !framework.NodeOSDistroIs(supportedNodeOsDistros...) {
        skipInternalf(1, "Only supported for node OS distro %v (not %s)",
            supportedNodeOsDistros, framework.TestContext.NodeOSDistro)
    }
}

framework.TestContext.NodeOSDistro 正是运行命令中 --node-os-distro=windows 写入的值。因此形成一条完整的保护链:命令行声明 OS → skipper 比对 → 非 Windows 环境自动跳过,再叠加 focus 正则,保证这套用例既能在通用 E2E 流程中安全混跑(自动 skip),又能被单独精确拉出来跑。

四、Windows E2E 用例全景

test/e2e/windows/ 目录下的文件即全部用例模块,覆盖了 Windows 节点的主要能力面:

文件 覆盖主题
cpu_limits.gomemory_limits.go CPU/内存限额与调度行为(Hyper-V 下内存限额有平台限制)
hyperv.go Hyper-V 隔离容器(对应 Feature WindowsHyperVContainers
host_process.go HostProcess 容器(Feature WindowsHostProcessContainers
gmsa_full.gogmsa_kubelet.go Windows GMSA 组托管服务账户认证
hybrid_network.go 混合网络(Linux 节点 + Windows 节点 Service 互通)
eviction.gonode_shutdown.goreboot_node.go 驱逐、节点计划关闭、重启等生命周期场景
security_context.godns.goservice.govolumes.gosubpath_cleanup.godevice_plugin.gokubelet_stats.godensity.go 安全上下文、DNS、Service、卷挂载、SubPath 清理、Device Plugin、kubelet 统计与密度

配套工具函数集中在 utils.go,其中包含几处值得注意的工程细节:

  • skipUnlessContainerdOneSevenOrGreater:要求 Windows 节点运行 containerd 1.7+,否则跳过(test/e2e/windows/utils.go#L90-L106);
  • windowsTestMemorySafetyBuffer(256 MiB):在内存容量边界测试中预留固定头寸,吸收 kubelet/cgroup 内存记账漂移,避免在容量边界产生 flaky 的 OutOfmemory 调度错误(test/e2e/windows/utils.go#L108-L119);
  • detectPodOverheadMemory:通过一次 DryRun Pod 创建探测集群准入链是否注入了 Pod Overhead 内存,并缓存结果用于后续容量计算(test/e2e/windows/utils.go#L136-L183)。

五、Density 密度测试:从 e2e_node 借来的 Windows 版

原文档第二节说明:e2e_node/density_test diff —— “该测试借自 e2e_node/density_test,除第一个测试外的其余测试以及部分日志均被省略”。对应实现即 density.go,其核心参数与流程:

5.1 测试参数与性能阈值

dTests := []densityTest{
    {
        podsNr:   10,
        interval: 0 * time.Millisecond,
        // percentile limit of single pod startup latency
        podStartupLimits: e2emetrics.LatencyMetric{
            Perc50: 30 * time.Second,
            Perc90: 54 * time.Second,
            Perc99: 59 * time.Second,
        },
        // upbound of startup latency of a batch of pods
        podBatchStartupLimit: 10 * time.Minute,
    },
}

即:一次性并发创建 10 个 Pod,单个 Pod 启动延迟的 P50/P90/P99 分别不得超过 30s/54s/59s,整批启动不得超过 10 分钟。源码注释明确指出这些值比较宽松(TODO(coufon): the values are generous, set more precise limits with benchmark data),后续将用基准数据收紧。

5.2 执行流程

  1. 创建测试 PodnewDensityTestPods 生成 10 个 pause 镜像 Pod,并带 NodeSelector: kubernetes.io/os=windows,保证全部调度到 Windows 节点(density.go#L246-L248);
  2. 建立 WatchnewInformerWatchPod 用 client-go 的 cache.NewInformer + ListWatch 按标签 type=density_test_pod 监听 Pod 状态,当 Pod 变为 Running 时记录时间戳(density.go#L174-L221);
  3. 批量创建createBatchPodWithRateControl 为每个 Pod 起一个 goroutine 并发创建,interval 用于吞吐控制(当前为 0)(density.go#L164-L172);
  4. 等待与断言:在 10 分钟内等待 Watch 观察到全部 10 个 Pod Running,计算每个 Pod 的端到端延迟与整批延迟(lastRunning - firstCreate),随后 deletePodsSync 并发删除并等待所有 Pod 消失。

该用例注册在 framework.WithSerial() + framework.WithSlow() 下(串行且不计入 P0 快速套件),与 README 中“只保留第一个测试”的裁剪说明一致。

六、小结:如何把这套流程用起来

把原文档浓缩为可复现的操作序列:

# 1. 指向含 Windows 节点的集群
export KUBECONFIG=path/to/kubeconfig

# 2. 准备 Windows 镜像清单并交给测试框架
curl https://raw.githubusercontent.com/kubernetes-sigs/windows-testing/master/images/image-repo-list -o repo_list
export KUBE_TEST_REPO_LIST=$(pwd)/repo_list

# 3. 只运行 [sig-windows] 相关 E2E 用例
./e2e.test --provider=local --ginkgo.no-color \
    --ginkgo.focus="\[sig-windows\]|\[Feature:Windows\]" \
    --node-os-distro="windows"

适用前提:集群中至少存在一个可运行的 Windows 节点(带 kubernetes.io/os=windows 标签);e2e.test 为编译好的 E2E 二进制(可按 test/images/README.md 的说明用 ./build/run.sh make WHAT=test/e2e/e2e.test 编译);KUBE_TEST_REPO_LIST 指向的清单必须包含 Windows 平台可用的测试镜像,否则 Pod 拉取镜像会失败。所有 Windows 专属行为——SIG 标签、Feature 标记、OS 跳过、密度阈值——都可以直接回溯到 test/e2e/windows/ 包内的源码进行验证。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395