Jenkins持续集成平台搭建及项目部署

第一部分 Jenkins持续集成平台搭建

一、整体配置

Jenkins持续集成平台搭建及项目部署_第1张图片

大致流程说明:

  1. 开发人员把代码提交到Gitlab代码仓库
  2. Jenkins从Gitlab中拉取项目源码,编译并打成jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库。
  3. Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器。
  4. 最后,用户可以访问到容器

二、代码托管平台搭建

2.1.GitLab安装及配置

1.安装相关依赖

yum -y install policycoreutils openssh-server openssh-clients postfix

2.启动ssh服务&设置为开机启动

systemctl enable sshd && sudo systemctl start sshd

3.设置postfix开机自启,并启动

systemctl enable postfix && systemctl start postfix

4.关闭防火墙

systemctl stop firewalld.service

5.下载GitLab包,并安装

wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm
rpm -i gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm

6.修改GitLab配置

vim /etc/gitlab/gitlab.rb
external_url 'http://192.168.1.220:8888'
nginx['listen_port'] = 8888

7.重载配置并启动GitLab

gitlab-ctl reconfigure
gitlab-ctl restart

在浏览器输入**http://192.168.1.220:8888** 即可进行访问。

三、持续集成平台搭建

3.1.Jenkins安装及配置

3.1.安装JDK

yum install java-1.8.0-openjdk* -y

安装目录为:/usr/lib/jvm

3.2.安装Jenkins

1.获取Jenkins安装包

下载地址:https://jenkins.io/zh/download/

安装文件:jenkins-2.323-1.1.noarch.rpm

2.把安装包上传到**192.168.1.222**,进行安装

rpm -ivh jenkins-2.323-1.1.noarch.rpm

3.修改Jenkins配置

vim /etc/syscofig/jenkins
JENKINS_USER="root
JENKINS_PORT="8080"

4.启动Jenkins

systemctl start jenkins
systemctl enable jenkins //开机自启

5.打开浏览器访问

http://192.168.1.222:8080

6.获取admin账户密码

cat /var/lib/jenkins/secrets/initialAdminPassword

7.自定义Jenkins->安装推荐的插件

8.创建用户,直接下一步完成。

3.3.安装Git插件和Git工具

3.3.1.安装Git工具
yum install git -y
3.3.2.安装Git插件

Jenkins持续集成平台搭建及项目部署_第2张图片

3.3.3.Git访问配置
3.3.3.1.用户密码类型

Jenkins->凭证->系统->全局凭证->添加凭证选择"Username with password",输入Gitlab的用户名和密码,点击"确定"。

Jenkins持续集成平台搭建及项目部署_第3张图片 Jenkins持续集成平台搭建及项目部署_第4张图片
3.3.3.2.SSH密钥类型

1.使用root用户生成公钥和私钥

ssh-keygen -t rsa

2.把生成的公钥放在GitLab中

​ 以root账户登录->点击头像->Settings->SSH Keys

​ 复制刚才id_rsa.pub文件的内容到这里,点击"Add Key"

Jenkins持续集成平台搭建及项目部署_第5张图片

3.在Jenkins中添加凭证,配置私钥

​ 在Jenkins添加一个新的凭证,类型为"SSH Username with private key",把刚才生成私有文件内容复制过来

Jenkins持续集成平台搭建及项目部署_第6张图片
3.3.4.Maven安装

1.先上传maven软件到**192.168.1.222**中

