ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Kubernetes 测试策略实战指南:从测试金字塔到 Prow CI 作业设计

Kubernetes 测试策略实战指南:从测试金字塔到 Prow CI 作业设计 Kubernetes 测试策略实战指南从测试金字塔到 Prow CI 作业设计【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community本文基于 Kubernetes Community 仓库中的 testing-strategy.md 编写系统讲解 Kubernetes 社区在多年 CI 实践中沉淀出的测试策略方法论如何用测试金字塔分配测试投入、如何设计 Prow 的 presubmit / postsubmit / periodic 作业、如何设置发布门禁与缓解 E2E 抖动并给出可直接落地的 Prow CI 配置示例。读完本文你将掌握为 Kubernetes 功能特性规划一套稳健、可维护、低抖动测试体系的核心方法并能在自己的集群项目中复用它。一、测试金字塔测试投入的优先级框架testing-strategy.md开篇即以测试金字塔作为组织测试的核心隐喻。它强调金字塔不是死板的处方而是一个帮助可视化的通用指南用于构建平衡且有效的测试策略。金字塔自下而上分为三层每一层都有明确的定位与取舍单元测试Unit Tests——金字塔的地基要求快一个包应当能在数秒内跑完其全部单元测试、隔离不依赖环境或非本地网络覆盖单个组件。它们是成本最低、反馈最快的测试层级。集成测试Integration Tests验证子系统内部各组件之间的交互。当需要以测试专属配置运行集群组件时优先选择这一层。E2E 测试End-to-End Tests测试整个系统包括与外部依赖的交互。这是最昂贵、最易抖动的层级每一个集群组件配置变体都对应一个独立的 e2e 作业。Kubernetes 社区在 testing.md 中为金字塔的各层提供了配套的执行入口可以与本策略文档互为印证单元测试入口make test是运行全部单元测试的标准入口它会正确设置GOPATH遇到 timeout panic 时可通过make test KUBE_TIMEOUT-timeout300s放宽超时用WHAT限定包范围如make test WHAT./pkg/kubelet追加...可覆盖子包用KUBE_TEST_ARGS-run ^TestValidatePod$定位单个用例用PARALLEL2 ITERATION5做压力重复运行以排查抖动用KUBE_COVERy生成 HTML 覆盖率报告。集成测试入口make test-integration会通过test-integration.sh包装make test并拉起一个 etcd 实例供测试连接依赖安装可用仓库提供的hack/install-etcd.sh测试数据目录可用TEST_ETCD_DIR环境变量覆盖见 integration-tests.md。E2E 测试体系基于 Ginkgo/Gomega 的 BDD 框架构建细节见 e2e-tests.md。注意本仓库是 Kubernetes Community 的文档仓库上述make test等命令面向的是kubernetes/kubernetes主代码库。策略文档本身不限定具体工具但给出了社区实践的权威参考。二、Prow CI 作业类型全景Kubernetes 的 CI 系统由Prow实现社区文档 testing.md 中说明了 PR 提交后 Prow 会自动运行预提交测试。testing-strategy.md将作业划分为四类职责清晰作业类型触发时机核心用途Presubmit预提交代码合并前把关待合入的变更Postsubmit后提交代码合并后构建产物等后续任务Periodic周期按计划时间间隔监控趋势、捕捉回归其中Presubmit 又细分为两类这是全文最关键的设计决策点Blocking阻塞式测试失败即阻止合并。由于影响范围是项目级的这类作业必须谨慎启用社区对其稳定性、可靠性与性能要求非常高的门槛high bar并需要提供证据。Non-Blocking / Informational非阻塞 / 告知式只提供反馈不阻止合并。2.1 Presubmit Blocking 作业为何必须永远运行文档给出了一个非常具体的理由链阻塞式 presubmit 作业必须始终运行must always run。如果某次 PR 未触发该作业就合并一旦它引入了回归那么该作业在后续其它 PR 上运行时就会失败导致后续 PR 即使本身值得合入也无法合并直到回归被修复。也就是说作业的缺席会演变成全项目的合并瓶颈。2.2 Non-Blocking 作业更早发现问题但需约束非阻塞作业默认不运行通常需要显式使用/test命令触发。不过也可以配置为当特定路径被修改时自动运行testing-strategy.md中给出了 sig-node 预提交作业配置的实例。为什么仍然需要非阻塞作业因为非阻塞作业无法发现所有回归一个测试抖动flake在 presubmit 阶段只运行一次时可能恰好通过定义路径触发器时不可能穷举所有可能需要跑测试的原因例如工具链变化、依赖包升级。因此必须配套一个定期运行相同测试的 periodic 作业作为兜底。非阻塞作业的核心价值在于更早暴露问题如果没有它维护者只能等到 periodic 作业发现回归再回头 ping 造成问题的贡献者若贡献者不响应维护者被迫亲自修复。而有了非阻塞作业负担落在 PR 失败的贡献者身上——如果他们不响应变更就不会被合并也就不会产生回归。此外对某些变更自动运行非阻塞作业还有一个收益审查者无需记忆合并前该跑哪些作业而且贡献者作为社区成员提交后测试会自动运行审查者首次查看 PR 时结果已就绪。⚠️警告失败的非阻塞作业会迷惑不熟悉该作业或其失败模式的贡献者若触发过于频繁则会浪费 CI 资源。为此社区为自动触发的非阻塞 presubmit 作业制定了四条硬性准则作业负责人响应迅速能及时处理作业问题作业必须有低失败率避免在路过式drive-byPR 中制造困惑特性的重要性必须足以 justify 额外的 CI 资源消耗取决于触发频率run_if_changed正则表达式必须足够窄避免为无关变更运行作业。好的实践是将其限定在代码变更上例如/(directory_a|directory_b)/.*\.go三、发布门禁SIG Release 的 Blocking 与 Informing 作业除了 presubmit 层面的阻塞SIG Release 还维护着两套决定发布健康度的作业集合Blocking与Informing。如果你的特性或领域对发布至关重要社区要求按照sig-release仓库中release-blocking-jobs.md的指引将你的 periodic 作业提升为 Blocking 或 Informing。testing-strategy.md给出了两条重要的进阶约束Presubmit Blocking 作业的前提条件它本身必须同时是 Release Blocking 作业速度要求Presubmit Blocking 作业应比 Release Blocking 作业更快——控制在 1 小时以内最好 30 分钟以内。文档特别强调了一个务实的升级标准只有当我们频繁地在发布阻塞作业被破坏之后才识别出 bug 时才值得把作业提升为 presubmit blocking。每个发布周期只发生几次并不构成充足理由——此时更经济的做法是使用 Testgrid 对通过/失败之间的合并提交做 bisect然后 revert 或修复相关 PR。原因也很直白presubmit blocking 作业比 release blocking 作业昂贵得多——它们必须在每次推送的 PR 上运行而不仅是已合并代码一旦出问题会干扰所有贡献者所以社区不会轻易新增 presubmit blocking 作业。四、缓解 E2E 测试抖动Flakiness的四个手段E2E 测试尤其在 Kubernetes 这种复杂项目中极易因外部依赖而抖动。testing-strategy.md给出了四个缓解方向识别模式Identify Patterns利用 periodic 作业与 Testgrid 监控测试结果识别失败模式隔离失败Isolate Failures改进测试隔离最小化外部因素影响重试机制Retry Mechanisms在 CI 作业中实现重试以处理瞬时失败。但必须清晰区分哪些是可重试错误——否则有掩盖真实 bug 的风险而这些 bug 最终会出现在生产集群中健壮的基础设施Robust Infrastructure确保测试基础设施本身可靠稳定。4.1 仓库中对抖动治理的更深层支撑在同一个目录下的 flaky-tests.md 进一步定义了社区的零抖动zero-flake政策自 2019 年起测试作业不得对测试失败自动重试例如 e2e 测试中不再允许ginkgo.flakeAttempts2。这与策略文档明确区分可重试错误的告诫相互呼应——自动重试会掩盖真实回归。具体到隔离手段e2e-tests.md 描述了测试标签体系[Slow]超过 5 分钟、[Serial]不能并行、[Disruptive]可能影响无关负载隐含串行、[Flaky]已知抖动、默认不运行、[Feature:.]、[FeatureGate:.]、[Conformance]等。在策略层面对单个抖动用例的隔离做法是给测试名加上[Flaky]绝大多数 CI 作业会排除这些用例对整组测试的隔离则是打上[Feature:Foo]标签并为其单独创建聚焦作业。五、面向特定功能/领域的测试策略如果你的关注点是 Kubernetes 内某个特定功能或领域你有责任确保这些测试 a) 在 CI 中运行b) 保持健康。策略文档明确划清了责任边界SIG Testing 提供的是运行测试的工具tooling但不负责运行具体的测试——运行与维护特定测试的职责在功能所有者身上。这在本仓库的 OWNERS 中也有迹可循sig-testing目录由sig-testing-leads作为 reviewers / approvers 把关体现了工具治理与功能所有权分离的组织模式。针对功能所有者的推荐策略分两步1. Periodic 作业承担主要回归检测周期性运行昂贵的 E2E 测试例如每 6 小时一次使用 Testgrid 监控趋势并订阅告警——Testgrid 能在 Kubernetes 其他部分的变更破坏你的特性时提供早期信号告警订阅帮助你在问题扩散前定位模式并有效排查。2. 非阻塞 Presubmit 作业提供软门禁通过run_if_changedProw 的基于变更触发作业机制配置作业仅在特定文件或目录被修改时运行使用OWNERS 文件要求相关代码库维护者审批——这构成一个软阻塞soft block在不冒全项目停摆风险的前提下确保审查与问责这种方式鼓励维护者对自己代码的质量与稳定性负责。关于 Testgrid 的进一步用法dashboards、告警响应流程、flaky 问题上报规范可参阅同目录的 monitoring.md。六、可复制的 CI 配置示例presubmit periodic 双作业testing-strategy.md在结尾给出了一个基础的 Prow CI 配置示例。文档提醒实际 CI 作业配置数量庞大且依赖多个因素原文拼写为 facvtos即 factors此示例必须按你的具体需求调整。以下完整保留原文配置并逐字段注解presubmits: kubernetes/my-feature: - name: my-feature-e2e-tests always_run: false # 非默认运行仅在命中 run_if_changed 时触发 run_if_changed: my-feature/**/* # 仅当 my-feature 目录下文件变更时触发 optional: true # 非阻塞optional作业失败不阻止合并 decorate: true # 使用 Prow 的 decorate 模式接管容器编排 path_alias: kubernetes/my-feature # 导入路径别名保持 go import 路径一致 spec: containers: - image: gcr.io/k8s-testimages/kubekins-e2e:v20241104-master-5917669-master command: - runner.sh - ./test/e2e.sh args: # 运行带有 MyFeature 标签的测试且只运行这些 -ginkgo.label-filterFeature: containsAny MyFeature Feature: isSubsetOf MyFeature !Flaky annotations: testgrid-dashboards: sig-my-feature # 结果聚合到 Testgrid 的 sig-my-feature 面板 testgrid-tab-name: My Feature E2E Tests # Testgrid 中的标签页名称 periodics: kubernetes/my-feature: - name: my-feature-periodic-e2e-tests interval: 6h # 每 6 小时运行一次覆盖 presubmit 无法发现的回归 decorate: true path_alias: kubernetes/my-feature spec: containers: - image: gcr.io/k8s-testimages/kubekins-e2e:v20241104-master-5917669-master command: - runner.sh - ./test/e2e.sh args: - -ginkgo.label-filterFeature: containsAny MyFeature Feature: isSubsetOf MyFeature !Flaky annotations: testgrid-dashboards: sig-my-feature testgrid-tab-name: My Feature Periodic E2E Tests6.1 配置要点解读always_run: falserun_if_changed两者组合实现了按路径触发的非阻塞预提交作业对应本文第五节第 2 条策略。run_if_changed的正则必须窄到不会为无关变更触发第五节中的/(directory_a|directory_b)/.*\.go是社区推荐形态。optional: true与Blocking相对失败不影响合并同时配合 periodic 兜底正是非阻塞作业 周期作业组合的落地形态。ginkgo.label-filter使用 Ginkgo 标签过滤Feature: containsAny MyFeature选取包含该特性标签的用例Feature: isSubsetOf MyFeature进一步限定只属于该特性!Flaky排除已知抖动用例——这是社区从--ginkgo.focus/skip正则迁移到标签过滤Kubernetes v1.29 起 Ginkgo v2 标签后的标准写法。annotationstestgrid-dashboards / testgrid-tab-name把作业结果投射到 Testgrid 面板使功能所有者能持续监控趋势、订阅告警——对应第四节识别模式与第五节periodic 作业监控的要求。从本仓库 testing.md 可以看到这一配置思想的端到端闭环PR 提交后 Prow 自动运行预提交测试 → 测试产物test results、junit xml、集群日志等经Details链接可回溯排查 → Testgrid 将结果可视化为网格供持续监控 → 抖动问题按 flaky-tests.md 的规范上报与治理。七、总结从策略到落地的完整链路testing-strategy.md的核心理念可浓缩为一条决策链按金字塔分配投入单元测试求快求稳、集成测试验证子系统交互、E2E 测试作为最终信号但必须为每种集群配置变体单独建作业作业分层控制风险presubmit blocking 必须始终运行且需高门槛审批non-blocking 用run_if_changed按需触发并配套 periodic 兜底postsubmit 负责产物构建发布门禁与 CI 门禁分离Presubmit Blocking 需同时是 Release Blocking且要更快1 小时最好 30 分钟升级须基于频繁暴露 bug 的证据抖动治理靠监控与隔离而非重试Testgrid 识别模式、明确可重试错误边界、必要时以[Flaky]标签隔离职责下沉SIG Testing 提供工具功能所有者负责自己测试的运行与健康并通过 OWNERS 形成软门禁。该文档与其配套的 testing.md、integration-tests.md、e2e-tests.md、flaky-tests.md、monitoring.md 与 verify-tests.md 共同构成了 Kubernetes 社区完整的测试知识体系是规划任何中大型云原生项目测试策略时的优质参考。【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表