美文网首页
5、持续集成-jenkins

5、持续集成-jenkins

作者: 六弦极品 | 来源:发表于2019-04-26 09:51 被阅读0次

一:通过jenkins调用shell脚本完成从Gitlab服务器获取代码、打包、部署到web服务器、将web服务器从负载均衡器删除、解压、复制配置文件、创建软连接、测试每一台web服务器、将web服务器添加至负载均衡、回滚到任意指定版本、一键回滚到上一版本等功能,脚本放在user_00用户家目录下的tools/deploy/sbin下,并使用user_00用户执行,每个web服务器也都使用user_00用户运行web服务,且gid和uid相同,web目录和权限都一致,以便达到标准化可以带来更安全的生产环境和更高的效率:

1.1 在jenkins项目配置中调用shell脚本与环境准备:
1.1.1 环境准备:
部署服务器(发布机):

# sudo su - user_00
$ cd /home/user_00/tools/deploy/
$ mkdir data sbin tmp tar conf/web-django/base -p

在发布机上对相应对应用做发布配置:

$ cat /home/user_00/tools/deploy/conf/web-django/deploy.cnf
DEV_LIST=""        # 开发环境
PRE_LIST="" # 预发布环境
PRO_LIST="192.168.56.3 192.168.56.4" # 线上环境

GIT_URL='git@192.168.56.3:liuzhousheng/web-django.git'
WEB_DIR='/data/apps'
PORT='22'
$ cat /home/user_00/tools/deploy/conf/web-django/exclude.cnf
.git

web应用节点:

# mkdir /data/apps && chown user_00.users /data/apps
# sudo su - user_00
$ cd /data/apps/ && mkdir release/web-django -p
$ ln -sv /data/apps/release/web-django/web-django_39b295f1_20190426-18-52-36 /data/apps/web-django   # 初始化打一个死链接

将发布机user_00的公钥放到多台web服务器user_00 家目录下的文件 .ssh/authorized_keys

$ cat /home/user_00/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHSkr5zTWobDcIUM6mFKDqFK6jO0CBlzD5qaOazO6WeKrJIlHtIaFZW4yAezWp9Cc8ZT0FCUaXHaOk39RKxIJGAuyi8kOpYM07/3NisRhukpu2HTTQKhAM3UpyQAjd+2w+Sw6Dl99YNeq0QVGn+2BGDCjaip4A6jNVpG601q3ztMr/ujtTXT0ulZcoy4xgtULpN66/Fu3YKUO1KuK6a6gxfdGyB9VIbrzS/ftdtsLvBD0TPisLbxN//ydwtvtJ1c1hqJtwob97F5v1Hu7rMEBjTVk3WwJ65eE0cey/L/0oPSePQHXJJI9geSwcHZdkWu1Di035SVa7E402ia6FgJYJ user_00@192.168.56.5

1.1.2 user_00 用户家目录中的脚本内容:

$ cat code_deploy.sh
#/bin/bash

BASE_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd )
.  $BASE_DIR/conf/$2/deploy.cnf

exclude_cfg=$BASE_DIR/conf/$2/exclude.cnf
APP_NAME=$2    # 项目名称的函数
#发布时间
DEPLOY_TIME=$(date "+%Y%m%d-%H-%M-%S")

# code env 代码变量
CODE_DIR="/home/user_00/tools/deploy/data"    # 从版本管理系统更新的代码目录
CONFIG_DIR="/home/user_00/tools/deploy/conf"    # 保存不同项目的配置文件,一个目录里面就是一个项目的一个配置文件或多个配置文件
TMP_DIR="/home/user_00/tools/deploy/tmp"            # 临时目录
TAR_DIR="/home/user_00/tools/deploy/tar"            # 打包目录
LOCK_FILE="/tmp/${APP_NAME}-deploy.lock" # 锁文件路径

# shell env 脚本位置等变量
SHELL_NAME="code_deploy.sh"    # 脚本名称
SHELL_DIR="/home/user_00/tools/deploy/sbin"  # 脚本路径
SHELL_LOG="/home/user_00/tools/deploy/logs/${APP_NAME}-deploy.log" # 脚本执行日志文件路径

