生成式AI领域的最新成果都在这里!抢 QCon 展区门票 了解详情
写点什么

Kubernetes Operator 测试面面观

  • 2020-03-02
  • 本文字数:3549 字

    阅读完需:约 12 分钟

Kubernetes Operator 测试面面观

软件测试是一门工程技术,更是一门艺术。维护良好、质量过硬的测试用例不仅能大幅提高开发者的工作幸福感,也是企业对外提供优质软件服务的重要基础。在这篇文章中,才云工程师 gaocegege 将分享团队在 Kubernetes Operator 测试方案上的一些心得。


本文将介绍一些比较成熟的 Kubernetes Operator 测试方案与方法,分析目前对 Kubernetes Operator 进行测试的最佳实践。

单元测试

首先,让我们把镜头对准单元测试。单元测试又称模块测试,它是针对程序模块(软件设计的最小单位)进行正确性检验的测试工作,也被视为是软件质量的第一道保障。


Kubernetes 的做法


在 tf-operator 中,我们采取了跟 Kubernetes 内置的 controller 类似的测试方案(例子可见 job_controller_test.go)。


如下面的代码所示,我们通过 Fake KubeConfig 创建了 Fake Clienset 和 Informer。之后,我们利用 Indexer,将测试的数据注入到 Informer 的 Cache 中,同时把 Informer 的 Sync 状态置为 AlwaysReady。最后,我们用到了 Fake PodControl 和 ServiceControl,这一操作使得我们不会真正在 Kubernetes 中创建对象,而是只进行一个记录。



随后,我们将状态更新的函数也 Fake 掉,将其赋值到内存的一个对象中,以便在后续的测试中进行状态比对。通过手动调用 SyncTFJob,我们可以利用之前自己手动构造的 Cache 进行状态的 Sync。


最后,就是根据构造对象和实际更新后对象的比对,来判断 Operator 在 Sync 的过程中是否达到了期望状态。



这一方法利用了 Kubernetes 的一些机制,绕过了对 Kubernetes API Server 和其他组件的依赖,直接利用 Informer 针对 Operator 的代码逻辑进行测试,可以测试单次 Sync 过程中,Operator 的工作是否符合预期。


etcd-operator 的做法


etcd-operator 是问世最久的 Operator 之一,Operator 这一模式也是由 CoreOS 提出的,了解 etcd-operator 有助于我们以史为镜。


目前 etcd-operator 在实现中仍没有像主流的 Operator 一样,采用 Work Queue 的方式来避免阻塞问题,而是在 Informer 中直接进行处理,而它的处理逻辑则被统一写成了:



因此,在做单元测试时,这种方法相对容易些,可以直接构造 Event 对象来进行测试。


Kubebuilder-generated Operator 的做法


严格意义上,Kubebuilder 的测试有别于传统单元测试,它背后依赖的是 “sigs.k8s.io/controller-runtime/pkg/envtest”.Environment。


在运行时,它会启动一个真正的 API Server 和 etcd,随后把 CRD 注册到 Scheme 中并把 Operator 运行起来。但值得注意的是,它不会启动 Controller Manager,这也意味着来自 API Server 的关于 Kubernetes 资源的事件不会真正被处理。


相比其他测试方法,它有许多比较明显的不同。首先,它需要运行一个真正的 API Server 和 etcd 来做对象存储。这就意味着在测试时可以使用真正的 Clientset 对 API Server 进行各种请求。



其次,它会运行一个真正的 Operator,而不只是通过手动调用 Sync 过程的方式进行测试。如下方代码所示,inner 这一对象就是真正的 Operator 的逻辑,而这一函数对其进行了再次封装,利用一个没有缓冲的 Channel 对其进行了执行的控制。



根据 Golang 的内存模型,不带缓冲的 Channel 的接收操作 happens-before 相应 Channel 的发送操作完成。利用这一特性,在同一个测试用例中,测试的对象可以被多次 Sync,每次 Sync 的状态都可以被检查。如果需要检查其中的 reconcile.Result 的值,如 Requeue 等,也可以改动这部分的逻辑来扩展。


这样做的优势是可以在单个测试中多次 Sync,并且依赖真实的 API Server,直接简单地利用 Clientset 进行操作。而它的劣势也在于依赖真实的 API Server,由于有些 CI 系统对多进程支持不好,真正在持续集成环境下运行时会有各种各样的问题。

