项目拓扑图
项目环境: jenkins-2.440 sonarqube-9.9.4 apache-maven-3.9.6 gitlab-ce-12.4.2 java17 docker20
harbor.v2.6.0 centos7.9
项目目的: 模拟企业构建一个流行的持续集成和持续部署环境,可以更轻松地创建和管理构建环境,实现自动化构建和部署应用程序的目标,同时基于docker就更灵活
项目步骤:
一. 安装gitlab服务器,作为代码托管服务器
二. 配置jenkin服务器,作为CICD工具
三. 配置harbor作为镜像仓库,方便镜像的上传与拉取
四. 配置sonarqube实现对代码的审查功能
五. 将jenkins中的pipline文件配置,以及其他配置集合起来
六. 改进,设置jenkins的slave节点,实现分流
1. 安装gitlab,作为代码托管服务器
1.1 安装相关依赖
bash
yum -y install policycoreutils openssh-server openssh-clients postfix
1.2 启动ssh服务&设置为开机启动
bash
systemctl enable sshd && sudo systemctl start sshd
1.3 关闭防火墙,防止通信受阻
bash
systemctl stop firewalld && systemctl disable firewalld
1.4 官方下载gitlab rpm包,并且安装
bash
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-12.4.2-ce.0.el6.x
86_64.rpm
rpm -ivh gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm
1.5. 更改gitlab配置文件,监听地址和端口(防止端口冲突)
bash
vi /etc/gitlab/gitlab.rb
external_url 'http://192.168.118.181:82'
nginx['listen_port'] = 82
1.6. 重新加载配置文件,重新启动gitlab,并且查看网页
bash
gitlab-ctl reconfigure
gitlab-ctl restart
1.7 添加组,创建用户,创建项目
添加My-group组,设为私有
在组里面中创建项目
创建用户
创建密码
将plf用户添加到组里面去,设置为owner权限
2. 安装jenkins,作为持续集成工具
2.1 安装jdk17,jenkins需要依赖jdk
bash
wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm
rpm -ivh jdk-17_linux-x64_bin.rpm
安装目录为: /usr/lib/jvm/jdk-17-oracle-x64/bin/java
2.2 下载jenkins,并且安装
bash
wget https://get.jenkins.io/redhat/jenkins-2.452-1.1.noarch.rpm
rpm -ivh jenkins-2.452-1.1.noarch.rpm
2.3 更改jenkins配置文件(将启动用户改为root)
bash
vim /usr/lib/systemd/system/jenkins.service
User=root
Group=root
2.4 重新加载配置文件,并且启动
bash
systemctl daemon-reload
systemctl restart jenkins
2.5 登录jenkins网站,进行相关配置
初始配置密码 cat /var/lib/jenkins/secrets/initialAdminPassword
2.6 安装Role 角色管理插件,实现对项目的更细颗粒度管理
2.7 开启全局角色安全配置
2.8 创建相关角色,分配权限
创建rolebase角色,分配全局登录权限
创建项目角色role1,分配匹配到的项目的所有权限
2.9 创建用户,为用户分配相关角色
创建plf用户
将用户分配角色,rolebase和role1,实现登录功能以及对项目的管理
用plf用户进行登录,只可以看到My.用户开头的项目
2.10 安装git插件以及凭证插件,以及git工具
安装git
bash
yum install -y git
安装git插件以及crendiential
2.11 在gitlab服务器和jenkins设置ssh免密登录,以及凭证设置
bash
[root@jenkins ~]# ssh-keygen -t rsa
[root@jenkins ~]# ssh-copy-id root@192.168.118.181
在gitlab ui界面中也要设置上传 公钥
在jenkins上设置ssh gitlab的凭证,将jenkins私钥添加进去,进行SSH验证
在My_pro项目中进行配置 git服务器 以及 凭证
进行构建,测试是否成功
2.12 安装maven工具
下载maven,并且安装
bash
wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
tar -xvf apache-maven-3.9.6-bin.tar.gz
移动到/opt/maven 目录,并且加入环境变量中
bash
mv apache-maven-3.9.6/* /opt/maven
vim /etc/profile
export MAVEN_HOME=/opt/maven
export PATH=$PATH:$MAVEN_HOME/bin
source /etc/profile
mvn -v 查看版本
2.13 在jenkins中配置指定maven和jdk的路径
配置环境变量
2.14 设置maven本地仓库,更改aliyun镜像地址
bash
mkdir /root/repo
vi /opt/maven/conf/settings.xml
#将repo 仓库改
/root/repo/
#添加aliyun私服地址
http://maven.aliyun.com/nexus/content/groups/public/
2.15 Git hook自动触发构建
#轮询SCM性能不佳
开启流水线中的 webhook触发器
默认gitlab不支持,所以gitlab上也要进行配置开启,允许webhook服务
并且还要配置,webhook指向的jenkins项目地址
最后 关闭认证过程,gitlab的
最后测试,认证成功
2.16 构建邮箱触发通知
开启网易发送邮件功能,保存授权密码 VLMQSHORTMDCAKVD
在jenkins配置邮件服务器相关参数
配置网易邮件凭证
进行测试,邮箱构建成功
设置邮件发送模板
<!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>(本邮件是程序自动下发的1,请勿回复!)</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>
3 安装SonarQube实现代码审查
3.1 安装postsql且创建sonar数据库(当前的sonarqube已经不支持,mysql)
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-6-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo yum install -y postgresql15-server
sudo service postgresql-15 initdb
sudo chkconfig postgresql-15 on
sudo service postgresql-15 start
systemctl enable postgresql-15
systemctl start postgresql-15
[root@jenkins conf]# su postgres
bash-4.2$ psql
psql (15.6)
Type "help" for help.
postgres=# create database sonar;
3.2 安装sonarqube(java版本为17)
https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.4.87374.zip
下载完成后上传到linux服务器中
[root@jenkins ~]# unzip sonarqube-9.9.4.87374.zip
[root@jenkins ~]# mv sonarqube-9.9.4.87374/* /opr/sonar
准备环境并且配置相关配置
[root@jenkins opt]# useradd sonar #创建sonar用户配置用于启动sonar
[root@jenkins opt]# chmod -R sonar:sonar sonar #将文件权限的所属都改为sonar
[root@jenkins opt]# vim sonar/conf/sonar.properties
sonar.jdbc.username=postgres #设置为数据库的账户和密码;默认postsql就会生成postgres和密码
sonar.jdbc.password=postgres
sonar.jdbc.url=jdbc:postgresql://localhost/sonar
#设置连接的数据库的地址和数据库
启动sonar使用sonar用户启动
su sonar /opt/sonar/bin/linux-x86-64/sonar.sh start
启动成功,访问 192.168.118.182:9000 (端口可以在配置文件中更改)https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.4.87374.zip
3.3 Sonar和Jenkins整合实现代码审查
首先在jenkins中安装sonarqube scanner的插件
在安装sonarscanner的软件
在jenkins中配置sonarqube服务器的环境
获取token并且配置sonarqube凭证 squ_d631e058089b8927f2da702ce55b178bcd4eb149
4. Harbor仓库搭建
4.1 首先先安装Docker并且启动docker
yum install -y epel-release
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
cat >>/etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://reg-mirror.qiniu.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
4.2 下载harbor压缩包,并且安装
wget https://github.com/goharbor/harbor/releases/download/v2.10.2/harbor-offline-installer-v2.10.2.tgz
tar -xvf harbor-offline-installer-v2.10.2.tgz
更改配置文件,设置为本机ip地址
vim /opt/harbor/harbor.yml
4.3 启动harbor 安装文件,下载相关镜像
4.3 进行访问 harbor
4.4 添加用户,创建项目,分配角色
5 准备测试服务器,并且将jenkins进行联动
5.1 在测试机器上安装docker,初始化环境
5.2 编写dockerfile文件,进行镜像的构建
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9001
ENTRYPOINT ["java","-jar","/app.jar"]
5.3 编写sonar文件,进行审查
# must be unique in a given SonarQube instance
sonar.projectKey=My_pro
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=My_pro
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.binaries=.
sonar.java.source=17
sonar.java.target=17
#sonar.java.libraries=**/target/classes/**
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
5.3 编写jenkins流水线脚本,实现代码的拉取,审查,编译,打包,上传,部署
//git凭证ID
def git_auth = "5011e58f-4eef-4a0b-abf3-141adc28972b"
//git的url地址
def git_url = "git@192.168.118.181:itheima/tensquare_back.git"
//镜像的版本号
def tag = "latest"
//Harbor的url地址
def harbor_url = "192.168.118.184:85"
//镜像库项目名称
def harbor_project = "tensquare"
//Harbor的登录凭证ID
def harbor_auth = "9b338fcd-6db0-43df-be49-667f8f736299"
node{
stage('拉取代码'){
checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])
}
stage("代码审查"){
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
stage('编译,工程,上传镜像'){
sh 'mvn -f ${project_name} clean package dockerfile:build'
def imageName="${project_name}:${tag}"
sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
withCredentials([usernamePassword(credentialsId: '9b338fcd-6db0-43df-be49-667f8f736299', passwordVariable: 'password', usernameVariable: 'username')]) {
sh "docker login -u ${username} -p ${password} ${harbor_url}"
sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
sh "echo 镜像上传成功"
}
}
}
jenkin参数化构建,拉取代码过程,可能有不同的master分支参数,设置参数
编译项目,打标签,并且上传镜像
def imageName="${project_name}:${tag}"
sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
(因为要登录harbor可能会设计到账户和密码,采取harbor的凭证ID)
5.4 在测试机上向harbor仓库拉去镜像,并且部署到机器上
sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
上传脚本到部署机器上 /opt/jenkins_shell/deploy.sh
#! /bin/sh
#接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
imageName=$harbor_url/$harbor_project_name/$project_name:$tag
echo "$imageName"
#查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
#停掉容器
docker stop $containerId
#删除容器
docker rm $containerId
echo "成功删除容器"
fi
#查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
#删除镜像
docker rmi -f $imageId
echo "成功删除镜像"
fi
# 登录Harbor
docker login -u eric -p Harbor123456 $harbor_url
# 下载镜像
docker pull $imageName
# 启动容器
docker run -di -p $port:$port $imageName
echo "容器启动成功"
同时要设置ssh免密通道,将jenkins服务器上的公钥发送到测试机上
ssh-copy-id root@192.168.118.184
同时在jenkins中相关ssh配置,实现远程发送shell命令
6 进行代码上传,测试流程是否成功
6.1 将相关的配置放入到项目目录下
6.2 配置gitlab服务器地址
6.3 进行代码的上传
6.4 进行jenkins的构建
6.5 构建成功,进行访问,并且查看相关的日志输出
6.6 代码审查结果查看
6.7 邮件发送通知查看
6.8 harbor查看相关的镜像是否上传成功
7. 改进,增加jenkins的slave节点
7.1 开启代理程序的TCP端口
7.2 新建节点
7.3 在slave 服务器上启动节点
curl -sO http://192.168.118.182:8888/jnlpJars/agent.jar
java -jar agent.jar -url http://192.168.118.182:8888/ -secret 80ae1fbe59ce71730735814ad979f55d82b7b5da3d088ac759c4cf2837bbe361 -name slave1 -workDir "/root/jenkins"
运行结果,显示成功
7.4 在jenkins中的pipline脚本中指定slave节点,即可指定slave运行
node('slave') {
stage('check out') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: '68f2087f-a034-4d39-a9ff-1f776dd3dfa8', url:
'git@192.168.66.100:itheima_group/tensquare_back_cluster.git']]])
}
}