Jenkins结合gitlab实现持续集成

前言:

发布对于运维人员而言是一件常事,发布的时候你敲每一个命令都得很细心,但人往往会因为一些环境因素影响而导致失误,而且有些小公司代码迭代速度快一天需要更新几个版本,运维人员在多次的同样操作后,可能会因为精神不集中或其他事而分心,导致误操作而影响线上业务。

简介:

本文将介绍jenkins结合gitlab实现持续集成,解放运维人员的双手,让运维人员可以有更多的时间去钻研其他技术,提升服务稳定性和创造更大的价值。

"1.png"

环境:

Jenkins发布机器:172.16.47.187
gitlab代码仓库:172.16.47.185
Nginx服务器:172.16.47.188

Jenkins的安装将会在往后更新,敬请谅解

配置ssh免密登陆:

#在发布机器上创建sshkey
[root@jenkins ~]# useradd www
[root@jenkins ~]# passwd www
Changing password for user www.
New password: 123456
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 123456
passwd: all authentication tokens updated successfully.
[root@jenkins ~]# su - www
[www@jenkins ~]$ ssh-keygen -t ras
[www@jenkins ~]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDX9V9MAzNlITVsDu97EgXSSu3q4pRq6CleXY9468BJWRlIWEMpuSy1a6NYlY+kEUjnFfvhjtG6o0WJy96NIH+0p4iSfI/5j2pMQuViJl7M8sA3ujJ9EwIgXwX1zYkpWvQEC2znHR5/GdpuJCZnH0clJs+RmUAxG6X7xxXQTFSzXzHp2Gktzunr1R/yfvIZEqIlozbf7IDHYujiCtZDNhdKrKEUFjmZwTk4XRMsRu08wD12ygCEtV/xCoYuPdco3YtYSoYjpkOlR0RHBl2eMbkze+ogIyAieRjK4WRiT7ucl+ddQ7rGi0dG1RvzBctvtWfHCKYdRdALSunvJxUN/Th www@jenkins

#将公钥放到nginx服务器上的www用户下
[root@nginx-node1 ~]# user add www
[root@nginx-node1 ~]# su - www
[www@nginx-node1 ~]$ vim ~/.ssh/authorized_keys

#将Jenkins发布机器生成的ssh公钥放到里面

#Jenkins测试登陆nginx服务器
"2.png"

#将Jenkins发布机器公钥放到gitlab上
"3.png"

#创建一个项目并测试通过ssh拉取代码
"4.png"

持续化构建配置:

#在浏览器输入http://172.16.47.187:8080 点击系统管理-插件管理-可选插件
"5.png"

#将Jenkins发布机器私钥添加到Jenkins里 点击凭据
"6.png"
"7.png"

#创建一个新的任务
"8.png"
"9.png"

#保存退出,点击立即构建
"10.png"

#随机生成10个数字用于jenkins与gitlab的token验证
[www@jenkins ~]$ openssl rand -hex 10
84b3b8cdf9ab33a0481b

#配置jenkins触发器
"11.png"

#配置gitlab webhook
"12.png"
"13.png"
"14.png"

#返回200即为成功

#安装ssh插件
"15.png"

#返回首页,点击凭据
"16.png"

#添加凭据
"17.png"

#保存返回首页,点击auto-deploy项目-配置
"18.png"

#更改index.html文件,提交代码
"19.png"
"20.png"

#到此为止,通过git push触发jenkins自动化部署就已经完成了。

附录:

自动化Shell脚本

该脚本并不是很完善,仅仅满足自动化部署,可根据自身情况修改该脚本
#!/bin/bash

USER="www"

#Code env
PRO_NAME="auto-deploy"
CODE_DIR="/data/code"
SOURCE_DIR="/data/source/$PRO_NAME"
WEB_DIR="/data/nginx/html"
TMP_DIR="/data/deploy_tmp"

#Date/Time
CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H%M_%S")

#Node list
NODE_LIST='172.16.47.188'
ROLLBACK_LIST='172.16.47.188'

#Shell Env
SHELL_DIR="/data/shell/"
SHELL_NAME="auto-deploy"

#log
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/deploy.lock"

#Lock
shell_lock(){
    touch ${LOCK_FILE}
}

shell_unlock(){
    rm -f ${LOCK_FILE}
}

#URL Test
url_test(){
    URL=$1
        curl -s --head $URL|egrep '200|301|302'
    if [ $? -ne 0 ];then
        shell_unlock;
        echo "$URL test error" && exit;
    fi
}

writelog(){
    LOGINFO=$1
    echo "${CDATE}-${CTIME}:${SHELL_NAME}:${LOGINFO}" >> ${SHELL_LOG}
}

code_get(){
    writelog "code_get"
    cd $SOURCE_DIR
        git pull
        GIT_CID=$(git log|awk 'NR==1{print $2}'|cut -c 1-6)
        PKG_VER="${CDATE}_${CTIME}_${GIT_CID}"
        PKG_NAME="${PRO_NAME}_${PKG_VER}"
        cp -r ${SOURCE_DIR} ${TMP_DIR}/${PKG_NAME}
}

code_tar(){
    writelog "code_tar"
    cd ${TMP_DIR} && tar czf ${PKG_NAME}_tar.gz ${PKG_NAME}
        writelog "${PKG_NAME}_tar.gz"
}

code_scp(){
    writelog "code_scp"
    for node in $NODE_LIST;do
        scp ${TMP_DIR}/${PKG_NAME}_tar.gz $USER@$node:${TMP_DIR}/
    done
}

pre_deploy(){
    writelog "remove from cluster"
    ssh $USER@$NODE_LIST "cd ${TMP_DIR} && tar xf ${PKG_NAME}_tar.gz -C ${CODE_DIR}/"
    ssh $USER@$NODE_LIST "rm -f $WEB_DIR/${PRO_NAME} && ln -s ${CODE_DIR}/${PKG_NAME} $WEB_DIR/${PRO_NAME}"
}

pre_test(){
    url_test "http://${NODE_LIST}/${PRO_NAME}/index.html"
    echo "Rre add to cluster"
}

rollback_list(){
    for node in $NODE_LIST;do
        ssh $USER@$node ls -l "$WEB_DIR" && \
        ssh $USER@$node find "$CODE_DIR/" -maxdepth 1 -mtime -2|sed 1d|awk -F '/' '{print $4}'
    done
}

rollback_fun(){
    if [ -z $ROOLBACK ];then
        shell_unlock;
        echo "Please input rollback version" $$ exit;
    else
        for node in $NODE_LIST;do
        ssh $USER@$node rm -f $WEB_DIR/${PRO_NAME} && \
        ssh $USER@$node ln -s ${CODE_DIR}/$ROOLBACK $WEB_DIR/${PRO_NAME}
        done
    fi
}

main(){
    if [ -f "$LOCK_FILE" ];then
        echo "Deploy is Running" && exit;
    fi

DEPLOY_METHOD="$1"
ROOLBACK="$2"
case $DEPLOY_METHOD in
    deploy)
        shell_lock;
        code_get;
        code_tar;
        code_scp;
        pre_deploy;
        pre_test;
        shell_unlock;
        ;;
    list)
        rollback_list;
        ;;
    rollback)
        shell_lock;
        rollback_fun $ROOLBACK;
        shell_unlock;
        ;;
    *)
echo "$Usage:$0 [ deploy | list | rollback ]"
esac
}

main $1 $2