Kubernetes面向所有人的端到端测试

作者: Patrick Ohly(英特尔)

现在越来越多的组件成为Kubernetes的一部分 在Kubernetes之外开发。例如,存储驱动程序 曾经被编译成Kubernetes二进制文件,然后被转移到 独立式FlexVolume binaries 在主机上,现在作为 集装箱存放接口 (CSI) 司机 部署在Kubernetes集群本身内部的Pod中。

这对使用此类组件的开发人员构成了挑战:如何 可以在Kubernetes集群上进行端到端(E2E)测试吗 外部组件?用于测试的E2E框架 Kubernetes本身具有所有必要的功能。但是,尝试 在Kubernetes之外使用它是困难的,只有通过 仔细选择大量的正确版本 依赖性。在Kubernetes 1.13中,端到端测试变得非常简单。

这篇博客文章总结了Kubernetes的变化 1.13。对于CSI驱动程序开发人员,它将涵盖正在进行的工作,以 还使存储测试可用于测试第三方CSI 司机。将基于两个英特尔CSI驱动程序显示如何使用它们:

测试这些驱动程序是其中大多数驱动程序的主要动机 enhancements.

端到端概述

端到端测试包括以下几个阶段:

  • 实施测试套件。这是此博客的主要重点 发布。 Kubernetes E2E框架是用Go编写的。它依靠 银杏 用于管理测试和 戈麦加 断言。这些工具 支持“行为驱动的开发”,它描述了预期的 “规范”中的行为。在此博客文章中,“测试”用于引用 an individual 银杏.It spec. Tests interact with 的 Kubernetes cluster using 客户去.
  • 建立一个测试集群。像这样的工具 kubetest在这里可以提供帮助。
  • 针对该集群运行E2E测试套件。银杏测试套件 can be run with 的 ginkgo tool or as a normal Go 测试 with go 测试. Without 一个y parameters, a Kubernetes E2E 测试 套房 will 根据环境变量连接到默认集群,例如 KUBECONFIG,与kubectl完全一样。 Kubetest还知道如何运行 Kubernetes E2E套件

Kubernetes 1.13中的E2E框架增强功能

以下所有增强功能都遵循相同的基本模式: 使E2E框架更有用,更易于在外部使用 Kubernetes,而不会更改原始Kubernetes的行为 e2e.test binary.

拆分提供商支持

使用Kubernetes的E2E框架的主要原因<= 1.12 依赖于特定于提供商的SDK是很困难的 拉进了大量的包裹。只是编译它是 non-trivial.

其中的许多软件包仅在某些测试中才需要。例如, 测试预先配置的卷的安装必须首先进行设置 这样的音量与管理员通过交谈相同 通过一些非Kubernetes API直接连接到特定的存储后端。

有努力 删除特定于云提供商的 tests 从 核心Kubernetes。采取的方法 公关 #68483 可 被视为实现该目标的渐进式步骤:而不是淘汰 立即执行代码并破坏所有依赖于它的测试 云提供商特定的代码已移至 测试/ e2e /框架/提供者。的 然后,端到端框架通过 一个 interface 由每个供应商软件包分别实施。

E2E测试套件的作者决定要获得这些软件包中的哪些 导入测试套件。然后通过激活供应商支持 the --provider command line flag. 的 Kubernetes e2e.test binary in 1.13和1.14仍然支持与中相同的提供程序 1.12。也可以不包含任何软件包,这意味着仅 通用提供程序将可用:

  • “骨架”:通过Kubernetes API访问集群,什么也没有 else
  • “本地”:类似于“ skeleton”,但除此之外, 测试后kubernetes / kubernetes / cluster可以通过ssh检索日志 suite is run

外部档案

测试可能必须在运行时读取其他文件,例如.yaml 表现。但是Kubernetes e2e.test二进制文件应该可用 完全独立,因为这简化了运输和运行 它。 Kubernetes构建系统中的解决方案是链接所有文件 under 测试/e2e/testing-manifests into 的 binary with go-bindata。的 过去,端到端框架对产品的输出有严格的依赖性 go-bindata,现在 绑定支持是 optional。什么时候 通过访问文件 测试文件 package, 文件将从不同的来源检索:

  • relative to 的 directory specified with --repo-root parameter
  • 零个或多个绑定块

测试参数