#解压
tar -xzf apache-maven-3.6.3-bin.tar.gz
#创建maven安装目录
mkdir -p /usr/local/java/maven
#移动解压后的文件到安装目录
mv apache-maven-3.6.3/* /usr/local/java/maven 

2.配置环境

vim /etc/profile
export JAVA_HOME=/usr/local/java/jdk1.8 
export MAVEN_HOME=/usr/local/java/maven 
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
#重载配置文件
source /etc/profile
3.3.5.Docker安装

1.卸载旧版本

#列出当前所有docker的包
yum list installed | grep docker
#卸载docker包
yum -y remove docker的包名称
#删除docker的所有镜像和容器
rm -rf /var/lib/docker

2.安装必要软件包

sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2

3.设置下载的镜像仓库

sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo

4.安装docker

sudo yum install docker-ce-20.10.11.ce

5.启动Docker

#启动
sudo systemctl start docker
#设置开机启动
sudo systemctl enable docker

6.添加阿里云镜像加速地址

vim /etc/docker/daemon.json
{
    "registry-mirrors": ["https://xmgk9z80.mirror.aliyuncs.com"],
    /*
    	添加Harbor地址到Docker的信任列表,不加后续的镜像上传及拉取会有问题
    	The push refers to repository [xxx.xxx.xxx.xxx:xx/xx/xx] Get https://xxx.xxx.xxx.xxx:xx/xx/: http: server gave HTTP response to HTTPS client
    */
    "insecure-registries": ["192.168.1.221:81"]
}

7.重启Docker

sudo systemctl restart docker

3.4.配置JDK、Maven环境

1.配置JDK环境

Jenkins持续集成平台搭建及项目部署_第7张图片

2.配置maven环境

Jenkins持续集成平台搭建及项目部署_第8张图片

在后续Jenkins构建的时候会出现无法找到jdk和maven,需要创建软连接

ln -s /usr/local/java/jdk1.8/bin/java /usr/bin/java
ln -s /usr/local/java/apache-maven-3.6.3/bin/mvn /usr/bin/mvn

3.2.安装SonarQube

3.2.1.安装MySQL数据库

1.下载官方repo

wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

2.安装

yum -y install mysql57-community-release-el7-10.noarch.rpm

3.安装MySQL服务器

yum -y install mysql-community-server

4.启动MySQL

systemctl start  mysqld.service

5.查找root用户密码

grep "password" /var/log/mysqld.log

6.修改root密码

# 进入数据库
mysql -uroot -p
#修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
#开启远程访问
grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option;
#刷新MySQL的系统权限相关表
flush privileges; 

7.修改MySQL编码

vim /etc/my.cnf
[client]
default-character-set=utf8

character-set-server=utf8
collation-server=utf8_general_ci

8.重启MySQL

systemctl restart mysqld.servie

3.2.2.安装SonarQube

1.在MySQL数据库中创建sonar数据库

Jenkins持续集成平台搭建及项目部署_第9张图片

2.下载SonarQube安装包

https://www.sonarqube.org/downloads/

3.将安装包上传到**192.168.1.222**

4.解压并设置权限

#安装unzip
yum install unzip
#解压
unzip sonarqube-6.7.4.zip
#创建目录
mkdir /usr/local/java/sonar
#移动文件
mv sonarqube-6.7.4/* /usr/local/java/sonar
#创建sonar用户,必须sonar用于启动,否则报错
useradd sonar
#更改sonar目录及文件权限
chown -R sonar. /usr/local/java/sonar

5.修改sonar配置文件

vim /usr/local/java/sonar/conf/sonar.properties
sonar.jdbc.username=root 
sonar.jdbc.password=xxxxxx
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

6.启动sonar

cd /usr/local/java/sonar
#启动
su sonar ./bin/linux-x86-64/sonar.sh start

7.访问sonar

http://192.168.1.222:9000

默认账户密码:admin/admin

8.创建token

Jenkins持续集成平台搭建及项目部署_第10张图片

token一定要记下来,配置需要使用

3.2.3.安装SonarQube Scanner插件

1.安装插件

Jenkins持续集成平台搭建及项目部署_第11张图片

2.添加SonarQube凭证

Jenkins持续集成平台搭建及项目部署_第12张图片 Jenkins持续集成平台搭建及项目部署_第13张图片

3.在Jenkins中配置SonarQube

Jenkins持续集成平台搭建及项目部署_第14张图片 Jenkins持续集成平台搭建及项目部署_第15张图片

4.SonarQube关闭审查结构上传到SCM功能

Jenkins持续集成平台搭建及项目部署_第16张图片

3.3部署应用环境搭建

1.安装Publish Over SSH插件

Jenkins持续集成平台搭建及项目部署_第17张图片

2.拷贝公钥到远程服务器

#拷贝公钥到远程服务器
ssh-copy-id 192.168.66.103

3.在Jenkins中配置环境

Jenkins持续集成平台搭建及项目部署_第18张图片

四、Docker仓库搭建

4.1.Harbor安装及配置

1.安装Docker

2.安装docker-compose,并添加执行权限

#安装docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker- compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
#添加执行权限
sudo chmod +x /usr/local/bin/docker-compose

3.下载Harbor安装包

https://github.com/goharbor/harbor/releases

4.上传安装包到**192.168.1.221**,并解压

tar -xzf harbor-offline-installer-v1.9.2.tgz
mkdir /usr/local/java/harbor
mv harbor/* /usr/local/java/harbor
cd /usr/local/java/harbor

5.修改Harbor配置

vim harbor.yml
hostname: 192.168.1.221
port: 81

6.安装Harbor

./perpare
./install.sh

7.启动Harbor

docker-compose up -d

8.访问Harbor

http://192.168.1.221:81

默认账户密码:admin/Harbor12345

五、部署服务器搭建

5.1.安装Docker

安装步骤和上边一致

{
    "registry-mirrors": ["https://xmgk9z80.mirror.aliyuncs.com"],
    /*
    	添加Harbor地址到Docker的信任列表,不加后续的镜像上传及拉取会有问题
    	The push refers to repository [xxx.xxx.xxx.xxx:xx/xx/xx] Get https://xxx.xxx.xxx.xxx:xx/xx/: http: server gave HTTP response to HTTPS client
    */
    "insecure-registries": ["192.168.1.221:81"]
}