端到端测试

端到端测试是利用真实的外部组件,将系统当做黑盒,站在终端用户的角度进行的测试。这里的“真实的组件”指的是 Kubernetes 还有一些外部依赖。相比单元测试,端到端测试需要依赖一个真实的 Kubernetes 集群,同时由于其黑盒属性,我们就有了更多不同选型。


Kubernetes 的做法


首先介绍下 Kubernetes 自身 Controller 的 e2e 测试是如何做的。


Kubernetes 的端到端测试依赖一个关键的抽象,也就是 Framework。Framework 负责把需要的 Client 创建好,同时,它也会为测试创建一个 Namespace。


当前的测试用例会在这个 Namespace 下运行,因此它从设计上就避免了并行测试可能引起的冲突,是一个非常有价值的特性。这也使得 Kubernetes 的测试用例可以并行地运行。


其实 Kubernetes 的端到端测试有许多值得学习的地方,包括其整体的原则、哲学、设计和实现。限于篇幅原因,这里不过多介绍。


Operator-SDK generated Operator 的做法


Operator-SDK 的做法和 etcd-operator 的做法类似,和 Kubernetes 的做法也有异曲同工之妙,相当于是基于 Kubernetes 社区的实现做了一个新的抽象和改写。


首先它需要设置 Main Entry:



这一函数会根据传入的 Kubeconfig、ProjectRoot 等参数,创建出 CRD 和 Operator。Operator 可以运行在集群外,也可以以 Pod 的方式运行在集群内。


随后,集群就可以进行测试了。我们可以完全把它当做黑盒,把 Clientset 当做 kubectl,将端到端的黑盒测试自动化。不过这里值得一提的是,这一方式不能通过 go test 直接进行测试。因为在 MainEntry 中,它会依赖一些参数,而这些参数会涉及一些预处理的逻辑。


举个例子,Operator-SDK 会把 Operator 所有的 YAML 文件合并成一个 YAML,然后再把这一临时的 YAML 文件的路径作为参数传递给后续的命令。


因此 Operator-SDK 是利用 operator-sdk test local 这一命令先进行预处理,然后再把处理好的参数传递给 go test 命令的。这一方式对用户并不是那么友好,必须依赖 operator-sdk 才能发起测试。但它默认支持一个用例一个 Namespace,与 Kubernetes 测试时的行为类似。


Kubebuilder-generated Operator 的做法


由于 Kubebuilder 生成的测试原本就依赖一个真实的 API Server 和 etcd,所以我们只要再创建出其他 Kubernetes 的组件就可以了。


但是,如果已经有正在运行的 Kubernetes 集群,那么我们就可以利用 UseExistingCluster,通过运行的集群进行测试。


相比前几种方式,这种方法可以真正检查所有资源的状态。而之前的方法只有 API Server 的运行中,是做不到对状态的检查的,因为事件不会被 Kubernetes Controller Manager 处理,因此状态更新无法进行。


tf-operator 的做法


因为端到端测试是黑盒测试,只要能够利用 Kubernetes 的 API 进行请求就可以完成,因此 tf-operator 的端到端测试是用 Python 实现的。


其实不只是端到端测试,tf-operator 的构建也不是用 Make 或者 Bazel 做的,而是用 Python 实现的,它们其实都是历史遗留问题。


不过这也证明了,只要能够解决集群部署、CRD 以及 Operator 的安装,用什么语言都可以做 Operator 的端到端测试。

总结

除了以上内容,Operator 的单元测试还存在多种不同的实现方案,本文只是基于才云内部实践,列举了几种较为主流且高效的方法。


对于单元测试,Kubernetes 和 tf-operator 的做法能够细粒度地构造测试用例,同时检查 Sync 的过程可否满足期望。


etcd-operator 的做法为单元测试提供了一种新思路,通过对 Operator 进行更高层次的抽象,针对高层次的抽象进行单元测试,我们可以避免手动利用 Indexer 构造测试场景。


kubebuilder 生成 Operator 实现的测试并不是传统意义上的单元测试。它利用了真实的 API Server,在测试时可以利用 Client 获取真实的资源。但由于没有 Controller 的支持,所以对于不少需要依赖一些 Kubernetes 自身资源状态来更新自己状态的 CRD 而言,没办法进行状态的检查。这一问题在前面的方法中不存在。