e2e.test二进制文件带有用于控制测试的其他参数 执行。 2016年,开始着手更换所有端到端命令 Viper配置文件添加行参数。但是那努力 停滞不前,这使开发人员没有明确的指导,他们应该如何处理 测试专用参数。

v1.12中的方法是将所有标志添加到中央 测试 / e2e / framework / 测试_context.go, 不适用于独立于 framework. Since 公关 #69105 的 recommendation has been to use 的 normal flag 包 to 在自己的源代码中定义其参数。标志名称必须是 分层的点分隔不同级别,例如 my.test.parameter,并且必须是唯一的。唯一性是由 flag 再次注册标志时会感到恐慌的软件包。的 new 配置 软件包简化了多个选项的定义,这些选项是 存储在单个结构中。

总而言之,这是现在处理参数的方式:

  • 测试包中的初始化代码定义了测试和参数。的 actual parameter 价值观 尚不可用,因此测试定义 cannot use 的m.
  • 测试套件的初始化代码解析参数和(可选) 配置文件。
  • 运行测试,现在可以使用参数值。

但是最近 被指出 out 这是理想的,并且可能不会将测试设置公开为 命令行标志,并且只能通过配置文件进行设置。那里 is 一个 打开错误 和一个 待定公关对这个。

per蛇支持得到增强。像提供商支持一样, 完全可选。它被拉入e2e.test二进制文件中 importing 的 viperconfig 包 一个d 呼唤 it 解析正常的命令行标志后。这已经实现 这样所有可以通过命令行标志设置的变量 当标志出现在Viper配置文件中时设置。例如, Kubernetes v1.13 e2e.test binary accepts --viper-config=/tmp/my-config.yaml 该文件将设置 my.test.parameter to value when 它 has this content: my: 测试: parameter: value

在较早的Kubernetes版本中,该选项只能从以下位置加载文件 在当前目录中,必须省略后缀,只有几个 参数实际上可以通过这种方式设置。当心一个限制 的Viper仍然存在:它通过匹配配置文件条目来工作 针对已知标志,而不发出有关未知配置文件条目的警告 从而使错别字未被发现。一种 更好的配置文件 parser 对于 Kubernetes仍在开发中。

从.yaml清单创建项目

在Kubernetes 1.12中,有一些支持加载个人 .yaml文件中的项目,但随后必须通过以下方式创建该项目 手写代码。现在框架有了 新 methods 用于加载包含多个项目的.yaml文件并修补这些项目 (例如,设置为当前测试创建的名称空间),以及 创建它们。这是目前 用于部署CSI drivers 从完全相同的.yaml文件为每个测试重新 用于通过kubectl进行部署。如果CSI驱动程序支持运行 用不同的名字,那么测试是完全独立的,并且可以 run in parallel.

但是,重新部署驱动程序会减慢测试的执行速度,并且确实会 不涵盖针对驱动程序的并发操作。更现实 测试方案是在启动测试时部署一次驱动程序 群集,然后针对该部署运行所有测试。最终 一旦更清楚地知道如何将Kubernetes E2E测试转移到该模型 可以扩展测试群集启动,使其也包括 安装其他实体,例如CSI驱动程序。

Kubernetes 1.14中即将推出的增强功能

重用存储测试

能够在Kubernetes之外使用框架可以构建 定制的测试套件。但是没有测试的测试套件仍然 无用。一些现有的测试,尤其是针对存储的测试,可以 也适用于树外组件。多亏了 Masaki Kimura, 存储 testsKubernetes 1.13中的定义使得可以实例化它们 多次针对不同的驱动程序。

但是历史有重演的习惯。与提供者一样, 定义这些测试的程序包还引入了所有驱动程序的定义 树内存储后端,这反过来又增加了更多 包超过所需。这是 固定 为了 即将推出的Kubernetes 1.14。

跳过不受支持的测试

一些存储测试取决于群集的功能(例如 在支持XFS的主机上运行)或驱动程序(如支持 块体积)。在测试运行时会检查这些条件, 如果不满意,则会导致跳过测试。好事 就是记录了为什么测试没有运行的解释。

