自动化测试现在一般都会上jenkin来定时做持续集成测试,但目前jenkins的slave机器常用的还是虚拟机,此时在没有跑自动化的时候造成了极大的资源浪费。基于k8s动态创建slave机器跑自动化测试能够最大化的利用资源。
指标 | 虚拟机做静态Slave | 在k8s集群动态生成slave |
---|---|---|
资源利用率 | 不高 | 高,随建随用 |
资源分配情况 | 不均衡 | 均衡,资源池化 |
扩容便利度 | 不便利 | 便利,操作 |
步骤主要有三步,修改测试项目,配置Jenkins Job,执行job,其中配置jenkins job和执行job在此不多赘述。根据自身项目,所以此处主要介绍如何修改Jenkinsfile和jenkins_pod_template.yaml文件中的参数。其中:
模板内容如下:
pipeline {
// 运行job所用的机器
agent {
kubernetes{
// 连接k8s,并利用yamlFile创建jenkins slave
cloud 'kubernetes-test' //cloud关联
label 'AUTOTEST-PYTHON36' //label一定要写
defaultContainer 'python36' // stages和post步骤中默认用到的container。如需指定其他container,可用语法 container("java8"){...}
idleMinutes 10 //所创建的pod在job结束后直到销毁前的等待时间
yamlFile "jenkins/jenkins_pod_template.yaml" // 指定创建pod时的yaml配置文件
}
}
// job的自定义参数,可在job运行前修改
parameters {
choice(name: 'env', choices: 'test\ndev\nstg', description: '测试环境,请选择dev?test?stg?')
string(name: 'keywords', defaultValue: 'test_case_example', description: '关键字,用于过滤测试用例,可以使用目录名、py文件名过滤')
}
// job的环境变量
environment {
//git相关
git_url = 'git@XXX' //[*] 项目git地址
git_key = 'XXX' //固定值,不要修改
git_branch = 'master'
gitpullerr = 'noerr'
//job失败后发送的邮件名单
email_list = '[email protected]'
}
// job的一些配置设定
options {
buildDiscarder(logRotator(numToKeepStr: '30')) //保存的job构建记录总数
timeout(time: 30, unit: 'MINUTES') //job超时时间
disableConcurrentBuilds() //不允许同时执行流水线
}
// job触发时机
triggers {
//pollSCM('H * * * 1-5')//周一到周五,每小时 定时检查源码变更
cron('H H(1-2) * * *') //每天 定时触发
//gitlab(triggerOnPush: false, triggerOnMergeRequest: false, branchFilterType: 'All') //git变更触发
//upstream(upstreamProjects: "", threshold: hudson.model.Result.SUCCESS) //上游变更触发
}
// 具体job的步骤,自动化测试工作主要在此处进行填写
stages {
stage('拉取测试代码') {
steps {
git branch: "${git_branch}", credentialsId: "${git_key}", url: "${git_url}"
}
}
stage('安装测试依赖') {
steps {
sh "pipenv install --skip-lock"
sh "pipenv graph"
}
}
stage('执行测试用例') {
steps {
sh "rm -rf $env.WORKSPACE/allure-*"//执行前先清空报告
sh "pipenv run py.test --env '${params.env}' -k '${params.keywords}'" // 执行自动化测试
}
}
}
// job收尾工作
post {
always{
container("jnlp"){
// 将allure 报告展示到jenkins上
allure includeProperties: false, jdk: '', report: 'jenkins-allure-report', results: [[path: 'allure-results']]
}
}
failure {
script {
if (gitpullerr == 'noerr') {
mail to: "${email_list}",
subject: "[Jenkins Build Notification] ${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} -构建失败!",
body: "'${env.JOB_NAME}' (${env.BUILD_NUMBER}) 执行失败了 \n请及时前往 ${env.BUILD_URL} 进行查看"
} else {
echo 'scm pull error ignore send mail'
}
}
}
}
}
利用K8s作为持续集成测试环境时,Jenkins slave是来自K8s的Pod对象。一个Jenkins salve就是一个Pod,一个Pod可以包含多个container。以我们使用的Jenkins slave为例,它包含三个container,如下文所示。
jenkins_pod_template.yaml 完整模版:
apiVersion: v1
kind: Pod
metadata:
namespace: sqe-test
spec:
containers:
# jnlp环境,必选,注意此处name=jnlp不能变,jenkins才能认出来
- name: jnlp
image: XXX/jnlp-slave:root_user
imagePullPolicy: Always
# mount的路径保持为jenkins的默认工作路径。jenkins 2.2版本默认工作路径/home/jenkins/agent
volumeMounts:
- mountPath: /home/jenkins/agent
name: jenkins-slave
# python36环境,可选
- name: python36
image: XXX/automation_python36:v1
imagePullPolicy: Always
env:
- name: WORKON_HOME # 设置pipenv的虚拟环境路径变量 WORKON_HOME
value: /home/jenkins/agent/.local/share/virtualenvs/
command:
- cat
tty: true
volumeMounts: # mount的路径保持为jenkins的默认工作路径。
- mountPath: /home/jenkins/agent
name: jenkins-slave
resources: # 资源限定,可调。尽量不要用太多
limits:
cpu: 300m
memory: 500Mi
# java8环境,可选,已安装maven,jacoco
- name: java8
image: XXX/automation_java8:v2
imagePullPolicy: Always
volumeMounts:
- mountPath: /home/jenkins/agent # mount的路径保持为jenkins的默认工作路径。
name: jenkins-slave
command:
- cat
tty: true
# nfs远程磁盘,用于共享公共库,复用资源等
volumes:
- name: jenkins-slave
nfs:
path: /data/jenkins-slave-nfs/
server: 10.10.129.178
# 用于test环境的node。nodeSelector不写的话,就是随机找台机器部署
nodeSelector:
node-app: normal
node-dept: sqe
jenkins_pod_template.yaml所用的image如下。
镜像名: XXX/jnlp-slave:root_user,Dockerfile如下:
FROM jenkins/jnlp-slave:latest
USER root
注意此处主要是把jnlp的user改为root,不然会有很多意想不到的问题。
镜像名: XXX/automation_python36:v1,Dockerfile如下:
FROM python:3.6.4
USER root
# 加入国内源
ADD ./sources.list /etc/apt/
# 更新
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get dist-upgrade -y
# 安装工具
RUN apt-get -y install \
vim \
net-tools \
zip
# 安装python包
RUN pip install --upgrade pip
RUN pip3 install pipenv
镜像名: XXX/automation_java8:v2,Dockerfile如下:
FROM maven:3.6.3-jdk-8
USER root
ARG ALLURE_VERSION=2.11.0
# 设置系统时区为北京时间
RUN mv /etc/localtime /etc/localtime.bak && \
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone # 解决JVM与linux系统时间不一致问题
# 支持中文
RUN apt-get update && \
apt-get install locales -y && \
echo "zh_CN.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
# 更新资源地址
ADD settings.xml /root/.m2/
# 安装jq
RUN wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 \
&& cp jq-linux64 /usr/bin/jq \
&& chmod +x /usr/bin/jq
# 安装jacococli
COPY jacoco-plugin/jacococli.jar /usr/bin
RUN chmod +x /usr/bin/jacococli.jar
在Jenkins master上配置pipeline中需要的工具,比如代码扫描工具SonarQube Scanner,测试报告生成工具Allure。
jenkins在启动时,增加如下配置。
-Dhudson.model.LoadStatistics.clock=2000
-Dhudson.slaves.NodeProvisioner.recurrencePeriod=5000
-Dhudson.slaves.NodeProvisioner.initialDelay=0
-Dhudson.model.LoadStatistics.decay=0.5
-Dhudson.slaves.NodeProvisioner.MARGIN=50
-Dhudson.slaves.NodeProvisioner.MARGIN0=0.85