第二部分 Jenkins持续集成平台使用

一、Jenkins部分

1.1.创建一个Item

Jenkins持续集成平台搭建及项目部署_第19张图片

1.2.配置Item

Jenkins持续集成平台搭建及项目部署_第20张图片 Jenkins持续集成平台搭建及项目部署_第21张图片

3.点击应用保存即可

这里我们测试Demo为前后端分离,一个后台代码,一个前端代码

二、代码部分

2.1.后台代码

2.1.1.pom文件添加依赖

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-maven-pluginartifactId>
        plugin>
        
        <plugin>
            <groupId>com.spotifygroupId>
            <artifactId>dockerfile-maven-pluginartifactId>
            <version>1.4.13version>
            <configuration>
                <repository>${project.artifactId}repository>
                <buildArgs>
                    <JAR_FILE>target/${project.build.finalName}.jarJAR_FILE>
                buildArgs>
            configuration>
        plugin>
    plugins>
build>

2.1.2.添加Dockerfile文件

在项目根目录添加名为**Dockerfile**文件

FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java", "-jar", "/app.jar"]

2.1.3.添加Jenkinsfile文件

在项目根目录添加名为**Jenkinsfile**文件

内容根据自己项目进行修改

//项目分支
def branch = "master"
//gitlab平台jenkins凭证ID
def gitlab_auth = "801603ce-e268-4349-8b8e-6e517e1ea8be"
//代码仓库地址
def gitlab_url = "http://192.168.1.220:8888/root/jenkins-demo.git"
//Harbor平台jenkins凭证ID
def harbor_auth = "49867939-b8e4-4e4c-a230-71f724022575"
//Docker镜像仓库地址
def harbor_url = "192.168.1.221:81"
//Docker仓库项目名称
def harbor_project = "jenkins"
//应用镜像名称
def image_name = "jenkins-demo"
//镜像版本号
def tag = "latest"
//应用端口
def port = "10086"
//部署脚本地址
def shell_url = "/usr/local/java/jenkins_shell/deploy.sh"
try{
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${gitlab_auth}", url: "${gitlab_url}"]]])
        }
        stage('编译打包,构建Dokcer镜像') {
            //编译,构建本地镜像
            sh "mvn clean package dockerfile:build"
        }
        stage('上传镜像到Docker仓库') {
             //给镜像打标签
            sh "docker tag ${image_name} ${harbor_url}/${harbor_project}/${image_name}"
            //登录Harbor,并上传镜像
            withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                //登录到Harbor
                sh "docker login -u ${username} -p ${password} ${harbor_url}"
                //上传镜像
                sh "docker push ${harbor_url}/${harbor_project}/${image_name}"
            }
            //删除本地镜像
            sh "docker rmi -f ${image_name}"
            sh "docker rmi -f ${harbor_url}/${harbor_project}/${image_name}"
        }
        stage('代码审查') {
            //定义scanner工具
            script {
                scannerHome = tool 'scanner'
            }
            //执行SonarQubeScanner
            withSonarQubeEnv('sonarqube') {
                sh "${scannerHome}/bin/sonar-scanner"
            }
        }
        stage('应用发布') {
            sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '${shell_url} ${harbor_url} ${harbor_project} ${image_name} ${tag} ${port}', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
        }
    }
}
catch (err){
    currentBuild.result="FAILURE"
}
finally{
    //构建后操作,发送构建结果到指定邮箱
    node(env.BuildMachineLabel){
        stage("发送邮件") {
            emailext(
                subject: '构建通知: ${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
                body: '${FILE, path="email-template.html"}',
                to: '[email protected]'
            )
        }
    }
}

