相信大家开始玩gitlab+jenkins的时候对着两个工具有肯定有一定了解,我就不做详细解释了,下面就跟大家简单的说下gitlab,jenkins之间工作关系:

GitLab是一个代码仓库,用来管理代码。Jenkins是一个自动化服务器,可以运行各种自动化构建、测试或部署任务。所以这两者结合起来,就可以实现开发者提交代码到GitLab,Jenkins以一定频率自动运行测试、构建和部署的任务,帮组开发团队更高效的集成和发布代码,下面是形象的图片:

gitlab+jenkins自动化上线部署持续集成_第1张图片

废话也不多说直接把我自己在摸索使用过程积攒下来的心德记录下来,给大家做技术分享也方便以后自己回顾,如果有参考不是很清楚的地方,可以多看几遍或者结合官方文档研究研究肯定是会成功的,世上无难事只怕有心人。

汉化部分参考文档:
https://www.cnblogs.com/straycats/p/7637373.html

实验所需安装包:
链接:https://pan.baidu.com/s/1ZzOHQQIhXk7gjtFSZ_hNYw 密码:z9zy

环境部署:

  1. 安装gitlab:(汉化版)

首先安装git:

yum -y install git

获取最新汉化版本库:

git clone https://gitlab.com/xhang/gitlab.git

查看汉化补丁包:

cat gitlab/VERSION

安装gitlab依赖项:

yum install -y curl openssh-server openssh-clients postfix cronie policycoreutils-python

启动postfix并设置开机自启动:

systemctl start postfix
systemctl enable postfix

若防火墙是开启状态的则需要配置一下规则:

firewall-cmd --add-service=http --permanent
firewall-cmd --reload

下载gitlab安装包:

方法一、
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.0.2-ce.0.el7.x86_64.rpm

方法二、
https://packages.gitlab.com/gitlab/gitlab-ce/

安装rpm包:

rpm -i gitlab-ce-10.0.2-ce.0.el7.x86_64.rpm

配置gitlab:

gitlab-ctl reconfigure

修改gitlab配置:

vim /etc/gitlab/gitlab.rb

将external_url变量地址改为gitlab所在主机IP
gitlab+jenkins自动化上线部署持续集成_第2张图片

重新加载配置文件:

gitlab-ctl reconfigure
gitlab-ctl restart

查看gitlab版本:

head -1 /opt/gitlab/version-manifest.txt

覆盖汉化包:

gitlab-ctl stop                                                  #停掉gitlab

cd /root/gitlab                                                 #切换到gitlab汉化包目录下

git diff v10.0.2 v10.0.2-zh > ../10.0.2-zh.diff   #比较汉化标签和源标签并导出patch用的diff文件导/root

cd /root                                                           #切回/root目录下并将10.0.2-zh.diff作为补丁更新到gitlab中

yum install patch -y
patch -d /opt/gitlab/embedded/service/gitlab-rails -p1 < 10.0.2-zh.diff

启动gitlab:

gitlab-ctl start

注:如果gitlab启动失败需要查看本地80端口是否被占用,gitlab默认使用的是80,若需要修改默认端口号查看参考:https://segmentfault.com/a/1190000011266124

重新载入配置:

gitlab-ctl reconfigure

通过Web登录查看:

http://IP
#默认是root和root密码即可登录

访问结果如下:
gitlab+jenkins自动化上线部署持续集成_第3张图片

  1. 下面安装jenkins依赖环境:

安装jdk:

tar zxf jdk-8u91-linux-x64.tar.gz –C /usr/local
ln –s /usr/local/jdk1.8.0_91 /usr/local/jdk

添加jdk环境变量:

vim /etc/profile
JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

安装maven:

tar zxf apache-maven-3.5.3-bin.tar.gz –C /usr/local/
ln –s /usr/local/apache-maven-3.5.3 /usr/local/maven

添加maven环境变量:

M3_HOME=/usr/local/maven
export PATH=$M3_HOME/bin:$PATH

加载环境变量:

source /etc/profile

查看jdk是否安装成功:
gitlab+jenkins自动化上线部署持续集成_第4张图片

