Jenkins

Jenkins功能

Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括:

  1. 持续的软件版本发布/测试项目。

  2. 监控外部调用执行的工作。

环境搭建

这里简单介绍如何搭建jenkins运行环境。

安装jdk

oracle官网

安装jenkins

JDK 1.8.x + tomcat 8.x + Jenkins 2.62

tomcat官网

wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.15/bin/apache-tomcat-8.5.15.zip

Jenkins官网

wget http://mirrors.jenkins.io/war/latest/jenkins.war

将 jenkins.war 复制到tomcat的webapp目录下,启动tomcat。(默认端口为8080)

如果tomcat权限不够无法启动,修改bin目录的下的执行文件权限

chmod u+x *.sh

输入 http://ip:8080/jenkins/访问jenkins的dashboard。

找到登录密码

cat /home/ubuntu/.jenkins/secrets/initialAdminPassword

安装插件

选择自定义安装插件

创建管理员用户

创建完管理员用户,成功后会跳到dashboard的首页。

安装git

官网

apt-get install git

配置gitlab的ssh密钥

ssh-keygen -t rsa -C "luming@mlogcn.com"

生成路径变换成 /home/ubuntu/.ssh/gitlab_rsa

获取公钥信息,并复制到gitlab中

cat ~/.ssh/gitlab_rsa.pub

编辑~/.ssh/config文件,如果没有,就创建一个,在其中写入如下配置内容

Host gitlab.mlogcn.com
     IdentityFile ~/.ssh/gitlab_rsa

初始化GIT信息

git config --global user.name "luming"
git config --global user.email "luming@mlogcn.com"

测试git的ssh key 配置情况

git clone xxx

安装maven

官网

wget http://apache.fayea.com/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip

设置maven环境变量

vim /etc/profile
export PATH=/home/ubuntu/apache-maven-3.3.9/bin:$PATH
source /etc/profile

测试maven:编译git中clone下来的项目

mvn clean install -Dmaven.test.skip=true

配置jenkins

系统管理 -> Global Tool Configuration

配置JDK

如图,勾掉自动安装,填写jdk环境信息

配置git

如图,勾掉自动安装,填写git环境信息

配置maven

查看maven安装信息

mvn --version

如图,勾掉自动安装,填写maven环境信息

使用jenkins

创建一个新任务

点击创建一个新任务,进入任务创建页面

创建一个maven工程

配置项目属性

General

填写项目名称和描述信息。

源码管理

选择Git,填写源码GIT地址和分支

构建触发器

选择当gitlab分支发生push动作的时候构建。Build when a change is pushed to GitLab。并填写允许的分支。

GitLab CI Service URL填入到gitlab项目中。

build

填写需要编译的pom.xml文件,并填写mvn编译命令

clean install -Dmaven.test.skip=true

立即构建

保存设置,进入刚刚创建的任务,然后执行立即构建来创建工作区。

点击当前编译,可以查看编译信息,如日志:

编译完成后,进入到jenkins的工作目录,可以看到成功创建了workspace目录,并从git上获取了对应的项目代码, 并执行了maven编译。

在jenkins的工作区间页面上也能看到项目文件

到目前为止,我们只完成了在指定分支上push代码的时候,自动获取并编译项目的步骤。接下来我们配置自动部署编译好的文件到指定目标服务器。

自动部署

如何让jenkins实现自动部署呢?这里提供我的思路:

让jenkins在编译成功后,执行shell脚本,将工作目录下的编译好的包扔到目标服务器上,然后运行。

设置任务Post Steps

选择当编译成功的时候执行Shell脚本

这里我们执行编写的deploy.bash 脚本

bash deploy.bash koala

编写运行脚本

下面是我自己写的执行脚本,主要功能是从config.json中读取配置信息,将编译好的包扔到指定服务器,并传送一个执行脚本到该服务器,执行该脚本,完成自动部署流程。

因为是用json做的配置文件,这里用jq作为json解析器

安装jq

apt-get install jq

下面是config.sh配置文件

[
 {
   "name": "koala-meta",
   "version": "v1",
   "path": "koala-meta/koala-meta-service",
   "deploys": [
   {
   "ip": "10.172.167.0",
   "port": "8085",
   "dpath": "/home/ubuntu/apps/koala"
   },
   {
   "ip": "10.172.167.0",
   "port": "8086",
   "dpath": "/home/ubuntu/apps/koala"
   }
  ]
 }
]

下面是deploy.sh 脚本

