jenkins+k8s进行持续集成自动化测试

0. 基于k8s创建Jenkins Slave优势

自动化测试现在一般都会上jenkin来定时做持续集成测试,但目前jenkins的slave机器常用的还是虚拟机,此时在没有跑自动化的时候造成了极大的资源浪费。基于k8s动态创建slave机器跑自动化测试能够最大化的利用资源。

指标 虚拟机做静态Slave 在k8s集群动态生成slave
资源利用率 不高 高,随建随用
资源分配情况 不均衡 均衡,资源池化
扩容便利度 不便利 便利,操作

1. 基于K8s的持续集成整体框架

jenkins+k8s进行持续集成自动化测试_第1张图片

2. 现有项目如何集成到这个流程中

步骤主要有三步,修改测试项目,配置Jenkins Job,执行job,其中配置jenkins job和执行job在此不多赘述。根据自身项目,所以此处主要介绍如何修改Jenkinsfile和jenkins_pod_template.yaml文件中的参数。其中:

  • Jenkinsfile,用于定义jenkins job的流水线
  • jenkins_pod_template.yaml用来定义在K8s上启动的jenkins slave

2.1 Jenkinsfile模板

模板内容如下:

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'
            }
        }
    }
}
}

2.2 jenkins_pod_template.yaml(即Jenkins slave pod)模板

利用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

3. 制作Jenkins Slave Pod使用的Image

jenkins_pod_template.yaml所用的image如下。

3.1 jnlp镜像

镜像名: XXX/jnlp-slave:root_user,Dockerfile如下:

FROM jenkins/jnlp-slave:latest
USER root

注意此处主要是把jnlp的user改为root,不然会有很多意想不到的问题。

3.2 python36镜像

镜像名: 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

3.3 java8镜像

镜像名: 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

4. JenkinsMaster做了哪些工作?

4.1 Jenkins配置Kubernetes

jenkins+k8s进行持续集成自动化测试_第2张图片

4.2 Jenkins工具设置

在Jenkins master上配置pipeline中需要的工具,比如代码扫描工具SonarQube Scanner,测试报告生成工具Allure。
jenkins+k8s进行持续集成自动化测试_第3张图片

4.3 Jenkins 调度slave的性能优化

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

你可能感兴趣的:(kubernetes,jenkins)