查看maven是否安装成功:
gitlab+jenkins自动化上线部署持续集成_第5张图片

部署tomcat8.0:
注:tomcat版本和jdk版本需要需要吻合否则启动成功web访问jenkins始终不成功,最好使用jdk1.8,tomcat8.0

创建tomcat存放目录:

mkdir -p /home/app/tomcat8.0

解压tomcat:

tar zxf apache-tomcat-8.0.51.tar.gz -C /home/app/tomcat8.0

启动tomcat查看是否成功:

/home/app/tomcat8.0/bin/startup.sh 

查看端口启动情况,并使用web访问:
gitlab+jenkins自动化上线部署持续集成

gitlab+jenkins自动化上线部署持续集成_第6张图片

将jenkins程序包放到tomcat里面并重新启动:

mv jenkins.war /home/app/tomcat8.0/webapps/Jenkins.war 

注:如果是本地jenkins的话想关闭web登录校验,可以参考:
https://blog.51cto.com/13859393/2166335

查看jenkins程序包是否正常启动:
直接查看webapps目录即可
gitlab+jenkins自动化上线部署持续集成_第7张图片

测试访问jenkins:
http://IP:8080/jenkins
注:第一次访问jenkins等待时间可能较长,等待的时候需要看服务器的性能
gitlab+jenkins自动化上线部署持续集成_第8张图片

打开界面后,会根据提示发到服务器上查看初始密码:
gitlab+jenkins自动化上线部署持续集成_第9张图片

登录进入后选择安装插件:
注:最省事的方式就是安装官方推荐的插件,但有些时候点击无效,不用着急后面我们进入jenkins可以选择我们需要安装插件

方法一、
gitlab+jenkins自动化上线部署持续集成_第10张图片

插件等待过程中:
gitlab+jenkins自动化上线部署持续集成_第11张图片

方法二、
登录jenkins后点击管理插件:
gitlab+jenkins自动化上线部署持续集成_第12张图片

如果在可选插件中看不到插件,点击高级:
gitlab+jenkins自动化上线部署持续集成_第13张图片

高级地下有个提升站点:
站点地址:http://mirror.xmission.com/jenkins/updates/update-center.json

gitlab+jenkins自动化上线部署持续集成_第14张图片

然后点击左下角提交,在点击右下角立即获取后查看可选插件看是否有插件可选择,如果没有重启jenkins即可(重启jenkins方式即重启tomcat)

安装插件:
jenkins自带的过滤不好用,使用浏览器的过滤器过滤ctrl+f 进行搜索
gitlab+jenkins自动化上线部署持续集成_第15张图片

搜索一下几个关键字,把带有此关键字的全部安装:shell,maven,jdk,git,gitlab,ssh 把搜索到的插件都安装后重启jenkins

配置全局工具:
gitlab+jenkins自动化上线部署持续集成_第16张图片

配置JDK:
把自动选的“自动安装”取消掉,并点击新增JDK
gitlab+jenkins自动化上线部署持续集成_第17张图片

注:JAVA_HOME为jdk路径

配置Git:
查找git路径
gitlab+jenkins自动化上线部署持续集成

gitlab+jenkins自动化上线部署持续集成_第18张图片

配置maven:
gitlab+jenkins自动化上线部署持续集成_第19张图片

最后选择save

下面是三个jenkins需要调用的脚本:cloud-run.sh(jenkins服务端),run-pord.sh(客户端),check-port.sh(客户端),放在/opt/work/目录下,也可以修改脚本内容自己定义:(此处的脚本支持java的spring cloud程序,其他语言或者框架如使用此脚本请稍作修改)
vim /opt/work/cloud-run.sh

#!/bin/bash  