开始测试的速度很慢,尤其是在必须先部署 CSI驱动程序,但在其他情况下也是如此。创建一个名称空间 测试是在5秒的快速群集上进行的,它会产生 很多嘈杂的测试输出。本来可以解决 that by 跳过不支持的定义 tests, 但是之后 报告为什么测试甚至不是测试套件的一部分 棘手的。放弃这种方法是为了重组 这样的存储测试套件 第一次检查 conditions 在执行更昂贵的测试设置步骤之前。

更具可读性的测试定义

相同的PR还重写了测试以使其像常规操作一样运行 银杏测试,包含测试用例及其局部变量 一个 function.

测试外部驱动程序

构建自定义的E2E测试套件仍然需要大量工作。的 e2e.test二进制文件将分发到 Kubernetes 1.14测试 archive 将有 the 能够 test 已经 安装的存储驱动程序,而无需重建测试套件。看到这个 自述文件 有关更多说明。

端到端测试套件HOWTO

测试套件初始化

第一步是设置必要的样板代码, 定义测试套件。 在Kubernetes中 E2E, this is done in 的 e2e.go 一个d e2e_test.go files. It could also be done in 一个 e2e_test.go file. Kubernetes imports all of 的 各种提供程序,树内测试,Viper配置支持以及 bindata file lookup in e2e_test.go. e2e.go controls 的 actual 执行,包括一些集群准备和指标收集。

A simpler starting point are 的 e2e_[test].go files 从 PMEM-CSI。它 不使用任何提供程序,Viper,bindata,而仅导入 storage 测试.

与PMEM-CSI一样,OIM放弃了所有其他功能,但还有更多功能 复杂,因为它直接将自定义群集启动集成到 the 测试 suite, 在这种情况下很有用,因为一些其他组件具有 在主机端运行。通过直接在E2E二进制文件中运行它们, interactive debugging with dlv becomes easier.

两个CSI驱动程序都遵循Kubernetes示例,并使用 测试/e2e 测试套件的目录,但其他目录和其他目录 文件名也可以。

添加端到端存储测试

测试由导入到测试套件中的程序包定义。的 端到端测试的唯一特定之处在于它们实例化了 framework.Framework pointer (usually called f) with framework.NewDefaultFramework。重新初始化此变量 in a BeforeEach 对于 each 测试 一个d freed in 一个 AfterEach。它 has a f.ClientSet 一个d f.Namespace at runtime (and only at runtime!) 可以用于测试。

记忆体存储 test 导入Kubernetes存储测试套件并设置一个实例 PMEM-CSI驱动程序的配置测试,该驱动程序必须已经 安装在测试集群中。存储测试套件更改了 存储类,以使用不同的文件系统类型运行测试。因为 为此,将通过.yaml文件创建存储类。

解释框架中可用的所有各种实用程序方法 在此博客文章的范围之外。阅读现有测试和 框架的源代码是入门的好方法。

供应商

即使消除了Kubernetes代码,它仍然不是一件容易的事 many of 的 unnecessary 深度endencies. k8s.io/kubernetes is not meant 包含在其他项目中,并且未定义其依赖项 in a way that is understood by tools like 深度。的 other k8s.io 应该包含软件包,但是 不要遵循语义 versioning yet 还是不 tag 一个y releases (k8s.io/kube-openapi, k8s.io/utils)。

记忆体用途 深度。它的 Gopkg.toml 文件是一个很好的起点。它启用修剪(未在dep中启用 并默认将某些项目锁定到以下版本 与所使用的Kubernetes版本兼容。什么时候 深度 没有选择兼容版本,然后检查Kubernetes的 Godeps.json 帮助确定哪个修订版是正确的。

编译并运行测试套件

go 测试 ./test/e2e -args -help 是最快的方法来测试 test 套房 compiles.

Once 它 does compile 和一个 cluster has been set up, 的 command go 测试 -timeout=0 -v ./test/e2e -ginkgo.v runs all 测试. In order to run 测试 in parallel, use 的 ginkgo -p ./test/e2e command instead.

卷入

Kubernetes E2E框架归测试通用所有 sub-project in SIG测试。看到 该页面以获取联系信息。

有很多任务可以处理,包括但不能 limited to:

  • 将测试/ e2e /框架移至暂存仓库并进行重组 使其更具模块化 (#74352)。
  • Simplifying e2e.go by moving more of 它 s code into 测试/e2e/framework (#74353)。
  • 从Kubernetes E2E测试套件中删除提供商特定的代码 (#70194)。

特别感谢本文的审稿人: