原创 吴就业 145 0 2023-10-13
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/bf641e628bfa4ee6a8a645970d0fa249
作者:吴就业
链接:https://wujiuye.com/article/bf641e628bfa4ee6a8a645970d0fa249
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
Mock接口是我们常用的功能测试方案,有时候依赖的接口未开发完成或者依赖的第三方接口不提供测试环境等,只有Mock才能跑通流程。
我们基于KubeVela开发的云原生应用交付平台,提供如初始化基础设施导入、中间件部署共用基础设施等相关能力的测试,需要依赖基础设施。虽然terraform是面向公司内部的混合云平台,但是测试都要跨部门配置效率太低了,而且这种模式无法支持持续测试。
为了解决测试问题,Mock才是最高效的方案。为此,我们实践了两种Mock基础设施申请的方案,最终选择一种最高效的方案作为长期执行的方案。
通过kubevela部署application,其中基础设施组件会渲染成configuration资源,由terraform controller去创建Job,Job创建Pod,Pod执行terraform命令去申请资源。
我们利用hostAlias去实现mock掉terraform通过混合云提供的terraform provider向混合云申请资源的请求,然后实现一个web服务伪装成混合云。
apiVersion: v1
kind: Pod
metadata:
name: proxy-test-pod
namespace: default
spec:
containers:
- name: curl
image: "alpine"
command:
- "sh"
- "-c"
- "touch /dev/shm/debug && tail -f /dev/shm/debug"
hostAliases:
- ip: 192.168.88.88
hostnames:
- api.mycloud.com
terminationGracePeriodSeconds: 15
注意,如果你们用的是阿里云的或者aws的terraform provider,由于伪装https服务器需要有证书,如果没有证书这个方案就行不通了。
通过webhook在application资源创建/更新的时候,将需要Mock的组件替换为自定义的Mock组件,最终kubevela会将组件渲染成自定义的一个CR,然后由自定义控制器实现Mock逻辑,如创建output对应的Secret资源,tfstate Secret资源等。
关键技术点:
得益于KubeVela提供的自定义组件的能力,通过自定义Mock组件,将原本渲染成terraform-controller的Configuration资源,改为渲染成MockConfiguration资源。使得我们声明的application.yaml不仅适用于测试,无修改修改就可以直接部署在线上环境,确保了应用部署的application.yaml不会因为上线时做了错误的修改,导致测试没问题而线上无法部署成功的问题。
最核心的部分是Mock组件的定义。每种基础设施资源对应一种组件,我们可能只定义一个Mock组件,也可以为每种基础设施组件定义一个Mock组件,我们选择后者。
案例是定义一个mycloud-vpc-mock组件,组件的workload是自定义的CRD:MockConfiguration,该Mock组件用于mock mycloud-vpc组件。
"mycloud-vpc-mock": {
alias: ""
annotations: {}
attributes: {
workload: definition: {
apiVersion: "nebula.lizhi.fm/v1"
kind: "MockConfiguration"
}
status: {
healthPolicy: #"""
isHealth: (context.output.status.apply.state == "Available")
"""#
customStatus: #"""
applyStatus: {
message: *"" | string
} & {
if context.output.status.apply != _|_ && context.output.status.apply.message != _|_ {
message: (context.output.status.apply.message)
}
}
message: applyStatus.message
"""#
}
}
description: "Mock mycloud-vpc Terraform Component Apply"
labels: {
"mock-terraform-component": "mycloud-vpc"
}
type: "component"
}
template: {
output: {
apiVersion: "nebula.lizhi.fm/v1"
kind: "MockConfiguration"
metadata: {
name: context.name
namespace: context.namespace
}
spec: {
variable: {
vpc_name: parameter.vpc_name
}
backend: parameter.backend
providerRef: parameter.providerRef
writeConnectionSecretToRef: parameter.writeConnectionSecretToRef
}
status: {}
}
outputs: {}
parameter: {
vpc_name: string
backend: {
secretSuffix: string
}
providerRef: {
name: string
namespace: string
}
writeConnectionSecretToRef: {
name: string
namespace: string
}
}
}
方案一的好处是,上层使用上没有任何区别,整条链路上没有任何改动。而方案二会修改application.yaml,且不会跑terrafrom-controller的逻辑,整条链路实际上是不完整的,导致测试覆盖率低,有一些底层的问题无法在测试阶段发现,例如terraform-controller可能存在严重的bug。
方案一的缺点也很明显,因为需要mock非常多的接口,而且还需要对混合云提供的terraform provider的代码或者相关接口非常熟悉才可以。学习使用成本太高,效率没有方案二高。 最终出于对学习使用成本和效率方案的追求,我们选择使用方案二作为上层功能测试的Mock方案。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
由于我们的使用场景是将基础设施资源定义成KubeVela的组件,一个terraform “module”对应的就是一个kubevela的组件,对应terraform-controller的一个Configuration资源。因此导入的最小粒度是组件,即一个terraform “module”。
官方提供的工作流步骤有限,另外,对于自研的PaaS平台,我们需要借助工作流步骤实现一些例如存量项目基础设施导入、项目环境初始化、平台组件共享基础设施需要解决的差异对比审核、基础设施漂移等。
如何Debug Terraform Controller;如何让Configuration可以指向私有仓库;为云资源编写ComponentDefinition;验证流程是否跑通。
terraformProvider、multiclusterProvider、oamProvider、configprovider、kube这些provider的Install方法注册了很多操作处理方法。这些方法就是提供给CUE中调用的方法。
kubevela安装一个Application的过程,就是执行工作流上的每个步骤的过程,并且当我们未配置工作流,kubevela会自动为组件的部署生成一个工作流步骤。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。