首页 > 其他分享 >【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s

时间:2022-12-15 13:37:09浏览次数:46  
标签:pipeline name harbor 企业级 构建 BUILD 自动化 k8s NAME

为什么要写企业级持续集成(jenkins + pipeline + k8s)?

目前网上自动化持续集成的资料很多,但基本上都是局限于jenkins自由风格的job,结合shell脚本来实现持续集成,这种方式的缺点也很明显:

  1、构建出问题,排查困难

  2、构建节点挂了,就不能完成构建任务

而当前主流技术是 “ k8s + 微服务 ” 等,我们完全可以利用k8s的优势来完成持续构建任务,每次构建时可以调度到任意节点,或者是具有指定标签的节点,这就实现了高可用,另外,结合pipeline,可以轻松简单实现持续集成,并且哪个阶段出问题了一目了然,排查起来也容易。

 

自动化测试框架

0基础到实现:java + testng + httpclient + allure

 

企业级持续集成技术栈

git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s

可以整合python、java等各种自动化测试框架

流程:拉取代码--》mvn打包--》构建镜像--》新镜像发布到k8s--》拉取自动化测试代码--》自动化测试--》allure报告

环境:jenkins使用k8s作为构建环境,在某个节点执行测试

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试

环境规划

5台虚拟机:

  192.168.117.160:harbor、jenkins、maven

  192.168.117.161:k8s-master

  192.168.117.162:k8s-node01

  192.168.117.163:k8s-node02

  192.168.117.180:gitlab

每台虚拟机都安装了git

 

环境搭建(含必备基础)

git安装及使用

gitlab安装及使用

maven安装及使用

docker安装及使用

harbor安装以及使用