#变量定义
jenkins_item=$1
app_name=$2
source_jar_path="/root/.jenkins/workspace/${jenkins_item}/${app_name}/target/${app_name}-*.jar"
run_cmd_path="/opt/work/run-prod.sh"
run_cmd="/opt/work/./run-prod.sh"
app_home=/opt/work/$app_name
now_user=root
all_param=$3
#本地通过ssh执行远程服务器的脚本  
function check_http(){
        now_ip=$1
        now_app_port=$2
        sleep_time=$3
        justWeb=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://${now_ip}:${now_app_port}`
        if [ !"$justWeb" = 404 ];
        then
                if [ !"$sleep_time" = 10 ];
                then
                        echo "执行${justWeb}时间${sleep_time}s,构建失败"
                        exit 1;
                else
                        sleep_time=$(($sleep_time+1))
                        check_http $now_ip $now_app_port $sleep_time
                fi
        fi
}
for i in ${all_param[@]}
do
        OLD_IFS="$IFS"
        IFS=","
        arr=($i)
        IFS="$OLD_IFS"
        now_ip=${arr[0]}
        now_port=${arr[1]}
        now_app_port=${arr[2]}
        jar_path=$app_home/$app_name-$now_app_port.jar
        echo $now_ip
        echo $now_port
                echo $now_app_port
        #复制脚本到远程地址
        scp -P $now_port $run_cmd_path $now_user@$now_ip:$run_cmd_path

        ssh -t -p $now_port $now_user@$now_ip "mkdir -p $app_home"
        #复制程序jar到远程地址
        scp -P $now_port $source_jar_path $now_user@$now_ip:$jar_path

        #执行远程脚本
        ssh -t -p $now_port $now_user@$now_ip "chmod +x $run_cmd_path"
    ssh -t -p $now_port $now_user@$now_ip "$run_cmd restart $app_name $now_app_port"
        check_http $now_ip $now_app_port 1
        sleep 30s
        ID=`ssh root@$now_ip '/opt/work/check-port.sh'`
        if [ "$ID" == 0 ]; then
                echo "$ID"
                echo "程序启动正常"
        else
                echo "$ID"
                echo "程序启动失败"
                exit
        fi
        sleep 30s
done

vim /opt/work/run-pord.sh

#!/bin/bash --login

APP_NAME=$2
APP_PORT=$3
APP_HOME=/opt/work/$APP_NAME

#创建目录
if [ ! -d "$APP_HOME" ];then
  mkdir -p $APP_HOME
fi

if [ ! -d "$APP_HOME/logs" ];then
  mkdir $APP_HOME/logs
fi

APP_LOG_PATH=$APP_HOME/logs/$APP_PORT
LOG_PATH=$APP_HOME/logs/$APP_PORT.out
JAR_FILE=$APP_NAME-$APP_PORT.jar
BACK_JAR_FILE=$APP_NAME-$APP_PORT.back
PID_FILE=$APP_HOME/$APP_PORT.pid

pid=""
function start(){
  checkpid
  if [ ! -n "$pid" ]; then
    nohup java -server -Xms512m -Xmx1024m -jar $APP_HOME/$JAR_FILE --spring.pid.file=$PID_FILE --server.port=$APP_PORT --logging.path=$APP_LOG_PATH > $LOG_PATH 2>&1 &
    echo "---------------------------------"
    echo "启动完成>>>>>"
    echo "---------------------------------"
    sleep 2s
        exit 0
  else
      echo "$APP_NAME is runing PID: $pid"  
  fi

}

function reback(){
        #还原备份文件
        cp $APP_HOME/$BACK_JAR_FILE $APP_HOME/$JAR_FILE
        restart
}

function status(){
   checkpid
   if [ ! -n "$pid" ]; then
     echo "$APP_NAME not runing"
   else
     echo "$APP_NAME runing PID: $pid"
   fi
}

function checkpid(){
        pid=`ps -ef |grep $JAR_FILE |grep -v grep |awk '{print $2}'`
}

function stop(){
    checkpid
    if [ ! -n "$pid" ]; then
     echo "$APP_NAME not runing"
    else
      echo "$APP_NAME stop..."
          #curl -X POST 'http://127.0.0.1:$APP_PORT/system/shutdown'
          kill -9 $pid
          sleep 1s
          stop
    fi
}

function restart(){
    stop
    sleep 1s
    start
}

case $1 in
          start) start;;
          stop)  stop;;
          restart)  restart;;
          status)  status;;
          reback)  reback;;
#              *)  echo "require start|stop|restart|status|reback"  ;;  
esac