而对于端到端测试,我列举的所有方案基本都是利用 Client 来对已经创建好的集群进行端到端的黑盒测试,它们的区别主要在于运行集群的方式。


Kubernetes 和 Operator-SDK 的做法利用 Framework 这一抽象来部署集群环境。


而 Operator-SDK 由于需要部署 CRD 和 Operator,因此基于 Kubernetes 原本的理念做了一些修改,支持从本地或者利用 Deployment 的方式部署 Operator 以便测试。


kubebuilder 采用了类似单元测试的方法,利用 controller-runtime 提供的抽象和能力,在运行时注册 CRD,在测试代码中运行 Operator 的逻辑,依赖已经部署好的标准的 Kubernetes 集群进行端到端测试。但它在默认情况下,没有每个测试使用一个 Namespace 的支持,需要用户自行实现这样的逻辑。


不同的测试选型适合于不同的 Operator,在测试时,大家可以根据 Operator 的特点来确定具体的测试方案。目前来看,社区并没有一个 One for all 的方案。


本文转载自才云 Caicloud 公众号。


原文链接:https://mp.weixin.qq.com/s/_vCZucfzlsKIzElxKnCDcQ


2020-03-02 17:47904

评论

发布
暂无评论
发现更多内容

DataOps系列丨数据的「资产负债表」与「现状」

DataPipeline数见科技

大数据

阿里大牛八年打造,编程宝典,从初学到编程进阶—深入学习—实战

Java~~~

Java 阿里巴巴 程序员 架构 编程语言

【得物技术】浅谈分布式事务中间件Seata

得物技术

开源 分布式事务 中间件 解决方案 seata

区块链+供应链,双链融合开启新时代

CECBC

区块链 供应链物流

结合实战和源码来聊聊Java中的SPI机制?

冰河

Java spi 服务发现

Spring Cloud Config 实现分布式配置中心

AI乔治

Java 架构 微服务 Spring Cloud

LeetCode 热题 - 递归

helbing

LeetCode

释放数字化活力 高质量建设数字中国

CECBC

数字经济

大专学历Java开发7年,从年初被裁到四面美团点评成功上岸,闭关七个月,入职那一天我哭了!

Java架构追梦

Java 阿里巴巴 面试 美团 java架构

消灭微服务的坏味道 之 循环依赖

码猿外

微服务 循环依赖 坏味道

架构师训练营 W05 作业

Geek_f06ede

《ZooKeeper分布式过程协同技术详解》.pdf

田维常

电子书

数字人民币究竟是什么

CECBC

数字货币

Nacos实战及其源码分析

Fox

Spring Cloud nacos spring cloud alibaba

32核打赢AMD64核 英特尔Ice Lake为HPC提供强劲性能

E科讯

输入法B端市场转化:百度推动产业智能化的新路径

脑极体

架构师系列之6: python实现一致性hash

桃花原记

DataOps系列丨DataOps理念与设计原则

DataPipeline数见科技

大数据

DataOps系列丨DataOps的组织架构与挑战

DataPipeline数见科技

大数据

石、火、水:从OriginOS透视移动系统进化论

脑极体

Appium常用操作之「Toast提示信息获取」

清菡软件测试

Maven-技术专题-Setting文件结构解析

洛神灬殇

git使用与原理剖析及其私服搭建

Fox

git

五、一致性哈希算法

Geek_28b526

用 Python 实现定时自动化收取蚂蚁森林能量

Python小二

Python

给,你们想要的内存溢出MAT排查工具

田维常

内存溢出

第五周-笔记

leo

极客大学架构师训练营

微服务手册:高速查询?除了Redis我们还有另外的选择

互联网应用架构

redis 微服务 springboot Caffeine 高速缓存

JVM运行时数据区,你真得好好学一学

Simon郎

JVM Java 分布式

实现2nm工艺突破,台积电为何能给“摩尔定律”续命?

脑极体

《使用C ++的数据结构和程序设计》限时免费下载

计算机与AI

c++

Kubernetes Operator 测试面面观_文化 & 方法_才云科技_InfoQ精选文章