k8s安装(k8s操作

jenkins搭建及devops自动化平台相关配置

allure报告:allure-commandline下载、安装、配置(linux或者docker)

jenkins把自动化测试结果发送到钉钉群

 

pipeline设计

pipeline常用功能

使用Blue Ocean设计pipeline脚本

说明:由于资源不足,暂未加入sonarqube等

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_02

 

pipeline具体实现

结合上面在Blue Ocean中设计的pipeline骨架,我们来完善并实现整个过程

parameters

可以选择要构建的分支

parameters {
gitParameter branch: '', branchFilter: 'origin/(.*)', defaultValue: '', description: '构建的分支', name: 'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'GitParameterDefinition'
}

 

环境变量

environment {
HARBOR_ADDRESS = "192.168.117.160"
IMAGE_NAME = "gift"
NAMESPACE = "gift"
}

 

agent

k8s作为构建环境

agent {
kubernetes {
cloud 'qzcsbj_kubernetes'
yaml '''apiVersion: v1
kind: Pod
spec:
containers:
- image: 'registry.cn-chengdu.aliyuncs.com/qzcsbj6/jnlp:alpine'
name: jnlp
imagePullPolicy: IfNotPresent
args: [\'$(JENKINS_SECRET)\', \'$(JENKINS_NAME)\']
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- image: "registry.cn-chengdu.aliyuncs.com/qzcsbj6/kubectl"
imagePullPolicy: "IfNotPresent"
name: "kubectl"
tty: true
command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LANG"
value: "en_US.UTF-8"
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- image: "registry.cn-chengdu.aliyuncs.com/qzcsbj6/docker"
imagePullPolicy: "IfNotPresent"
name: "docker"
tty: true
command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LANG"
value: "en_US.UTF-8"
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- mountPath: "/var/run/docker.sock"
name: "dockersock"
readOnly: false
- image: "registry.cn-chengdu.aliyuncs.com/qzcsbj6/maven"
imagePullPolicy: "IfNotPresent"
name: "maven"
tty: true
command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LANG"
value: "en_US.UTF-8"
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
- mountPath: "/root/.m2/"
name: "m2dir"
readOnly: false
- image: "registry.cn-chengdu.aliyuncs.com/allure-commandline"
imagePullPolicy: "IfNotPresent"
name: "allure"
tty: true
command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LANG"
value: "en_US.UTF-8"
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
restartPolicy: "Never"
volumes:
- name: "dockersock"
hostPath:
path: "/var/run/docker.sock"
- name: "localtime"
hostPath:
path: "/usr/share/zoneinfo/Asia/Shanghai"
- name: "m2dir"
hostPath:
path: "/opt/m2"
'''
}
}

 

pull project code

stage('pull project code') {
parallel {
stage('ui build') {
when {
expression {
env.gitlabBranch == null
}
}
steps {
sh """
echo '=================开始拉取项目代码'
"""

git(url: '[email protected]:qzcsbj/gift.git', branch: "${BRANCH}", credentialsId: 'qzcsbj_gitlab')
script {
COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
TAG = BUILD_TAG + '-' + COMMIT_ID
println "Current branch is ${BRANCH}, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"
}
}
post {
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 拉取项目代码失败",
text: ["#### '${JOB_NAME}'项目代码拉取失败\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}
stage('trigger build') {
steps {
sh """
echo "待更新。。。"
"""
}
}
}
}

  

mvn package

stage('mvn package') {
steps {
container(name: 'maven') {
sh """
echo '=================mvn开始打包'
mvn clean package -Dmaven.test.skip=true
echo '=================mvn打包完成'
"""
}
}
post {
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: mvn package失败",
text: ["#### '${JOB_NAME}'项目mvn package失败\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

  

build and push image

stage('build and push image') {
environment {
HARBOR_USER = credentials('qzcsbj_harbor')
}
steps {
container(name: 'docker') {
sh """
echo '=================开始构建镜像'
docker build -t ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} .
docker login -u ${HARBOR_USER_USR} -p ${HARBOR_USER_PSW} ${HARBOR_ADDRESS}
docker push ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG}
echo '=================镜像推送完成'
"""
}
}
post {
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 构建或者推送镜像失败",
text: ["#### '${JOB_NAME}'项目构建或者推送镜像失败\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

 

deploy to k8s

stage('deploy to k8s') {
environment {
MY_KUBECONFIG = credentials('qzcsbj_k8s')
}
steps {
container(name: 'kubectl'){
sh """
echo '=================开始部署到k8s'
/usr/local/bin/kubectl --kubeconfig $MY_KUBECONFIG set image deploy -l app=${IMAGE_NAME} ${IMAGE_NAME}=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} -n $NAMESPACE
echo '=================部署到k8s完成'
"""
}
}
post {
success {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化部署到k8s完成",
text: ["#### '${JOB_NAME}'项目自动化部署到k8s完成\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化部署到k8s失败",
text: ["#### '${JOB_NAME}'项目自动化部署到k8s失败\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

 

pull autotest code

stage("pull autotest code"){
steps{
sh """
echo '=================开始拉取自动化测试代码'
"""
git(
credentialsId: 'qzcsbj_gitlab',
url: '[email protected]:root/apiautotest.git'
)
}
post {
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 拉取自动化测试代码失败",
text: ["#### 拉取自动化测试代码失败\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

  

run autotest

stage("run autotest"){
steps{
sh """
mvn clean test -Dsurefire.suiteXmlFiles=testngXML/testng.xml
"""
}
post {
success {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化测试完成",
text: ["#### '${JOB_NAME}'项目自动化测试完成\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL}console)"]
)
}
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化测试运行出错",
text: ["#### '${JOB_NAME}'项目自动化测试运行出错\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

  

allure report

stage("allure report"){
steps{
sh """
echo '=================开始生成测试报告'
"""
allure(
includeProperties: false,
jdk: '',
results: [[path: 'target/allure-results']]
)
}
post {
success {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化测试报告已生成,全部通过",
text: ["#### '${JOB_NAME}'项目自动化测试报告已生成,全部通过\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次测试报告](${BUILD_URL}allure)"]
)
}
unstable {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化测试报告已生成,有未通过的",
text: ["#### '${JOB_NAME}'项目自动化测试报告已生成,有未通过的\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次测试报告](${BUILD_URL}allure)"]
)
}
failure {
dingtalk (
robot:'dd01',
type:'MARKDOWN',
atAll: true,
title: "notice: 自动化测试报告生成出错",
text: ["#### '${JOB_NAME}'项目自动化测试报告生成出错\n - 构建:第'${BUILD_NUMBER}'次\n - 状态:'${currentBuild.result}'\n - [查看本次构建详情](${BUILD_URL})"]
)
}
}
}

 

构建及效果展示

pipeline脚本可以放在流水线项目的脚本框中

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_docker_03

 

也可以放gitlab上,选择SCM

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_docker_04

 

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_05

 

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_git_06

 

pipeline脚本放到Jenkinsfile中,Jenkinsfile在gift项目master分支下

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_docker_07

第一次构建,点击“Build Now”,会失败,因为我们使用了参数化构建,这次构建获取不到参数值

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_08

 

刷新页面,就可以看到参数化构建了,就可以选择要构建的分支

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_09

 

部署到k8s的通知

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_10

消息

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_11

 

运行自动化测试的通知

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_12

消息

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_docker_13

 

生成allure测试报告的通知

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_14

消息

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_15

测试报告的通知可以优化,直接链接到allure测试报告

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_docker_16

 

测试报告

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_17

【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_自动化测试_18

 

【建议收藏备用】热门技术、项目实战、简历、笔试题、面试题、职业规划(助你少走弯路,轻松跳槽加薪)

 

包含以下内容:

测试实战:
性能:jmeter + k8s + 微服务 + skywalking + efk,测试都在学的热门技术
自动化:python版、java版
测开:待更新

简历:写出一份高质量简历

笔试题:linux、shell、mysql、java、python、测开、性能、自动化、docker、k8s等

职业规划:让你少走弯路,尽早跳槽加薪,方向不对,努力白费

摸鱼:上班正确的摸鱼方式

 

 

__EOF__


【实战】企业级持续集成(DevOps/TestOps自动化平台):git + gitlab + jenkins + pipeline + maven + harbor + docker + k8s_git_19


本文作者:​持之以恒(韧)​​
关于博主:擅长性能测试、全链路压测、自动化测试、企业级自动化持续集成(DevOps/TestOps)等



标签:pipeline,name,harbor,企业级,构建,BUILD,自动化,k8s,NAME
From: https://blog.51cto.com/qzcsbj/5939307

相关文章

  • 如何快速构建企业级数据湖仓?
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群本文整理自火山引擎开发者社区技术大讲堂第四期演讲,主要介绍了数据湖仓开源趋势、火山......
  • 如何快速构建企业级数据湖仓?
     更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 本文整理自火山引擎开发者社区技术大讲堂第四期演讲,主要介绍了数据湖仓开源......
  • Jenkins实践指南-05-Jenkins pipeline 语法01
    3.Jenkinspipeline语法3.1pipeline组成  [作者:Surpassme]Jenkinspipeline是基于Groovy语言实现的一种DSL(领域特定语言),用于描述整条流水线是如何进行的。流水......
  • 私有harbor镜像仓库离线安装
    Harbor仓库在做此操作前必须保证有docker-compose1.安装compose[root@server1~]#curl-Lhttps://github.com/docker/compose/releases/download/1.22.0/docker-comp......
  • Registry&Harbor私有仓库问题
    1、按照我对docker的理解,宿主机a,想要访问宿主机机b中的容器,哪怕是局域网访问,一定要让这个容器绑定宿主机b的物理端口,然后通过宿主机b的ip和端口访问但是老师今天的课程中,他......
  • openGauss企业级开源数据库获第十届中国电子信息博览会金奖
    2022年8月16日,在2022第十届中国电子信息博览会(ChinaInformaticaTechnologyExpo;英文简称“CITE”)期间,openGauss企业级开源数据库一举摘得本届中国电子信息博览会最高奖项......
  • 企业级开源IDaas/EIAM产品重磅发布
    产品概述TopIAM数字身份管控平台,简称:EIAM(EmployeeIdentityandAccessManagement),用于管理企业内员工账号、权限、身份认证、应用访问,帮助整合部署在本地或云端的内部办......
  • JeecgBoot 3.4.4 ONLINE专项升级,开源的企业级低代码平台
    项目介绍JeecgBoot是一款企业级的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue3,Mybatis-plus,Shiro,JWT支持微服务。强大的代码生成器让前后端代码......
  • MongoDB 聚合管道(Aggregation Pipeline)
    管道概念POSIX多线程的使用方式中,有一种很重要的方式-----流水线(亦称为“管道”)方式,“数据元素”流串行地被一组线程按顺序执行。它的使用架构可参考下图:以面向对象的思想......
  • 大数据【企业级360°全方位用户画像】基于RFE模型的挖掘型标签开发
        上一篇博客,已经为大家介绍了基于RFM(用户价值模型)的挖掘型标签开发过程(......