1 问题背景 {#1-%E9%97%AE%E9%A2%98%E8%83%8C%E6%99%AF}
5月20日,MeterSphere开源持续测试平台发布v1.20.3-lts版本。在这一版本中,MeterSphere支持使用Deployment方式创建Kubernetes类型的资源池。
除了传统的添加一台独立主机作为测试资源池外,在MeterSphere的X-Pack功能增强包中,还支持Kubernetes(K8s)类型的资源池。通过这种方式我们可以达到更大的并行测试规模,或者将不同团队使用的资源池区分开来,避免互相影响。接下来我们将详细介绍接口测试及性能测试在Kubernetes集群中的执行流程, 以及Kubernetes类型的资源池应该如何配置使用。
2 架构图 {#2-%E6%9E%B6%E6%9E%84%E5%9B%BE}
2.1 在Kubernetes资源池中执行接口测试 {#2.1-%E5%9C%A8kubernetes%E8%B5%84%E6%BA%90%E6%B1%A0%E4%B8%AD%E6%89%A7%E8%A1%8C%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95}
2.2 在Kubernetes资源池中执行性能测试 {#2.2-%E5%9C%A8kubernetes%E8%B5%84%E6%BA%90%E6%B1%A0%E4%B8%AD%E6%89%A7%E8%A1%8C%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95}
3 具体操作 {#3-%E5%85%B7%E4%BD%93%E6%93%8D%E4%BD%9C}
3.1 Kubernetes集群中的具体操作 {#3.1-kubernetes%E9%9B%86%E7%BE%A4%E4%B8%AD%E7%9A%84%E5%85%B7%E4%BD%93%E6%93%8D%E4%BD%9C}
3.1.1 创建一个 namespace {#3.1.1-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA-namespace}
首先我们需要一个Kubernetes集群,以及一个有相应资源创建权限的用户。如果还没有Kubernetes集群的小伙伴,可以考虑使用KubeOperator(https://github.com/KubeOperator/KubeOperator)这个开源项目快速部署一个Kubernetes集群。
在我们有了Kubernetes集群且能正常使用kubectl命令之后,需要先创建一个单独的Namespace,名为"ms-pool",后续创建的所有资源均在该Namespace中。
kubectl create ns ms-pool
接下来,我们需要创建有对应权限的ServiceAccount供MeterSphere调用Kubernetes接口使用。
3.1.2 创建ServiceAccount {#3.1.2-%E5%88%9B%E5%BB%BAserviceaccount}
apiVersion: v1
kind: ServiceAccount
metadata:
name: metersphere
namespace: ms-pool
3.1.3 创建绑定给ServiceAccount的Role {#3.1.3-%E5%88%9B%E5%BB%BA%E7%BB%91%E5%AE%9A%E7%BB%99serviceaccount%E7%9A%84role}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: metersphere
namespace: ms-pool
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- watch
- list
- create
- update
- patch
- delete
- exec
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- get
- create
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- watch
- list
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- watch
- list
- create
- update
- patch
- delete
- apiGroups:
- batch
resources:
- jobs
verbs:
- get
- watch
- list
- create
- update
- patch
- delete
3.1.4 创建RoleBinding,为ServiceAccount添加权限 {#3.1.4-%E5%88%9B%E5%BB%BArolebinding%EF%BC%8C%E4%B8%BAserviceaccount%E6%B7%BB%E5%8A%A0%E6%9D%83%E9%99%90}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: metersphere
namespace: ms-pool
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: metersphere
subjects:
- kind: ServiceAccount
name: metersphere
namespace: ms-pool
3.1.5 获取ServiceAccount的Token {#3.1.5-%E8%8E%B7%E5%8F%96serviceaccount%E7%9A%84token}
export NAMESPACE=ms-pool
export TOKENNAME=$(kubectl -n $NAMESPACE get serviceaccount/metersphere -o jsonpath='{.secrets[0].name}')
export TOKEN=$(kubectl -n $NAMESPACE get secret $TOKENNAME -o jsonpath='{.data.token}' | base64 --decode)
echo $TOKEN
接下来,创建执行接口测试需要使用到的Node-Controller。具体的创建方式可以是Deployment或者DaemonSet,只要能够产生Node-Controller的Pod就可以。
3.1.6 使用Deployment方式创建 {#3.1.6-%E4%BD%BF%E7%94%A8deployment%E6%96%B9%E5%BC%8F%E5%88%9B%E5%BB%BA}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ms-node-controller
name: ms-node-controller
namespace: ms-pool
spec:
selector:
matchLabels:
app: ms-node-controller
replicas: 2
template:
metadata:
labels:
app: ms-node-controller
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ms-node-controller
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- env:
image: registry.cn-qingdao.aliyuncs.com/metersphere/ms-node-controller:dev
imagePullPolicy: IfNotPresent
name: ms-node-controller
ports:
- containerPort: 8082
protocol: TCP
resources: {}
volumeMounts:
- mountPath: /opt/metersphere/logs
name: metersphere-logs
restartPolicy: Always
volumes:
- emptyDir: {}
name: metersphere-logs
类似地也可以使用DaemonSet来提供Node-Controller。上面使用到的Role以及Deployment和DaemonSet模板,都可以在MeterSphere平台的如下位置进行下载。
3.2 MeterSphere平台上的具体操作 {#3.2-metersphere%E5%B9%B3%E5%8F%B0%E4%B8%8A%E7%9A%84%E5%85%B7%E4%BD%93%E6%93%8D%E4%BD%9C}
3.2.1 创建Kubernetes资源池 {#3.2.1-%E5%88%9B%E5%BB%BAkubernetes%E8%B5%84%E6%BA%90%E6%B1%A0}
Kubernetes集群中各个资源都创建成功后,就可以在MeterSphere平台上添加Kubernetes测试资源池了。在MeterSphere的"系统设置"→"测试资源池管理"页面中,新建一个Kubernetes类型的资源池。
填入所使用的Kubernetes集群API地址、对应的Namespace名字、获取到的ServiceAccount的Token,以及提供Node-Controller Pod的Deployment或DaemonSet的名字。
信息都填写完毕后点击"确定"按钮保存,MeterSphere会去验证填写的信息是否正确。如果在资源池列表查看到新建的资源池为启用状态,说明验证成功。后续接口测试及性能测试的执行就可以选择该资源池了。
3.2.2 Kubernetes资源池参数介紹 {#3.2.2-kubernetes%E8%B5%84%E6%BA%90%E6%B1%A0%E5%8F%82%E6%95%B0%E4%BB%8B%E7%B4%B9}
■ 镜像:使用该资源池执行性能测试时,用于创建JMeter Pod使用的镜像;不填写时,默认使用后台配置文件中的jmeter.image参数;
■ 后置监听器(X-Pack):使用该资源池执行性能测试时,是否使用JMeter后置监听器来汇总发送结果数据;开启时,使用JMeter中的Kafka Backend Listeners来收集并上传结果,使用DataStreaming计算处理;关闭时,使用外置的Java应用汇总处理结果数据并上传;
■ 用途:该资源池可以用于何种类型的测试;
■ JMeter HEAP:创建JMeter Pod时,使用的JVM HEAP参数;
■ JMeter GC_ALGO:创建JMeter Pod时,使用的JVM GC_ALGO参数;
■ 类型:测试资源池底层资源类型,独立节点或Kubernetes;
■ Master URL:Kubernetes API服务地址;
■ Token:调用Kubernetes API时使用的Token;
■ Namespace:Kubernetes相关资源的所属Namespace;
■ Deploy Name:使用该资源池执行接口测试时,提供Node-Controller Pod的Deployment或DaemonSet的名称;
■ API Image:创建Node-Controller Pod使用的镜像名称;不填写时,默认使用后台配置文件中的k8s.node-controller-image参数;
■ 最大并发数:使用该资源池执行性能测试时,能支持的最大并发数限制;
■ 单Pod最大线程数:使用该资源池执行性能测试时,每个Pod支持的最大并发数;启动的Pod个数=总并发数/该参数;
■ 定时同步Jar:是否定时同步用户上传的Jar包到资源池中的Node-Controller节点上。