vim /opt/work/check-port.sh

#!/bin/bash
#检测本地程序端口
source /opt/work/run-prod.sh
check_port() {
        netstat -tlpn | grep "\b$1\b" >> /dev/null
}
if check_port $APP_PORT
then
        echo "0"
#    exit 1
else
        echo "1"
fi

此处构建需要用到无秘钥登录,即是jenkins服务器本地部署都需要本机无秘钥登录:

无秘钥登录配置方法:

ssh-keygen (接下来一路狂按回车即可)
cd /root/.ssh/
cat id_rsa.pub >> authorized_keys

测试是否可以无秘钥登录:
gitlab+jenkins自动化上线部署持续集成

现在一切准备好了,开始创建个新任务构建下看看是否成功:
点击新建项目
gitlab+jenkins自动化上线部署持续集成_第20张图片

确定后进行配置:
General
gitlab+jenkins自动化上线部署持续集成_第21张图片

源码管理:
gitlab+jenkins自动化上线部署持续集成_第22张图片

注:
Repositories配置:
Repository URL: 为gitlab中项目连接
Credentials:设置为gitlab中登录的用户名和密码

gitlab中项目连接如下:
点击到需要上线的项目中

gitlab+jenkins自动化上线部署持续集成_第23张图片

Credentials设置:

gitlab+jenkins自动化上线部署持续集成_第24张图片

Branch Specifier (blank for 'any'):项目分支

gitlab+jenkins自动化上线部署持续集成_第25张图片

构建触发器和构建环境不用设置:
gitlab+jenkins自动化上线部署持续集成_第26张图片

配置构建:
刚开始是没有调用顶层Maven目标和执行shell的,需要手动添加:
gitlab+jenkins自动化上线部署持续集成_第27张图片

配置调用顶层Maven目标:
gitlab+jenkins自动化上线部署持续集成

目标:进行打包方式,每种打包方式不同可以问研发,后面的-P dev 为代码中配置文件

执行shell:
gitlab+jenkins自动化上线部署持续集成_第28张图片

命令:/opt/work/cloud-run.sh hcb-eureka-dev hcb-eureka "192.168.3.206,22,10100"
/opt/work/cloud-run.sh :jenkins服务上运行在服务端的一个脚本
hcb-eureka-dev:jenkins项目名
hcb-eureka :gitlab中拉去打包代码的子项目名,同时也是服务器中创建的文件夹名
192.168.3.206:程序需要上传到的服务IP
22:远程的端口号(每次都需要)
10100:程序的端口号
注:此脚本支持同一个程序往不同服务器上上线,可以是通一个端口也可以是不同端口,shell的配置方式如:
gitlab+jenkins自动化上线部署持续集成_第29张图片

构建后操作可以不用设置,直接点击保存即可:
gitlab+jenkins自动化上线部署持续集成_第30张图片

此时可以点击立即构建:
gitlab+jenkins自动化上线部署持续集成_第31张图片

构建历史中可以看到正在构建和已经构建过的项目:
gitlab+jenkins自动化上线部署持续集成_第32张图片

点击到一个构建项目中,项目中可以看到详细信息,以及在构建中弹出的日志:
控制台输出
gitlab+jenkins自动化上线部署持续集成_第33张图片

构建结束后可以看到success:
gitlab+jenkins自动化上线部署持续集成_第34张图片

在服务器中查看程序是否启动,以及端口监听:
gitlab+jenkins自动化上线部署持续集成_第35张图片

查看端口监听,以及进入目录进行查看:
gitlab+jenkins自动化上线部署持续集成

进入/opt/work/目录下查看:
gitlab+jenkins自动化上线部署持续集成_第36张图片

此时可以看到构建已经完成了,完全没有瑕疵

gitlab+jenkins不仅可以自动化java程序其他程序也可以构建,不过构建方式和上线脚本有所改动,很妒忌人以为gitlab+jenkins只能上线java的代码,其实是大家进入了误区,只是市面上现在用java比较多而已


有志者事竟成,破釜沉舟,百二秦关终属楚;
苦心人天不负,卧薪尝胆,三千越甲可吞吴;