2.1.4.添加邮件模板(随意)

文件名称根据流水线脚本来,我这里设置的是**email-template.html**

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>构建TAG  ${BUILD_TAG}li>
                <li>构建编号  第${BUILD_NUMBER}次构建li>
                <li>触发原因: ${CAUSE}li>
                <li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}consolea>li>
                <li>构建  Url  <a href="${BUILD_URL}">${BUILD_URL}a>li>
                <li>工作目录  <a href="${PROJECT_URL}ws">${PROJECT_URL}wsa>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}changesa>li>
            ul>
            ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br/>%c<br/>",showPaths=true,changesFormat="
            <pre>[%a]<br/>%mpre>
            ",pathFormat="    %p"}
        td>
    tr>
    <tr>
        <td><b>Failed Test Resultsb>
            <hr size="2" width="100%" align="center"/>
        td>
    tr>
    <tr>
        <td><pre
                style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTSpre>
            <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>

2.2.前端部分

2.2.1.添加Jenkinsfile文件

在项目根目录添加名为**Jenkinsfile**文件

//项目分支
def branch = "master"
//gitlab平台jenkins凭证ID
def gitlab_auth = "801603ce-e268-4349-8b8e-6e517e1ea8be"
//代码仓库地址
def gitlab_url = "http://192.168.1.220:8888/root/jenkins-ui.git"
node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${gitlab_auth}", url: "${gitlab_url}"]]])
    }
    stage('node安装及项目构建') {
        nodejs('nodejs') {
            sh '''
                npm install
                npm run build
            '''
        }
    }
    stage('项目部署') {
        sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/usr/share/nginx/html', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    }
}

三、部署服务器部分

3.1.部署shell脚本

1.在服务器中创建一个目录,存放部署脚本

mkdir /usr/local/java/jenkins_shell
cd /usr/local/java/jenkins_shell

2.创建部署shell脚本

vim 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 admin -p Harbor12345 $harbor_url 
# 下载镜像 
docker pull $imageName 
# 启动容器 
docker run -di -p $port:$port $imageName
echo "容器启动成功"

3.为部署脚本添加执行权限

chmod +x deploy.sh

四、在Jenkins中进行构建

构建项目

Jenkins持续集成平台搭建及项目部署_第22张图片

构建日志控制台输出

Jenkins持续集成平台搭建及项目部署_第23张图片

邮件接收内容

Jenkins持续集成平台搭建及项目部署_第24张图片 grep -w $project_name | awk '{print $3}'` if [ "$imageId" != "" ] ; then #删除镜像 docker rmi -f $imageId echo "成功删除镜像" fi # 登录Harbor私服 docker login -u admin -p Harbor12345 $harbor_url # 下载镜像 docker pull $imageName # 启动容器 docker run -di -p $port:$port $imageName echo "容器启动成功" ```

3.为部署脚本添加执行权限

chmod +x deploy.sh

四、在Jenkins中进行构建

构建项目

Jenkins持续集成平台搭建及项目部署_第25张图片

构建日志控制台输出

Jenkins持续集成平台搭建及项目部署_第26张图片

邮件接收内容

Jenkins持续集成平台搭建及项目部署_第27张图片

你可能感兴趣的:(jenkins,ci,运维)