一、安装基础环境 1.1 安装JDK1.8 上传JDK1.8二进制包至服务器
解压二进制包并添加java环境变量
1 2 3 4 5 6 7 8 9 ~]$ tar xzvf jdk-8u211-linux-x64.tar.gz ~]$ mv jdk1.8.0_211/ /usr/local/ ~]$ sudo vim /etc/profile export JAVA_HOME=/usr/local/jdk1.8.0_211export JRE_HOME=${JAVA_HOME} /jreexport CLASSPATH=.:${JAVA_HOME} /lib:${JRE_HOME} /lib:$CLASSPATH export JAVA_PATH=${JAVA_HOME} /bin:${JRE_HOME} /binexport PATH=$PATH :${JAVA_PATH}
加载环境变量并验证
1 2 3 4 5 ~]$ source /etc/profile ~]$ java -version java version "1.8.0_211 Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
1.2 安装maven-3.6.3 下载maven二进制包解压并添加到环境变量
1 2 3 4 5 6 7 ~]$ wget https://mirrors.bfsu.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz ~]$ tar xzvf apache-maven-3.6.3-bin.tar.gz ~]$ sudo mv apache-maven-3.6.3 /usr/local/ ~]$ sudo vim /etc/profile export MAVEN_HOME=/usr/local/apache-maven-3.6.3export PATH=$MAVEN_HOME /bin:$PATH
重新加载环境变量并验证
1 2 3 4 5 6 7 ~]$ source /etc/profile ~]$ mvn -v Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /usr/local/apache-maven-3.6.3 Java version: 1.8.0_211, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_211/jre Default locale: zh_CN, platform encoding: UTF-8 OS name: "linux" , version: "3.10.0-957.el7.x86_64" , arch : "amd64" , family: "unix"
1.3 安装Git 1 2 3 ~]$ sudo yum install -y git ~]$ git --version git version 1.8.3.1
1.4 安装NodeJs(前端用) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo $ yum install -y yarn $ yarn -v 1.22.15 $ wget https://nodejs.org/download/release/v10.18.1/node-v10.18.1-linux-x64.tar.gz && tar xzvf node-v10.18.1-linux-x64.tar.gz && mv node-v10.18.1-linux-x64 /usr/local/node-v10.18.1 && chown root:root -R /usr/local/node-v10.18.1/ $ cat >> /etc/profile <<EOF # NodeJs环境变量 export NODE_HOME=/usr/local/node-v10.18.1 export PATH=\$NODE_HOME/bin:\$PATH EOF $ node -v && npm -v v10.18.1 6.13.4
npm设置为国内仓库
1 2 ~]$ npm config set registry https://registry.npm.taobao.org ~]$ npm config get registry
1.5 安装Yarn(前端用) 1 2 3 4 ~]$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo ~]$ yum install yarn -y ~]$yarn -v 1.22.5
二、安装Jenkins服务 2.1 下载安装Jenkins服务 下载jenkins的rpm包并安装
1 2 3 4 5 6 7 ~]$ wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.249.3-1.1.noarch.rpm ~]$ rpm -ivh jenkins-2.249.3-1.1.noarch.rpm warning: jenkins-2.249.3-1.1.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID 45f2c3d5: NOKEY Preparing... Updating / installing... 1:jenkins-2.249.3-1.1
创建jenkins宿主目录并配置jenkins-home到宿主目录
1 2 3 4 5 6 创建Jenkins主目录 ~]$ mkdir /data/jenkins -p ~]$ sudo chown jenkins:jenkins /data/jenkins/ ~]$ vim /etc/sysconfig/jenkins JENKINS_HOME="/data/jenkins"
修改jenkins配置添加自定义java环境变量并启动jenkins
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ~]$ vim /etc/init.d/jenkins candidates=" /etc/alternatives/java /usr/local/jdk1.8.0_211/bin/java # 74行新添加为自己的路径 /usr/lib/jvm/java-1.8.0/bin/java /usr/lib/jvm/jre-1.8.0/bin/java /usr/lib/jvm/java-1.7.0/bin/java /usr/lib/jvm/jre-1.7.0/bin/java /usr/lib/jvm/java-11.0/bin/java /usr/lib/jvm/jre-11.0/bin/java /usr/lib/jvm/java-11-openjdk-amd64 /usr/bin/java " ~]$ systemctl enable jenkins jenkins.service is not a native service, redirecting to /sbin/chkconfig. Executing /sbin/chkconfig jenkins on ~]$ systemctl start jenkins
2.2 配置Jenkins国内仓库 配置jenkins国内镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 ~]$ vim /data/jenkins/hudson.model.UpdateCenter.xml <?xml version='1.1' encoding='UTF-8' ?> <sites> <site> <id >default</id> <url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url> </site> </sites> ~]$ systemctl daemon-reload && systemctl restart jenkins
上面配置jenkins国内镜像仓库失效用下面方法
1 2 3 ~]$ cd $jenkins_home /updates ~]$ sed -i 's/http:\/\/updates.jenkins-ci.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
浏览器访问jenkins8080端口
1 2 ~]$ netstat -anpt | grep 8080 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 13960/java
查看jenkins管理密码进行初始化
1 2 ~]$ cat /data/jenkins/secrets/initialAdminPassword 0c23b38c14f44172a3b678213dfe8baa
2.3 需要安装的插件 Manage Jenkins
–> Manage Plugins
–> 可选插件
–> Search
安装以下插件
Git & Git Parameter
Maven Integration
Localization: Chinese
Pipeline
Config File Provider
Extended Choice Parameter
description setter
Build Name and Description Setter
2.4 Jenkins添加全局工具 添加自定义的工具列表,把前面我们安装的基础环境变量添加进去
Manage Jenkins
–> Global Tool Configuration
–> Maven配置
–> 默认settings提供
–> Settings file in filesystem
–> 填写我们maven的settings.xml文件路径
Manage Jenkins
–> Global Tool Configuration
–> Maven配置
–> 默认全局settings提供
–> Global Settings file on filesystem
–> 填写我们maven的settings.xml文件路径
三、创建pipeline的Job Job的命名规范:项目组名_部署环境名_项目名称
3.1 创建dev_uat后端项目流水线 选择新建一个Job
输入Job名称,创建一个流水线类型的Job
3.2 dev—uat环境pipeline脚本与部署脚本 整个管道大致流程:
不同项目组成员登陆Jenkins账号,选择指定的项目点击构建。
(拉取代码步骤)Jenkins通过Git插件拉取指定项目和指定分支的代码到本地。
(Maven代码编译步骤)Maven对前面拉取的代码进行编译构建生成jar包。
(发布代码步骤)Jenkins服务器执行流程
将构建好的项目jar包 项目名称-exec.jar
移动至 ${project}
目录并格式化规范名称 项目名称-部署的环境-本次构建ID.jar
。
将名称规范的jar包推送到目标部署服务器的 /tmp
目录下。
通过传参的方式,让目标部署主机执行Jenkins服务器本地的部署脚本。
(发布代码步骤)目标服务器脚本部署流程
shell脚本加载服务器环境变量。
通过jps判断发布的服务是否正在运行,如果正在运行就停止服务。
将旧jar包备份至../backup
目录下,将/tmp
下的新jar包移动到当前目录。
启动服务程序,通过判断服务名称来决定服务启动的 JAVA_OPS
参数。
通过jps判断服务是否启动成功,如果启动成功就删除../backup
备份目录下五天之前的jar包。
Jenkins的一个项目一个服务Pipeline脚本内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 // 更换环境需要改的配置 // 1. parameters内的部署环境与对应Git项目地址 // 2. 拉取代码步骤中的对应环境代码分支 // 3.发布代码中的部署环境判断、远程部署的目标主机ip与用户名、不同环境的nacos服务器信息、jar_name环境变量 // 认证 def git_auth = "89efc092-2c68-4b4f-813f-b3e3148ef56e" def deployment_huanjing = "dev" def git_add = "http://172.23.1.57:8082/gitlab/backend/bas-center.git" def git_branch = "develop" def mysh(cmd) { sh('#!/bin/sh -e\n' + cmd) } pipeline { agent any environment{ PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/jdk1.8.0_211/bin/:/usr/local/apache-maven-3.6.3/bin/" } parameters { // 配置发布的环境变量 choice (choices: ["${deployment_huanjing} " ], description: '部署的环境' , name: 'Deployment' ) //choice (choices: ['http://172.23.1.57:8082/gitlab/backend/cms-center.git' ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_add} " ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_branch} " ], description: 'Git分支' , name: 'git_fenzhi' ) } stages { stage('1.拉取代码' ) { steps { //配置构建的分支 //checkout([$class : 'GitSCM' , branches: [[name: '*/develop' ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) checkout([$class : 'GitSCM' , branches: [[name: "*/${git_branch} " ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) } } stage('2.Maven代码编译' ) { steps { mysh '' ' source /etc/profile &> /dev/null mvn clean package -Dmaven.test.skip=true ' '' } } stage('3.发布代码' ) { steps { mysh '' ' if [ ${Deployment} = ' dev' ]; then # 定义变量名称 # 目标部署主机的IP和用户名(需要提前做免密登录) remote_host="172.23.1.55" remote_user="root" jar_name="bas-center" # 定义不同环境的nacos注册中心地址 #uat环境nacos配置 #nacos_server="172.30.26.79:8848" #dev环境nacos配置 nacos_server="172.23.1.55:8848" # jenkins本地临时存放jar包目录 project_mulu="/root/project/\${jar_name}" # 远程部署服务器的jar包目录 remote_service_mulu="/home/framework" # 定义格式化包名生成变量 format_name=\${jar_name}-${Deployment}-${BUILD_NUMBER} old_jar_name=\$(find ./* -name "\${jar_name}-*.jar") new_jar_name="\${format_name}-exec.jar" # 1.判断创建jar包目录,2.将构建后的jar重命名并移动到jar目录,3.发送jar包至部署服务器 [ -d \${project_mulu} ]||mkdir -p \${project_mulu} mv \$old_jar_name \${project_mulu}/\$new_jar_name scp \${project_mulu}/\$new_jar_name \${remote_user}@\${remote_host}:/tmp/ # 远程服务器传参方式执行本地部署脚本 ssh \${remote_user}@\${remote_host} "bash -s" < ~/scripts/dev_uat.sh \${jar_name} \${remote_host} \${remote_service_mulu} \${new_jar_name} ${Deployment} \${nacos_server} fi ' '' } } } }
Jenkins的一个项目多个服务Pipeline脚本内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 // 更换环境需要改的配置 // 1. parameters内的部署环境与对应Git项目地址 // 2. 拉取代码步骤中的对应环境代码分支 // 3.发布代码中的部署环境判断、远程部署的目标主机ip与用户名、不同环境的nacos服务器信息、jar_name环境变量 // 认证 def git_auth = "89efc092-2c68-4b4f-813f-b3e3148ef56e" def deployment_huanjing = "dev" def git_add = "http://172.23.1.57:8082/gitlab/backend/message-center.git" def git_branch = "develop" // 定义mysh函数,取消默认sh打印的多于日志,类似于每个变量名称前都有+号 def mysh(cmd) { sh('#!/bin/sh -e\n' + cmd) } pipeline { agent any environment{ PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/jdk1.8.0_211/bin/:/usr/local/apache-maven-3.6.3/bin/" } parameters { // 配置发布的环境变量 choice (choices: ["${deployment_huanjing} " ], description: '部署的环境' , name: 'Deployment' ) //choice (choices: ['http://172.23.1.57:8082/gitlab/backend/cms-center.git' ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_add} " ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_branch} " ], description: 'Git分支' , name: 'git_fenzhi' ) } stages { stage('1.拉取代码' ) { steps { //配置构建的分支 //checkout([$class : 'GitSCM' , branches: [[name: '*/develop' ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) checkout([$class : 'GitSCM' , branches: [[name: "*/${git_branch} " ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) } } stage('2.Maven代码编译' ) { steps { mysh '' ' source /etc/profile &> /dev/null mvn clean package -Dmaven.test.skip=true ' '' } } stage('3.发布代码' ) { steps { mysh '' ' if [ ${Deployment} = ' dev' ]; then # 定义变量名称 # 目标部署主机的IP和用户名(需要提前做免密登录) remote_host="172.23.1.55" remote_user="root" message_cneter="message-consumer message-producer" info="[INFO]" # 定义不同环境的nacos注册中心地址 #uat环境nacos配置 #nacos_server="172.30.26.79:8848" #dev环境nacos配置 nacos_server="172.23.1.55:8848" # 循环获取单个项目下的多个部署服务名称实现部署 for jar_name in `echo \${message_cneter}` do # jenkins本地临时存放jar包目录 project_mulu="/root/project/message-center/\${jar_name}" # 远程部署服务器的jar包目录 remote_service_mulu="/home/framework" # 定义格式化包名生成变量 format_name=\${jar_name}-${Deployment}-${BUILD_NUMBER} old_jar_name=\$(find ./* -name "\${jar_name}-*.jar") new_jar_name="\${format_name}-exec.jar" # 1.判断创建jar包目录,2.将构建后的jar重命名并移动到jar目录,3.发送jar包至部署服务器 [ -d \${project_mulu} ]||mkdir -p \${project_mulu} mv \$old_jar_name \${project_mulu}/\$new_jar_name scp \${project_mulu}/\$new_jar_name \${remote_user}@\${remote_host}:/tmp/ # 远程服务器传参方式执行本地部署脚本 ssh \${remote_user}@\${remote_host} "bash -s" < ~/scripts/dev_uat.sh \${jar_name} \${remote_host} \${remote_service_mulu} \${new_jar_name} ${Deployment} \${nacos_server} done if [ \${?} -eq 0 ];then echo "==================================================================================================================" echo "\${info} \${message_cneter}项目部署部署成功..." echo "\${info} 部署的目标主机:\${remote_host}" echo "\${info} 部署主机服务目录:\${remote_service_mulu}" echo "\${info} 部署的服务信息:" ssh \${remote_user}@\${remote_host} ". /etc/profile && jps|grep message" echo "==================================================================================================================" else echo "\${info} \${message_cneter}项目部署失败,请检查日志..." fi fi ' '' } } } }
DEV和UAT环境使用的通用shell部署脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 jar_ops1="-Xms256m -Xmx512m -server -Dspring.profiles.active=$5 -Dnacos.server=$6 " jar_ops2="-Xms1000m -Xmx1000m -server -Dspring.profiles.active=$5 -Dnacos.server=$6 " INFO="[INFO]" source /etc/profile &> /dev/nullif [ $(jps -l|grep "$1 " |awk '{print $1}' |wc -l) -ge 1 ];then echo "$INFO $1 服务进程已经存在,正在停止服务..." jps -l | grep "$1 " kill -9 $(jps -l|grep "$1 " |awk '{print $1}' ) if [ $(ps elf|grep -v grep |grep $1 |wc -l) = "0" ];then echo "$INFO $1 服务进程停止成功,开始部署服务......" fi else echo "$INFO $1 服务进程不存在,开始部署服务......" fi sleep 3cd $3 [ -d ../backup ]|| mkdir ../backup -p old_jar=$(basename $(find ./$1 *-exec.jar -type f)) if [ -f ./${old_jar} ];then echo "${INFO} 备份${1} 服务的历史jar包至${3} /../backup目录下" echo "历史的jar包名称:${old_jar} " mv ${old_jar} ../backup/ else echo "${INFO} 不存在历史jar包,不进行备份..." fi echo "${INFO} 移动${1} 服务最新jar包${4} 至${3} 目录下。" mv /tmp/$4 ./if [ $1 == "gratus-center" -o $1 == "pms-center" -o $1 == "oms-center" -o $1 == "payment-center" ];then echo "$INFO 正在启动${1} 服务..." nohup java -jar $jar_ops2 $3 /$4 >> $3 /nohup.out 2>&1 & sleep 20 else echo "$INFO 正在启动${1} 服务..." nohup java -jar $jar_ops1 $3 /$4 >> $3 /nohup.out 2>&1 & sleep 20 fi if [ $(jps -l |grep -v grep |grep $1 |wc -l) -ge 1 ];then echo "$INFO ------------------------------------------------------------------------" echo "$INFO DEPLOYMENT SUCCESS" echo "$INFO ------------------------------------------------------------------------" echo "$INFO ${1} 服务部署成功,新的部署项目名称为$4 " echo $(jps -l |grep -v grep |grep $1 ) echo "$INFO 部署的目标主机:$2 " echo "$INFO 目标主机服务存放目录:$3 /$4 " echo "$INFO 历史jar包备份目录:$3 ../backup/$4 " else echo "${ERRO} ${1} 服务发布失败,请查看$3 /nohup.out输出日志" exit 1 fi
3.3 preprd-prd环境pipeline脚本与部署脚本 整个管道大致流程:
不同项目组成员登陆Jenkins账号,选择指定的项目点击构建。
(拉取代码步骤)Jenkins通过Git插件拉取指定项目和指定分支的代码到本地。
(Maven代码编译步骤)Maven对前面拉取的代码进行编译构建生成jar包。
(发布代码步骤)Jenkins服务器执行流程
将构建好的项目jar包 项目名称-exec.jar
移动至 ${project}
目录并格式化规范名称 项目名称-部署的环境-本次构建ID.jar
。
判断部署的环境如果为pro
生产环境,即获取nacos
的登录token
,之后通过curl
针对当前部署的服务在nocas
进行下线操作并延迟20秒钟。
将名称规范的jar包推送到for
循环获取到的目标部署服务器 /tmp
目录下。
通过传参的方式,让目标部署主机执行Jenkins服务器本地的部署脚本。
(发布代码步骤)目标服务器脚本部署流程
shell脚本加载服务器环境变量。
通过jps判断发布的服务是否正在运行,如果正在运行就停止服务。
将旧jar包备份至../backup
目录下,将/tmp
下的新jar包移动到当前目录。
启动最新的服务程序jar包
通过for
循环三次每次间隔10秒对服务的ip:port/doc.html
页面健康探测,状态码为200即为active。
判断健康检查为active时即打印成功的部署信息,Jeknis继续下一个发布操作。
判断健康检查非active时,随后判断部署的环境是否为prd
生产环境,当为生产环境时执行回滚版本操作,从backup
目录下移动上一个版本的jar
包到服务发布目录,重新启动历史jar包,健康探测成功后退出脚本,终止后续发布操作。非prd生产环境时就退出脚本终止后续发布操作。
preprd_prd的Pipeline脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 // 更换环境需要改的配置 // 1. git的验证ID、git地址、git拉取的分支、部署的环境、当前服务使用的端口号 // 2. 发布代码中的:jar_name、remote_host_list(多个主机空格隔开)、remote_user、remote_service_mulu、project_mulu、nacos_server、nacos_username、nacos_password // gitlab认证账号密码的JenkinsID def git_auth = "e810a67e-8430-4517-8f58-25b5bb0cc103" def git_add = "http://172.23.1.57:8082/gitlab/backend/cms-center.git" def git_branch = "develop" def deployment_huanjing = "uat" def remote_service_port = "7400" def mysh(cmd) { sh('#!/bin/sh -e\n' + cmd) } pipeline { agent any environment{ PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/jdk1.8.0_211/bin/:/usr/local/apache-maven-3.6.3/bin/" } parameters { // 配置发布的环境变量 choice (choices: ["${deployment_huanjing} " ], description: '部署的环境' , name: 'Deployment' ) choice (choices: ["${git_add} " ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_branch} " ], description: 'Git分支' , name: 'git_fenzhi' ) choice (choices: ["${remote_service_port} " ], description: '服务端口号' , name: 'Remote_service_port' ) } stages { stage('1.拉取代码' ) { steps { //配置构建的分支 //checkout([$class : 'GitSCM' , branches: [[name: '*/develop' ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) checkout([$class : 'GitSCM' , branches: [[name: "*/${git_branch} " ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) } } stage('2.Maven代码编译' ) { steps { mysh '' ' source /etc/profile &> /dev/null mvn clean package -Dmaven.test.skip=true ' '' } } stage('3.发布代码' ) { steps { mysh '' ' # 定义构建后jar包前缀变量名称 jar_name="cms-center" # 目标部署主机的IP和用户名(需要提前做免密登录) remote_host_list="172.23.5.92 172.23.5.107" remote_user="root" # 远程部署服务器的jar包目录 remote_service_mulu="/home/framework" # jenkins本地临时存放jar包目录 project_mulu="/root/project/\${jar_name}" # 定义nacos登录信息 # dev #nacos_server="172.23.5.117:8848" # uat nacos_server="172.23.5.117:8849" nacos_username="nacos" nacos_password="neoderm2020" nacos_token=`curl -s -X POST -d "username=\${nacos_username}&password=\${nacos_password}" \${nacos_server}/nacos/v1/auth/users/login | awk -F ' "' '{print $4 }'` # 定义格式化包名生成变量 format_name=\${jar_name}-${Deployment} -${BUILD_NUMBER} old_jar_name=\$(find ./* -name " \${jar_name} -*.jar") new_jar_name=" \${format_name} -exec.jar" # 1.Jenkins本地判断创建jar包目录。2.将构建后的jar重命名并移动到jar目录。3.判断部署环境如果为prd环境则进行nacos注册中心节点下线操作。4.传送最新jar包至远程服务器。5.远程主机执行本地部署脚本 [ -d \${project_mulu} ]||mkdir -p \${project_mulu} mv \$old_jar_name \${project_mulu}/\$new_jar_name for remote_host in `echo \${remote_host_list}` do echo " ===========================【开始部署\${jar_name} 服务至远程主机:\${remote_host} 】===========================" # 根据部署环境判断是否nacos提前下线节点 if [ ${Deployment} = 'uat' ]; then nacos_offline_param=" serviceName=\${jar_name} &clusterName=DEFAULT&groupName=DEFAULT_GROUP&ip=\${remote_host} &port=${Remote_service_port} &enabled=false " [ " \${nacos_token} " == " " ]||echo " [INFO] 获取到Nacos登录Token:\${nacos_token} " echo " [INFO] 正在从Nacos服务器下线\${remote_host} 节点的\${jar_name} 服务..." curl -s -X PUT -d " ${nacos_offline_param} " http://${nacos_server} /nacos/v1/ns/instance?&accessToken=${Nacos_Token} && echo " [INFO] 通知Nacos服务下线成功,20秒后开始部署服务..." sleep 20 fi scp \${project_mulu}/\$new_jar_name \${remote_user}@\${remote_host}:/tmp/ # 远程服务器传参方式执行本地部署脚本 ssh \${remote_user}@\${remote_host} " bash -s" < ~/scripts/preprd_prd.sh \${jar_name} \${remote_host} \${remote_service_mulu} \${new_jar_name} ${Deployment} \${nacos_server} ${Remote_service_port} echo " ================================================【END】================================================" done ''' } } } }
preprd_prd的shell部署脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 jar_ops="-Xms256m -Xmx512m -server -Dspring.profiles.active=$5 -Dnacos.server=$6 " INFO="[INFO]" ERRO="[ERRO]" source /etc/profile &> /dev/nullif [ $(jps -l|grep "${1} " |awk '{print $1}' |wc -l) -ge 1 ];then echo "${INFO} ${1} 服务进程已经存在,正在停止服务..." jps -l | grep "${1} " kill -9 $(jps -l|grep "${1} " |awk '{print $1}' ) if [ $(ps elf|grep -v grep |grep ${1} |wc -l) = "0" ];then echo "${INFO} ${1} 服务已经停止成功,开始部署服务..." fi else echo "${INFO} ${1} 服务进程不存在,开始部署服务..." fi sleep 3cd ${3} [ -d ../backup ]|| mkdir ../backup -p old_jar=$(basename $(find ./$1 *-exec.jar -type f)) if [ -f ./${old_jar} ];then echo "${INFO} 备份${1} 服务的历史jar包至${3} /../backup目录下" echo "${INFO} 历史的jar包名称:${old_jar} " mv ${old_jar} ../backup/ else echo "${INFO} 不存在历史jar包,不进行备份..." fi echo "${INFO} 移动${1} 服务最新jar包${4} 至${3} 目录下。" mv /tmp/$4 ./echo "$INFO 正在启动${1} 服务..." nohup java -jar ${jar_ops} ${3} /${4} >> ${3} /nohup.out 2>&1 &sleep 20for i in `seq 3`do http_code=$(curl -m 5 -s -o /dev/null -w %{http_code} http://${2} :${7} /doc.html) if [ "${http_code} " == "200" ];then service_status="active" echo "${INFO} 服务健康检查成功,状态为${service_status} " break else service_status="down" echo "${INFO} 第${i} 次${2} :${7} /doc.html主机${7} 端口健康探测状态为down..." fi sleep 10 done if [ "$service_status " == "active" ];then echo "$INFO ------------------------------------------------------------------------" echo "$INFO DEPLOYMENT SUCCESS" echo "$INFO ------------------------------------------------------------------------" echo "$INFO ${1} 服务部署成功,新的部署项目名称为$4 " echo $(jps -l |grep -v grep |grep $1 ) echo "$INFO 部署的目标主机:$2 " echo "$INFO 目标主机服务存放目录:$3 /$4 " echo "$INFO 历史jar包备份目录:$3 ../backup/$4 " else if [ "$5 " == "uat" ];then echo "${ERRO} ${1} 服务发布失败,已停止后续节点发布操作,开始回滚服务至${old_jar} 版本..." find ./ -name "${1} -*.jar" -exec mv {} ../backup \; mv ../backup/${old_jar} ./ [ -f ./${old_jar} ]&& echo "$INFO 历史jar包已经移动至${3} 发布目录下,正在启动服务..." nohup java -jar $jar_ops $3 /${old_jar} >> $3 /nohup.out 2>&1 & sleep 30 if [ $(jps -l |grep -v grep |grep $1 |wc -l) -ge 1 ];then echo "$INFO ------------------------------------------------------------------------" echo "$INFO RollBACK SUCCESS TO ${old_jar} " echo "$INFO ------------------------------------------------------------------------" exit 100 else echo "${ERRO} ${1} 服务发布失败,请查看$3 /nohup.out输出日志..." exit 1 fi else echo "${ERRO} ${1} 服务发布失败,请查看$3 /nohup.out输出日志" fi fi
3.3 创建前端项目Job 安装Nginx服务器
1 2 /]$ vim /etc/yum.repos.d/nginx.repo /]$ yum install -y nginx
创建web根目录并生成nginx虚拟机主机配置文件
1 2 3 4 5 6 7 8 9 10 /]$ mkdir -p /data/web /]$ vim /etc/nginx/conf.d/web-center-admin.conf server { listen 8066; location / { root /data/web/; try_files $uri $uri / /admin/index.html; } }
测试nginx配置是否正常,启动nginx服务验证。
1 2 3 4 5 /]$ nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful /]$ systemctl enable nginx /]$ systemctl start nginx
前端使用的pipeline代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 // 更换环境需要修改的配置 // 1. 通用全局变量中的Gitlab账号的凭据ID、要部署的环境(dev|uat)、当前流水线使用的git地址、流水线构建的分支 // 2. 拉取代码步骤中的对应环境代码分支 // 3.发布代码中的部署环境判断、远程部署的目标主机ip与用户名、不同环境的nacos服务器信息、jar_name环境变量 // 部署的jar包命名规范:项目名称-部署的环境-本次构建ID.jar // Git认证信息与部署环境项目分支 def deployment_huanjing = "dev" def git_auth = "89efc092-2c68-4b4f-813f-b3e3148ef56e" def git_add = "http://172.23.1.57:8082/gitlab/frontenddev/web-center.git" def git_branch = "develop" def mysh(cmd) { sh('#!/bin/sh -e\n' + cmd) } pipeline { agent any // 定义Jenkins构建时加载的环境变量路径 environment{ PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/jdk1.8.0_211/bin/:/usr/local/apache-maven-3.6.3/bin/:/usr/local/node-v10.18.1/bin/" } parameters { // 定义参数化构建,会调用全局变量中的内容在构建时可视化展示。 choice (choices: ["${deployment_huanjing} " ], description: '部署的环境' , name: 'Deployment' ) choice (choices: ["${git_add} " ], description: 'Git地址' , name: 'git_url' ) choice (choices: ["${git_branch} " ], description: 'Git分支' , name: 'git_fenzhi' ) } stages { stage('1.拉取代码' ) { steps { // 配置构建流水线时拉取的代码信息 checkout([$class : 'GitSCM' , branches: [[name: "*/${git_branch} " ]], doGenerateSubmoduleConfigurations: false , extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth} " , url: "${git_url} " ]]]) } } stage('2.Maven代码编译' ) { steps { mysh '' ' info="[INFO] " project_name="admin-frontend" echo "\${info}开始构建编译代码..." source /etc/profile &> /dev/null cd \${project_name} yarn && yarn build if [ $? -eq 0 ];then echo "\${info}项目代码编译构建成功,开始发布代码至目标服务器..." else echo "\${info}项目构建失败..." fi ' '' } } stage('3.发布代码' ) { steps { mysh '' ' # 传送构建成功的项目至目标主机项目目录 # 目标部署主机的IP和用户名(需要提前做免密登录) info="[INFO] " remote_host="172.23.1.55" remote_user="root" remote_scp_service="admin" remote_service_mulu="/data/web" project_name="admin-frontend" if [ ${Deployment} = ' dev' ]; then scp -r ./\${project_name}/dist/\${remote_scp_service} \${remote_user}@\${remote_host}:\${remote_service_mulu} if [ $? -eq 0 ];then echo "\${info}\${project_name}项目部署成功,部署的服务器:\${remote_host} 部署的vhost目录:\${remote_service_mulu}" else echo "\${info}项目构建失败...查看Jenkins服务器日志..." fi fi ' '' } } } }
四、分项目组看到不同视图权限 公司内部Jenkins项目太多,不同的项目组与开发测试人员要有不同项目的权限。系统自带的矩阵管理不太适合,这里使用Role-based Authorization Strategy插件,使不同的账号有不同的权限,看到不同的项目。
本次试验的目的是:dev和uat两组人员,登录自己的jenkins账号,只可以看到自己项目组的任务,并且只有read和build的权限。
1.安装Role-based Authorization Strategy插件,安装后重启jenkins。
开启插件
系统管理>>>全局安全配置>>>Role-Based Strategy
3.创建dev和uat代表不同项目组的成员
Manage Jenkins
—> Manage Users
—> 新建用户
4.创建权限角色并把权限角色分配给用户
5.在创建Job时不同项目按不同名称前缀来命名,例如dev组的Job名以BackEnd_dev
开头
添加项目角色时,需要制定匹配项目的模式,如上图中的 Pattern,官方文档介绍该选项支持正则表达式,如“Roger-.”表示所有以 Roger-开头的项目,“(?i)roger-.*”表示以 roger-开头的项目并且不区分大小写,*如以 ABC开头的项目可以配置为“ ABC**|ABC .*”,也可以使用“abc|bcd|efg ”直接匹配多个项目。**
**此处一定注意:**全局角色**admin不能删除,且必须在*全局角色*中创建一个只有Overall/Read的角色,这个角色是分配给下面的项目角色使用的,否则,分配了项目角色的用户登录后会提示“ 用户名 is missing the Overall/Read permission”
6.登陆dev或者uat的用户验证权限