#!/bin/bash
#定义配置文件
JENKINSPACE=/home/ubuntu/.jenkins/workspace
BASH_PATH=/home/ubuntu/.jenkins/workspace/publish.sh
PROJECTNAME=$1
CONFIG_FILE=${JENKINSPACE}/${PROJECTNAME}/config.json
INDEX=0
for NAME in `cat $CONFIG_FILE | jq -r .[].name` ; do
 VERSION=`cat $CONFIG_FILE | jq -r .[$INDEX].version`
 FPATH=`cat $CONFIG_FILE | jq -r .[$INDEX].path`
 echo "MODULE : $NAME  $VERSION $FPATH"
 D_INDEX=0
 for IP in `cat $CONFIG_FILE | jq -r .[$INDEX].deploys[].ip` ; do
  PORT=`cat $CONFIG_FILE | jq -r .[$INDEX].deploys[$D_INDEX].port`
  DPATH=`cat $CONFIG_FILE | jq -r .[$INDEX].deploys[$D_INDEX].dpath`
  ((D_INDEX++))
  echo "IP is $IP PORT is $PORT dpath is $DPATH"
  #创建目标服务器目录
  ssh -t -t -p 1022 $IP "mkdir -p $DPATH"
  #将文件scp到目标服务器
  scp -P 1022 ${JENKINSPACE}/${PROJECTNAME}/${FPATH}/target/*.zip ${IP}:${DPATH}/${NAME}_${VERSION}_${PORT}.zip
  scp -P 1022 ${BASH_PATH} ${IP}:${DPATH}/.
  ssh -t -t -p 1022 $IP "bash $DPATH/publish.sh $PORT ${DPATH}/${NAME}_${VERSION}_${PORT} ${DPATH}/${NAME}_${VERSION}_${PORT}.zip"
  done
 ((INDEX++))
done
#结束退出
exit

下面是publish.sh脚本

#!/bin/bash
PORT=$1
FILEPATH=$2
ZIPPATH=$3
function killByPort(){
 for kpid in `sudo lsof -t -i:${PORT}` ; do
 echo "THE PID IS $kpid"
 kill $kpid
 done
}
function readandreplace(){
 compstr=$1
 replacestr=$2
 filepath=$3
 filebakpath=$filepath"_bak"
 mv $filepath $filebakpath
 while read LINE
 do
  echo "READ LINE INFO : $LINE"
  case "$LINE" in
   "$compstr"* ) LINE=$compstr"="$replacestr
   ;;
  esac
 echo $LINE >> $filepath
 done < $filebakpath
}
killByPort
rm -rf $2
unzip -o -d $2 $3
readandreplace server.port $PORT ${FILEPATH}/conf/bootstrap.properties
readandreplace port $PORT ${FILEPATH}/conf/appinfo.properties
pwd
cd ${FILEPATH}
pwd
nohup bash start.sh
exit

下面是start.sh 执行文件

#!/bin/sh
source config.sh
nohup java $JAVA_OPTS  $AGENT_OPTS -cp $classpath com.mlog.koala.meta.MetaStationApplication  >>out.log &
pid=$!
echo $pid>koala.pid

下面是config.sh 执行文件

#!/bin/sh
classpath="./conf"
for file in lib/*.jar
do
  if [[ ! -f "$file" ]]
  then
      continue
  fi
  classpath="$classpath:$file"
done
JAVA_OPTS="-Duser.timezone=GMT+08"
AGENT_OPTS=""
if [ -f lib/sharelibs-health*.jar ];then
    healthAgent=`ls -lrt lib/sharelibs-health-*.jar |awk -F" " '{print $NF}'`
    AGENT_OPTS="$AGENT_OPTS  -javaagent:$healthAgent"
fi

if [ -f lib/mlog-log*.jar ];then
    logAgent=`ls -lrt lib/mlog-log*.jar |awk -F" " '{print $NF}'`
    AGENT_OPTS="$AGENT_OPTS  -javaagent:$logAgent=catch_error=true"
fi
export AGENT_OPTS
export classpath
export JAVA_OPTS
echo $AGENT_OPTS

设置jenkins服务器到目标服务器的免密登录

生成ssh key

ssh-keygen -t rsa -f jenkins_rsa

将公钥scp到目标服务器

scp -p 22 ~/.ssh/jenkins_rsa.pub 10.172.167.0:~/.ssh/.

配置config文件

Host 10.172.167.0
     IdentityFile ~/.ssh/jenkins_rsa

测试

将脚本放到jenkins目录下。

在koala项目下,进行一次代码提交。

在非发布分支下提交

在luming分支下做代码提交

进入jenkins的koala任务页面,可以看到jenkins并没有反应。

切换到testpub分支,重复一遍上述步骤

然后在jenkins上看到了我们想要的结果

进入部署服务器,确认一下部署结果

其他问题

jenkins执行Shell脚本结束后,显示执行失败如果解决?

在最末尾加上

echo commonder quit!

修改 设置任务Post Steps

选择当编译成功的时候执行Shell脚本

这里我们执行编写的deploy.bash 脚本

bash /home/ubuntu/.jenkins/workspace/deploy.bash koala

调整为

#!/bin/bash
bash /home/ubuntu/.jenkins/workspace/deploy.sh koala 
echo commonder quit!