usage(){ # 使用帮助函数
    echo $"Usage: $0 deploy app_name | rollback app_name version"
}

writelog(){ # 写入日志的函数
    LOGINFO=$1 # 将参数作为日志输入
    echo "${DEPLOY_TIME}: ${SEHLL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}

# 锁函数
shell_lock(){
    touch ${LOCK_FILE}
}

# 解锁函数
shell_unlock(){
    rm -f ${LOCK_FILE}
}

# 获取代码的函数
code_get(){
    echo "code_get"
    writelog code_get
    if [ -d "$CODE_DIR/$APP_NAME" ];then
        cd ${CODE_DIR}/${APP_NAME} && git pull #从git服务器更新代码
    else
        cd $CODE_DIR && git clone $GIT_URL
    fi
    /bin/cp -rf ${CODE_DIR}/${APP_NAME} ${TMP_DIR}/${APP_NAME} # 临时保存代码并重命名,包名为时间+版本号,准备复制到web服务器
    cd ${CODE_DIR}/${APP_NAME}
    API_VERL=$(git show |grep commit |cut -d ' ' -f2)
    API_VER=$(echo ${API_VERL:0:8})        # 版本号
}

code_build(){ # 代码编译函数
    echo code_build
}

code_config(){ # 配置文件函数
    writelog "code_config"
    rsync -arP ${CONFIG_DIR}/${APP_NAME}/base/ ${TMP_DIR}/${APP_NAME} # 将配置文件放在本机保存配置文件的临时目录,用于暂时保存代码项目
    PKG_NAME="${APP_NAME}"_"$API_VER"_"${DEPLOY_TIME}"    # 定义代码目录名称
    cd ${TMP_DIR} && mv ${APP_NAME} ${PKG_NAME}    # 重命名代码文件为web-django_123id838-20170629-11-19-10格式
}

code_tar(){    # 对代码打包函数
    writelog code_tar
    #cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude=".git" && rm -rf ${PKG_NAME} # 将目录打包成压缩文件,便于网络传输
    cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude-from=$exclude_cfg && rm -rf ${PKG_NAME} # 将目录打包成压缩文件,便于网络传输
    writelog "${PKG_NAME}.tar.gz packaged success"    # 记录打包成功的日志
}

code_rsync(){ # 代码压缩包同步到客户端的函数
    writelog  "code_scp"
    for node in $PRO_LIST;do # 循环服务器节点列表
        rsync -razP ${TMP_DIR}/${PKG_NAME}.tar.gz $node:${WEB_DIR}/release/${APP_NAME} # 将压缩后的代码包复制到web服务器的/opt/webroot
    done
    rm -f ${TMP_DIR}/${PKG_NAME}.tar.gz
}

cluster_node_add(){ #将web服务器添加至前端负载
    echo cluster_node_add
}

cluster_node_remove(){ # 将web服务器从集群移除函数(正在部署的时候应该不处理业务)
    writelog "cluster_node_remove"
}

pro_deploy(){ # 代码解压部署函数
    writelog "pro_code_deploy"
    for node in ${PRO_LIST};do # 循环生产服务器节点列表
        cluster_node_remove $node
        echo "pro, cluster_node_remove $node"
        ssh -p ${PORT} ${node} "cd ${WEB_DIR}/release/${APP_NAME} && tar zxf ${PKG_NAME}.tar.gz && rm -f ${PKG_NAME}.tar.gz" # 分别到各web服务器节点执行压缩包解压命令
        ssh -p ${PORT} ${node} "rm -f ${WEB_DIR}/${APP_NAME} && ln -s ${WEB_DIR}/release/${APP_NAME}/${PKG_NAME} ${WEB_DIR}/${APP_NAME}" # 整个自动化的核心,创建软连接
    done
}

pro_test(){ # 生产主机测试函数
    for node in ${PRO_LIST};do # 循环生产主机列表
        #curl -s --head http://${node}:9999/index.html | grep "200 OK" #测试web界面访问
        curl -s --head http://www.baidu.com/index.html |grep "200 OK"
        if [ $? -eq 0 ];then  #如果访问成功
            writelog " ${node} Web Test OK!" #记录日志
            echo "pro_test,${node} Web Test OK!"
            cluster_node_add
            writelog " ${node} add to cluster OK!" #记录将服务器 添加至集群的日志
        else #如果访问失败
            writelog "${node} test no OK" #记录日志
            echo "${node} test no OK"
            shell_unlock # 调用删除锁文件函数
            break # 结束部署
        fi
    done
}

rollback_fun(){
    for node in $PRO_LIST;do # 循环服务器节点列表
        # 注意一定要加"号,否则无法在远程执行命令
        ssh -p ${PORT} $node "ls -l ${WEB_DIR}/release/${APP_NAME}/$1 && rm -f ${WEB_DIR}/${APP_NAME} && ln -s ${WEB_DIR}/release/${APP_NAME}/$1 ${WEB_DIR}/${APP_NAME}" # 立即回滚到指定的版本,$1即指定的版本参数
        echo "${node} rollback success!"
        done
}

rollback(){ # 代码回滚主函数
    if [ -z $1 ];then
        shell_unlock # 删除锁文件
        echo "Please input rollback version" && exit 3;
    fi
    case $1 in # 把第二个参数做当自己的第一个参数
        list)
            ls -l ${WEB_DIR}/release/${APP_NAME}/*.tar.gz
            ;;
        *)
            rollback_fun $1
    esac

}

main(){
    if [ -f $LOCK_FILE ] ;then # 先判断锁文件在不在,如果有锁文件直接退出
        echo "Deploy is running" && exit 10
    fi
    DEPLOY_METHOD=$1 # 避免出错误将脚本的第一个参数作为变量
    ROLLBACK_VER=$3
    case $DEPLOY_METHOD in
        deploy) # 如果第一个参数是deploy就执行以下操作
            shell_lock # 执行部署之前创建锁。如果同时有其他人执行则提示锁文件存在
            code_get # 获取代码
            code_build # 如果要编译执行编译函数
            code_config # cp配置文件
            code_tar    # 打包
            code_rsync  # scp到服务器
            pro_deploy # 生产环境部署
            pro_test   # 生产环境测试
            shell_unlock # 执行完成后删除锁文件
            ;;
        rollback) # 如果第一个参数是rollback就执行以下操作
            shell_lock # 回滚之前也是先创建锁文件
            rollback $ROLLBACK_VER
            shell_unlock # 执行完成删除锁文件
            ;;
        *)
            usage;
    esac
}
main $1 $2 $3

1.1.3 jenkins-项目-配置:

sudo ssh user_00@192.168.56.5 "~/tools/deploy/sbin/code_deploy.sh deploy web-django" ##正常发版 

构建配置 立即构建

web服务器192.168.56.4:

[root@localhost web-django]# ll /data/apps/release/web-django/
总用量 0
drwxr-xr-x. 3 user_00 users 70 4月  26 18:58 web-django_39b295f1_20190427-14-56-05
drwxr-xr-x. 3 user_00 users 70 4月  26 18:58 web-django_39b295f1_20190427-15-01-54
[root@localhost web-django]# ll /data/apps/
总用量 0
drwxr-xr-x. 3 user_00 users 24 4月  26 12:26 release
lrwxrwxrwx. 1 user_00 users 67 4月  27 15:01 web-django -> /data/apps/release/web-django/web-django_39b295f1_20190427-15-01-54

回滚到web-django_39b295f1_20190427-14-56-05 这个版本:

sudo ssh user_00@192.168.56.5 "~/tools/deploy/sbin/code_deploy.sh rollback web-django web-django_39b295f1_20190427-14-56-05" ##回滚到指定的版本
回滚配置 回滚构建

web节点软链指向回滚版本

[root@localhost web-django]# ll /data/apps/
总用量 0
drwxr-xr-x. 3 user_00 users 24 4月  26 12:26 release
lrwxrwxrwx. 1 user_00 users 67 4月  27 15:10 web-django -> /data/apps/release/web-django/web-django_39b295f1_20190427-14-56-05

相关文章

网友评论

      本文标题:5、持续集成-jenkins

      本文链接:https://www.haomeiwen.com/subject/cxnxnqtx.html