rpm安装
#下载
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/jenkins-2.275-1.1.noarch.rpm
#安装
rpm -ivh jenkins-2.275-1.1.noarch.rpm
#修改配置文件
vi /etc/sysconfig/jenkins
修改工作目录
JENKINS_HOME="/var/lib/jenkins"
修改用户名,切记要么修改为root,要么使用默认的,其他的需要修改权限后才能使用,否则报错
JENKINS_USER="root"
修改端口号
JENKINS_PORT="8888"
修改时区
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai"
#配置jdk路径
vi /etc/init.d/jenkins
在 candidates 后追加jdk 安装路径(一直到jdk安装路径下的bin/java)
#修改以后必须使用此命令才能生效
systemctl daemon-reload
#启动Jenkins,并配置服务器重启后自动启动
systemctl start jenkins
# 浏览器访问http://124.70.5.141:8888/
Jenkins国外官方插件地址下载速度非常慢,所以可以修改为国内插件地址
Jenkins->Manage Jenkins->Manage Plugins,点击Available,等页面加载出来
这样做是为了把Jenkins官方的插件列表下载到本地,接着修改地址文件,替换为国内插件地址
# 执行如下命令修改地址文件
[root@ecs-andyhuawei updates]# sed -i 's/http:\/\/updates.jenkinsci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
然后来到advanced
URL修改成: mirrors.tuna.tsinghua.edu.cn/jenkins/upd…
在浏览器上重启jenkines:http://124.70.5.141:8888/restart
下载中文汉化插件
成功后看到如下页面
重启一生效。重启过程中发现已经变成中文
安装Role-based Authorization Strategy插件来管理Jenkins用户权限
安装完插件后开启权限全局安全配置
创建角色
- Global roles(全局角色):管理员等高级用户可以创建基于全局的角色
- Item roles(项目角色):针对某个或者某些项目的角色
- Node roles(奴隶角色):节点相关的权限
我们添加以下三个角色:
baseRole:该角色为全局角色。这个角色需要绑定Overall下面的Read权限,是为了给所有用户绑定最基本的Jenkins访问权限。注意:如果不给后续用户绑定这个角色,会报错误:用户名 is
missing the Overall/Read permission
role1:该角色为项目角色。使用正则表达式绑定"itcast.*",意思是只能操作itcast开头的项目。
role2:该角色也为项目角色。绑定"robot.*",意思是只能操作robot开头的项目。
创建用户
创建两个用户
andy和luce
密码同用户名
给用户分配角色
绑定规则如下:
andy用户分别绑定baseRole和role1角色
luce用户分别绑定baseRole和role2角色
创建项目测试权限
管理凭证
凭据可以用来存储需要密文保护的数据库密码、Gitlab密码信息、Docker私有仓库密码等,以便
Jenkins可以和这些第三方的应用进行交互。
安装Credentials Binding插件
安装完成后可见多了一个【Manage Credentials】按钮
- Username with password:用户名和密码
- SSH Username with private key: 使用SSH用户和密钥
- Secret file:需要保密的文本文件,使用时Jenkins会将文件复制到一个临时目录中,再将文件路径设置到一个变量中,等构建结束后,所复制的Secret file就会被删除。
- Secret text:需要保存的一个加密的文本串,如钉钉机器人或Github的api token
- Certificate:通过上传证书文件的方式
常用的凭证类型有:Username with password(用户密码)和SSH Username with private key(SSH密钥)
安装Git插件和Git工具
安装git插件后在服务器上安装git
yum install git -y
git --version
SSH Username with private key: 使用SSH用户和密钥
生成公钥私钥
复制公钥在gitlab上配置ssh key
在jenkins上配置私钥
在工程中选择ssh链接,选中刚才创建的凭证,保存后构建,可看到从gitlab上拉取得项目内容
查看构建历史,可以看到控制台输出
Username with password:使用用户名和密码与上述类似,这里省略
服务器中安装配置maven,省略
jenkins配置jdk和maven
添加Jenkins全局变量
修改Maven的settings.xml 略
测试maven是否配置成功
使用之前的gitlab密码测试项目,修改配置
构建->增加构建步骤->Execute Shell
输入mvn clear package
再次构建
集成安装tomcat
服务器上安装tomcat并启动,访问不到的话查看日志catalina.out,大概率是端口被占用,不只是8080,还有可能是8005被占用
配置Tomcat用户角色权限
默认情况下,tomcat是没有配置用户角色权限的
会出现如下页面
但是后续Jenkins部署项目到Tomcat服务器,需要用到Tomcat的用户,所以修改tomcat以下配置,添加用户及权限,用户和密码都是:tomcat
vi /opt/tomcat/apache-tomcat-8.5.73/conf/tomcat-users.xml
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script,tomcat,admin-gui,admin-script"/>
注意:为了能够用才配置的用户登录到Tomcat,还需要修改以下配置,把下面这行注释掉即可!
重启Tomcat,访问测试
shutdown.sh 停止
startup.sh 启动
再次访问Tomcat,点击manager webapp ,成功
安装 Deploy to container插件,把项目部署到远程的Tomcat里面
Jenkins本身无法实现远程部署到Tomcat的功能,需要安装Deploy to container插件实现,安装后点击“构建后操作步骤”会出现这个选项
Jenkins自动构建项目-自由风格项目
保存后立即构建,成功后发现列表中多了一个项目
访问http://124.70.5.141:8081/robot/hello
其中出现过一个构建错误,报错信息如下
检查conf/tomcat-users.xml中角色配置是否有差错,第一次是因为manager-script中间少了一个中横线“-”
Jenkins自动构建项目-maven项目
安装Maven Integration插件,如果失败则可能是版本太低升级新版本,新版本安装插件Pipeline Maven Integration Plugin
页面点击更新则会下载最新版本的jenkins.war包,在usr/lib/jenkins/下替换新的war包,重启即可
下载完插件完后可见
配置过程的git和tomcat同自由风格项目,不同之处参考如下配置
Jenkins自动构建项目-流水线项目pipeline
首先要安装pipeline插件,然后两种,一种是直接在Jenkins的web页面编写代码,另一种是在项目的代码里编写Jenkinsfile(可自定义文件名字)代码
方式一:直接在Jenkins的web页面编写代码
Declarative声明式-Pipeline
从代码仓库拉取代码的代码生成
maven编译打包的代码生成
项目发布到容器中(部署)
stages:代表整个流水线的所有执行阶段。通常stages只有1个,里面包含多个stage
stage:代表流水线中的某个阶段,可能出现n个。一般分为拉取代码,编译构建,部署等阶段。
steps:代表一个阶段内需要执行的逻辑。steps里面是shell脚本,git拉取代码,ssh远程发布等任意内容。
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/dev']], extensions: [], userRemoteConfigs: [[credentialsId: '48bc1124-dec4-432d-99d0-5db3f11c9976', url: 'git@124.70.5.141:jiaofuxiaomi/robot_web.git']]])
}
}
stage('编译构建') {
steps {
sh 'mvn clean package'
}
}
stage('部署') {
steps {
deploy adapters: [tomcat8(credentialsId: '1f95685f-d7e1-4aaf-bd7d-74d622a1dd6c', path: '', url: 'http://124.70.5.141:8081/')], contextPath: null, war: 'target/*.war'
}
}
}
}
刚才我们都是直接在Jenkins的UI界面编写Pipeline代码,这样不方便脚本维护,建议把Pipeline脚本放
在项目中(一起进行版本控制)
方式二:在项目的代码里编写Jenkinsfile
在项目根目录建立Jenkinsfile文件,把内容复制到该文件中,然后提交推送至远程仓库
常用的构建触发器
Jenkins内置4种构建触发器:
- 触发远程构建
- 其他工程构建后触发(Build after other projects are build)
- 定时构建(Build periodically)
- 轮询SCM(Poll SCM)
触发远程构建
其他工程构建后触发
只有当robot_web_pipeline被构建成功了,此工程才会自动构建
定时构建
定时字符串从左往右分别为: 分 时 日 月 周
一些定时表达式的例子:
每30分钟构建一次:H代表形参 H/30 * * * * 10:02 10:32
每2个小时构建一次: H H/2 * * *
每天的8点,12点,22点,一天构建3次: (多个时间点中间用逗号隔开) 0 8,12,22 * * *
每天中午12点定时构建一次 H 12 * * *
每天下午18点定时构建一次 H 18 * * *
在每个小时的前半个小时内的每10分钟 H(0-29)/10 * * * *
每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午
4:38) H H(9-16)/2 * * 1-5
轮询SCM
轮询SCM,是指定时扫描本地代码仓库的代码是否有变更,如果代码有变更就触发项目构建。
但是Jenkins会定时扫描本地整个项目的代码,增大系统的开销,不建议使用。
Git hook自动触发构建
刚才我们看到在Jenkins的内置构建触发器中,轮询SCM可以实现Gitlab代码更新,项目自动构建,但是
该方案的性能不佳。那有没有更好的方案呢? 有的。就是利用Gitlab的webhook实现代码push到仓
库,立即触发项目自动构建。
需要安装两个插件:Gitlab Hook和GitLab
安装成功后可以看到多了一种触发模式,勾选后保存,等会需要把生成的webhook URL(http://124.70.5.141:8888/project/robot_web_pipeline)配置到Gitlab中。
Gitlab配置webhook--->Menu->Admin->Setting->Network->Outbound requests->勾选后保存
在相应的项目中添加webhook
注意:在jenkins的系统配置中取消勾选这个,否则会报错
此时只要代码变更推送到gitlab中,就会自动触发构建
配置邮箱服务器发送构建结果
安装Email Extension Template插件
邮箱官网-设置-找到:
秘钥:GTULSHHXYVRBGRTA
系统设置配置邮箱参数
配置完成后,测试一下,收到短信后即为配置成功
准备邮件内容
在项目根目录编写email.html,并把文件推送到Gitlab,内容如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans- serif">
<tr>
<td>(本邮件是程序自动下发的,请勿回复!)</td>
</tr>
<tr>
<td>
<h2>
<font color="#0000FF">构建结果 - ${BUILD_STATUS}</font>
</h2>
</td>
</tr>
<tr>
<td><br/> <b><font color="#0B610B">构建信息</font></b>
<hr size="2" width="100%" align="center"/>
</td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}次构建</li>
<li>触发原因: ${CAUSE}</li>
<li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
</td>
</tr>
<tr>
<td><b><font color="#0B610B">Changes Since Last Successful Build:</font></b>
<hr size="2" width="100%" align="center"/>
</td>
</tr>
<tr>
<td>
<ul>
<li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
</ul>
${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br/>%c<br/>",showPaths=true,changesFormat="<pre>[%a]<br/>%m</pre>",pathFormat=" %p"}
</td>
</tr>
<tr>
<td><b>Failed Test Results</b>
<hr size="2" width="100%" align="center"/>
</td>
</tr>
<tr>
<td>
<pre style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
<br/>
</td>
</tr>
<tr>
<td><b><font color="#0B610B">构建日志 (最后 100行):</font></b>
<hr size="2" width="100%" align="center"/>
</td>
</tr>
<tr>
<td><textarea cols="80" rows="30" readonly="readonly" style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>
</td>
</tr>
</table>
</body>
</html>
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '48bc1124-dec4-432d-99d0-5db3f11c9976', url: 'git@124.70.5.141:jiaofuxiaomi/robot_web.git']]])
}
}
stage('编译构建') {
steps {
sh 'mvn clean package'
}
}
stage('部署') {
steps {
deploy adapters: [tomcat8(credentialsId: '1f95685f-d7e1-4aaf-bd7d-74d622a1dd6c', path: '', url: 'http://124.70.5.141:8081/')], contextPath: null, war: 'target/*.war'
}
}
}
post {
always {
emailext(
subject: '构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} -${BUILD_STATUS}!',
body: '${FILE,path="email.html"}',
to: '964356738@qq.com'
)
}
}
}
编写Jenkinsfile添加构建后发送邮件
安装sonarqube7.9及以上版本不支持java8和MySQL,需要Java11和Oracle
这里安装7.8版本
下载地址www.sonarqube.org/downloads/
前提环境:
MySQL5.6/5.7及以上
java8及以上
#创建目录
mkdir /opt/sonarQube
#将包sonarqube-7.8.zip放在此目录下
#下载解压工具
yum install unzip
#来到sonarQube目录下解压
[root@ecs-andyhuawei sonarQube]# unzip sonarqube-7.8.zip
#创建sonar用户,必须用sonar用户启动,否则报错(必须用非root用户,这里用方便记忆创建sonar用户)
useradd sonar
#赋予sonar用户的sonarQube目录及文件的权限
chown -R sonar /opt/sonarQube
#修改sonar配置文件
vi /opt/sonarqube-7.8/conf/sonar.properties
sonar.jdbc.username=root
sonar.jdbc.password=root
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
#注意:sonar默认监听9000端口,如果9000端口被占用,需要更改
#启动sonar
cd /opt/sonarQube/sonarqube-7.8
su sonar ./bin/linux-x86-64/sonar.sh start
#出现如下内容即为已经启动,但不一定启动成功,还需查看状态
[root@ecs-andyhuawei sonarqube-7.8]# su sonar ./bin/linux-x86-64/sonar.sh start
Starting SonarQube...
Started SonarQube.
#查看状态
su sonar ./bin/linux-x86-64/sonar.sh status
#出现如下内容即为启动失败
[root@ecs-andyhuawei sonarqube-7.8]# su sonar ./bin/linux-x86-64/sonar.sh status
SonarQube is not running.
#查看日志
[root@ecs-andyhuawei sonarqube-7.8]# tail -f logs/sonar.log
2021.12.24 14:03:08 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[[key='es', ipcIndex=1, logFilenamePrefix=es]] from [/opt/sonarQube/sonarqube-7.8/elasticsearch]: /opt/sonarQube/sonarqube-7.8/elasticsearch/bin/elasticsearch
2021.12.24 14:03:08 INFO app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running
2021.12.24 14:03:08 INFO app[][o.e.p.PluginsService] no modules loaded
2021.12.24 14:03:08 INFO app[][o.e.p.PluginsService] loaded plugin [org.elasticsearch.transport.Netty4Plugin]
ERROR: [1] bootstrap checks failed
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
2021.12.24 14:03:14 WARN app[][o.s.a.p.AbstractManagedProcess] Process exited with exit value [es]: 78
2021.12.24 14:03:14 INFO app[][o.s.a.SchedulerImpl] Process[es] is stopped
2021.12.24 14:03:14 INFO app[][o.s.a.SchedulerImpl] SonarQube is stopped
# 通过日志可看出关键信息“max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]”
#解决方案,修改/etc/sysctl.conf
vi /etc/sysctl.conf
新增一行 vm.max_map_count=262144
#执行命令sysctl -p
sysctl -p
#重新启动sonarqube
su sonar ./bin/linux-x86-64/sonar.sh start
#查看状态
su sonar ./bin/linux-x86-64/sonar.sh status
#出现如下内容即为成功启动
SonarQube is running (12823).
#浏览器访问sonar页面
http://124.70.5.141:9000/
#默认登录用户密码
admin/admin
生成一个token令牌,一定要及时保存,否则将再也见不到这个token第二次
token:24e5694e5444a10241d931d60ff27dff09b2d7d3
jenkins安装sonar scanner插件
添加sonarqube凭证
进行sonar配置
Manage Jenkins->Configure System->SonarQube servers
Manage Jenkins->Global Tool Configuration
SonaQube关闭审查结果上传到SCM功能
在项目添加SonaQube代码审查(非流水线项目)
# must be unique in a given SonarQube instance
sonar.projectKey=robot_web
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=robot_web
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.source=1.8
sonar.java.target=1.8
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
选择要添加代码审查的项目->配置->构建->增加构建步骤->选择execute sonarqube scanner->选择jdk->将上面内容复制到Analysis properties->保存->立即构建->查看控制台成功后刷新sonarqube页面可以看出代码已经被添加到sonarqube中了
Analysis properties和Path to project properties只能选择其一,如果不在Analysis properties里面写,则要在项目代码的根目录下创建sonar-project.properties文件,将内容写在文件内,将路径填写在Path to project properties
参考资料