jenkins流水线基础(CICD 04)
目录:
1、构建工具集成(CI工具)
2、部署集成工具(CD)
3、用户认证集成
4、SonarQube集成(代码质量平台集成)
1、构建工具集成(CI工具)
构建工具主要是帮我们打包、编译、跑单测
1.1 Maven集成(java)
Maven项目管理工具,可以对Java项目进行构建、依赖管理。结合此文档加以下补充。
集成有两种方式,文档中是一种方式,另一种是在Jenkinsfile中写绝对路径;安装一般都不要选择自动安装,因为有时候会有问题
mvn常用命令:https://www.jianshu.com/p/ee7bc34d7ccc,https://www.jb51.net/article/190998.htm
1.2 Ant集成(java)
Ant也是java项目构建的工具,逐渐被Maven替代。结合此文档加以下补充。
mvn是用的pom.xml,ant得指定build.xml;
1.3 gradle集成(java)
gradle可以理解为java项目构建的工具的后起之秀,和Gradle相比,ant显得冗余复杂,maven显得有些死板落后。结合此文档加以下补充。
若Jenkins全局工具配置处没有gradle,先安装插件。
1.4 npm集成(前端)
先安装插件NodeJS。结合此文档加以下补充。
Node.JS是一个JavaScript运行环境(不是一个JS文件);npm内置在nodeJS中,所以安装Node安装包时,一并成功安装npm了,npm可以理解为与maven、gradle类似,只不过他们管理java jar包,npm管理js。https://blog.csdn.net/hong10086/article/details/85062678
报错:
原因(推测):因为npm执行的时候默认是使用/usr/bin/node去执行的,但本地是没有/usr/bin/node的。
解决办法:
方法1:创建一个软连接将自己的node的执行文件指到/usr/bin/node上。
ln -s /usr/local/node-v16.13.2-linux-x64/bin/node(实际安装的node位置) /usr/bin/node
方法2:改一下JenkinsFile
原来脚本如下:
stage("npm测试"){ steps{ script{ NpmHome = tool 'NPM' sh "${NpmHome}/bin/npm ${buildshell}" } } }
现在改为:
stage("npm测试"){ steps{ script{ NpmHome = tool 'NPM' sh """ export NODE_HOME=${NpmHome} export PATH=\$NODE_HOME/bin:\$PATH ${NpmHome}/bin/npm ${buildshell} """ } }
相当于将node环境变量在脚本中再次声明;
P.S.:sh """之间的换行,也可以之间用&&符号连接"",注意如果不是变量,真正使用$前加转义字符
方法3:将环境全局生效(这个应该要重启Jenkins,还不一定有效;建议用前两种方法)
# npm install -g npm
1.5 使用共享库1.1~1.4构建进行函数化
以上构建其实有很大相同点,可以函数化写在ShareLibrary中,然后调用使用。
Step1:Jenkins web页面进行参数选项设置;运行流水线前会进行选择;
Step2:在SHareLibrary中写build.groovy构建函数
package org.devops /* 函数功能:根据不同得构建类型,进行构建工作 参数buildType:构建类型,比如:mvn、ant、gradle、npm 参数buildshell:构建参数,比如:-v,clean,clean install等等 */ def Build(buildType,buildshell){ //定义一个字典,将构建类型与Jenkins的环境变量对应 def buildTools = ["mvn":"MVN3","ant":"ANT","gradle":"GRADLE","npm":"NPM"] println("当前选择的构建类型为${buildType}") buildhome = tool buildTools[buildType] if(buildType=="npm"){ // npm特殊处理,如果已经建立软连接,其实可以不用 sh""" export NODE_HOME=${buildhome} export PATH=\$NODE_HOME/bin:\$PATH ${buildhome}/bin/${buildType} ${buildshell} """ }else{ sh"${buildhome}/bin/${buildType} ${buildshell}" } }
Step3:JenkinsFile中调用。主要是导入函数包,获取Jenkins的构建变量,在构建环节进行函数调用
#!groovy @Library("JenkinsLib")_ def tools = new org.devops.tools() def build = new org.devops.build() //获取Jenkins页面的参数 String buildType = "${env.buildType}" String buildShell = "${env.buildShell}" String workspace = "/opt/jenkins/worksapce" //pipeline pipeline{ agent{ node { label "master" //指定运行节点的标签或者名称 customWorkspace "${workspace}" //指定运行工作目录(可选) } } options{ timestamps() //日志会有时间 skipDefaultCheckout() //删除隐式checkout scm语句 disableConcurrentBuilds() //禁止并行 timeout(time:1, unit:'HOURS') //流水线超时设置1h } stages{ // 下载代码 stage("GetCode"){ // 阶段名称 steps{ //步骤 timeout(time:5, unit:'MINUTES'){ //步骤超时时间限制 script{ //填写运行代码 println("获取代码") } } } } //构建 stage("Build"){ steps{ timeout(time:20, unit:'MINUTES'){ script{ build.Build(buildType,buildshell) } } } } //代码扫描 stage("CodeScan"){ steps{ timeout(time:20, unit:'MINUTES'){ script{ println("代码扫描") // 调用JenkinsShareLibrary tools.PrintMes("调用JenkinsShareLibrary打印函数",'green') } } } } } //构建后操作 post{ always{ // always{}总是执行脚本片段 script{ println("always") } } success{ // success{}执行成功后执行 script{ currentBuild.description += "\n 构建成功!" //currentBuild是一个全局变量,description构建描述 } } failure{ // failure{}执行失败后执行 script{ currentBuild.description += "\n 构建失败!" } } aborted{ // aborted{}执行被取消后执行 script{ currentBuild.description += "\n 构建取消!" } } } }
2、部署集成工具(CD)
2.1 SaltStack(工作中用Ansible,故暂略)
SaltStack是CS架构:salt-master与salt-minion,master是中心控制系统,部署在部署机上,minion是被管理的客户端,部署在目标机器上。分别安装,然后建立连接。
2.2 Ansible
Ansible与SaltStack一样,都是发布部署工具。但是它不是CS架构,不需要在目标机器上装客户端。
学习参考一下:https://www.cnblogs.com/keerya/p/7987886.html
Step1:在部署机/操作机上安装Ansible,这里是Jenkins机器上安装。
yum install epel-release -y
yum install ansible -y
Step2:因为是基于ssh实现,配置一下免密。这里实验时,目标机器也是用的Jenkins,是同一台机器,但是也一样要配置。(但是有时候同一台机器不用,可以ssh 目标机器IP试试,看看要不要输入密码)
#生成密钥对,默认生成在/root/.ssh/下 ssh-keygen #向目标主机发私钥 ssh-copy-id root@目标主机IP
Steps3:配置一下主机列表,即要通讯的目标主机列表文件;
# 打开主机列表配置文件 vi /etc/ansible/hosts # 根据情况写入目标主机IP [servers] server1 ansible_ssh_host=目标主机1的IP server2 ansible_ssh_host=目标主机2的IP
检查一下是否配置成功;这里servers是一个分组,下面有server1、2等等
Step4:Jenkins集成。
比如还是将部署函数写于shareLibrary中,如下
1 package org.devops 2 3 /*ansible集成 4 hosts参数:目标机器IP名称,就是Jenkins机器中/etc/ansible/hosts配置的 5 func参数:指令 6 */ 7 def AnsibleDeploy(hosts,func){ 8 sh " ansible ${func} ${hosts}" 9 10 11 }
Jenkinsweb页面设置参数如下:
Jenkinsfile中获取参数,并调用此参数;
#!groovy @Library("JenkinsLib")_ def deploy = new org.devops.deploy() //获取Jenkins页面的参数 String hosts = "${env.hosts}" String func = "${env.func}" String workspace = "/opt/jenkins/worksapce" //pipeline部分 //构建 stage("Build"){ steps{ timeout(time:20, unit:'MINUTES'){ script{ deploy.AnsibleDeploy(hosts,func) } } } }
3、用户认证集成
如果没有设置Jenkins进行安全检查,那么任何打开Jenkins页面得人都可以做任何事。
3.1 基础知识:单点登录(Single sign on ,SSO)
想象一下,新员工入职,你必须给他创建Jenkins、gitlab、JIRA、conf等多个系统的用户。你刚登录过Jenkins后,想用Gitlab,还要重新输入用户名与密码,再登录。员工离职,也是要一个个注销。对于个体用户来说烦,低效,对于管理者审计也烦。单点登录,是指在多个系统应用中登录其中一个系统,便可以在其他所有系统中得到授权,而无须再次登录,包括单点登录与单点注销两个部分。
3.2 LDAP集成
LDAP其实就是一个协议,功能可以理解为目录;轻型目录访问协议(Lightweight Directory Access Protocol,LDAP),具体可以百度。
它最常见的应用场景就是单点登录。
集成可以看相关文档。
LDAP的作用,相当于将多个系统用户名密码记录在一个目录本中,目录本给一个多个系统的公共用户名与密码。当各个系统集成LDAP后,比如这里Jenkins集成了LDAP后,就可以用在LDAP中设置用户名/账号密码登录,原jenkins账号密码应该是失效。(再比如JIRA、CONF、Gerrit这些工具想要使用统一账号密码登录管理,也要集成)(初步理解,可能有误)
3.3 Gitlab/Github SSO用户认证(略)
4、SonarQube集成(代码质量平台集成)
关于SonarQube简介:
架构:1/2/3在服务端,4在客户端
1、sonarqube server :一台SonarQube Server启动3个主要过程:
- Web服务器,供开发人员,管理人员浏览高质量的快照并配置SonarQube实例
- 基于Elasticsearch的Search Server从UI进行后退搜索
- Compute Engine服务器,负责处理代码分析报告并将其保存在SonarQube数据库中
2、sonarqube db :一个SonarQube数据库要存储:
- SonarQube实例的配置(安全性,插件设置等)
- 项目,视图等的质量快照。
3、sonarqube plugins:服务器上安装了多个SonarQube插件,可能包括语言,SCM,集成,身份验证和管理插件
4、sonar-scanner(安装在Jenkins机器上):在构建/持续集成服务器上运行一个或多个SonarScanner,以分析项目;
关于Jenkins+SonarQube安装可参考博客:https://www.cnblogs.com/mascot1/category/1291403.html
说明:
1、sonarscaner扫描时,会用到编译类,比如java项目编译后生成的target文件下class;所以我感觉扫当前的问题,准确的话,应该先编译打包,再扫描。
5、制品库Nexus集成
5.1 Nexus主要作用:
- 私服仓库:本地maven私服,可以加快构建速度(管理依赖)
- 代理仓库:将公网等第三方提供的仓库代理到本地(管理依赖)
- 项目生成制品上传。可以发布模块或项目到自定义的专属仓库,供局域网内其他开发人员复用,也就是说,我开发完一个项目,使用maven的deploy发布到nexus私服的专属仓库后,其他同事就可以在她的pom.xml文件添加这个包的依赖就可已调用这个项目的代码了。
5.2 Nexus基本概念(可以看官网):
1)Components(组件)
仓库中每个包就是组件。
引用时,通过不同方式的坐标定位。
2)中央仓库
当下载并安装Maven而没有进行任何自定义时,它将从中央存储库中检索组件。中央存储库时用于Java组件的最大存储库。
3)组件坐标
5.3 Nexus3安装:
前提:安装JDK和maven
下载安装包:官网太卡了