1、jenkins结合Sonarqube实现代码扫描
2、jenkins流水线实现代码自动部署、回滚

#=============================================================================

1 jenkins结合Sonarqube实现代码扫描

1.1 sonarqube-7.9.2 安装

#安装 JDK 11
# apt install openjdk-11-jdk

#=================================================================
#安装postgresql
# apt -y install postgresql

#修改监听地址
# sed -ri "/listen_addresses/s/#(.*=).*/\1 '*'/" /etc/postgresql/10/main/postgresql.conf

#开启远程访问
# vim /etc/postgresql/10/main/pg_hba.conf
host    all             all             0.0.0.0/0               ident

#启动数据库
# systemctl restart postgresql

#创建sonarqube数据库和用户,授权用户
# su - postgres
# psql -U postgres
postgres=# create database sonarqube;
postgres=# create user sonarqube with encrypted password 'sonarpasswd';
postgres=# grant all privileges on database sonarqube to sonarqube;
postgres=# alter database sonarqube owner to sonarqube;
postgres=# \q

#========================================================
#安装sonarqube-7.9.2
#下包

#解包
# cd /usr/local/src
# unzip sonarqube-7.9.2.zip -d /usr/local
# ln -s /usr/local/sonarqube-7.9.2 /usr/local/sonarqube

#更改配置文件
# sed -ri '/sonar.jdbc.username=/s/#(.*)/\1sonarqube/' /usr/local/sonarqube/conf/sonar.properties
# sed -ri '/sonar.jdbc.password=/s/#(.*)/\1sonarpasswd/' /usr/local/sonarqube/conf/sonar.properties
# sed -ri '/sonar.jdbc.url=jdbc:postgresql/s/#(.*)localhost(\/sonarqube).*/\110.0.0.100\2/' /usr/local/sonarqube/conf/sonar.properties

#更改系统内核参数及资源限制
# echo -e 'vm.max_map_count=262144\nfs.file-max=65536' >> /etc/sysctl.conf
# sysctl -p
# echo -e 'sonarqube - nofile 65536\nsonarqube - nproc 65536' >> /etc/security/limits.conf

#添加系统用户sonarqube,不能使用root用户启动
# useradd -r -m sonarqube

#更改权限
# chown -R sonarqube.sonarqube /usr/local/sonarqube/

#设置服务开机启动并重启sonarqube主机
# echo -e '#!/bin/bash\nsu - sonarqube -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"' >> /etc/rc.local
# [ -x /etc/rc.local ] || chmod +x /etc/rc.local
# reboot

#浏览器访问http://10.0.0.100:9000,默认用户名密码都为admin

#汉化
 web界面->Administration->Marketplace->search输入Chinese Pack->Install->安装后web界面点击重启生效
#新版本无法在线下载,非官方github下载jar包
# cd /usr/local/sonarqube/extensions/plugins
# wget https://github.com/xuhuisheng/sonar-l10n-zh/releases/download/sonar-l10n-zh-plugin-1.29/sonar-l10n-zh-plugin-1.29.jar
#重启sonarqube
 su - sonarqube -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"

1.2 jenkins 结合 sonarqube 实现代码扫描

1.2.1 jenkins 通过命令结合 sonarqube 实现代码扫描

#jenkins配置
#1.安装扫描器(sonarqube客户端),可单独部署,依赖java环境(1.8及以上)
#下包
# cd /usr/local/src
# wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.3.0.2102-linux.zip
#解包
# unzip sonar-scanner-cli-4.3.0.2102-linux.zip -d /usr/local
# ln -s /usr/local/sonar-scanner-4.3.0.2102-linux /usr/local/sonar-scanner
#更改扫描器配置文件,指定sonarqube-server地址
# sed -ri '/sonar.host.url=/s/#(.*)localhost(.*)/\110.0.0.100\2/' /usr/local/sonar-scanner/conf/sonar-scanner.properties

#2.修改job,在执行shell中直接调用sonar-scanner命令
 test-job-scan->构建->执行shell->cd /root/.jenkins/workspace/test-job-scan && /usr/local/sonar-scanner/bin/sonar-scanner
                            tar zcf web-app1.tar.gz ./*
                            scp -r web-app1.tar.gz www@10.0.0.27:/data/tardir
                            scp -r web-app1.tar.gz www@10.0.0.37:/data/tardir
                            ssh www@10.0.0.27 '/etc/init.d/tomcat stop'
                            ssh www@10.0.0.37 '/etc/init.d/tomcat stop'
                            ssh www@10.0.0.27 'rm -rf /data/web-app1/ && tar xf /data/tardir/web-app1.tar.gz -C /data/appdir/web-app1'
                            ssh www@10.0.0.37 'rm -rf /data/web-app1/ && tar xf /data/tardir/web-app1.tar.gz -C /data/appdir/web-app1'
                            ssh www@10.0.0.27 '/etc/init.d/tomcat start'
                            ssh www@10.0.0.37 '/etc/init.d/tomcat start'

#3.代码目录下新建文件sonar-project.properties
# grep ^[^#] sonar-project.properties
sonar.projectKey=test-job
sonar.projectName=test-job
sonar.projectVersion=1.0.1
sonar.sources=./
sonar.language=html
sonar.sourceEncoding=UTF-8

1.2.2 jenkins 通过插件结合 sonarqube 实现代码扫描

#jenkins配置
#1.安装扫描器(sonarqube客户端),可单独部署,依赖java环境(1.8及以上)
#下包
# cd /usr/local/src
# wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.3.0.2102-linux.zip
#解包
# unzip sonar-scanner-cli-4.3.0.2102-linux.zip -d /usr/local
# ln -s /usr/local/sonar-scanner-4.3.0.2102-linux /usr/local/sonar-scanner

#2.安装插件:SonarQube Scanner
#指定sonarqube-server地址
 系统管理->系统配置->SonarQube servers->Add SonarQube->Name:sonarqube-server
                                                      Server URL:http://10.0.0.100:9000
                                                      Server authentication token:无
#指定扫描器(sonarqube客户端)位置
 系统管理->全局工具配置->SonarQube Scanner->新增SonarQube Scanner->Name:sonar-scanner
                                                                 自动安装:取消勾选
                                                                 SONAR_RUNNER_HOME:/usr/local/sonar-scanner

#3.修改job
 test-job->构建->增加构建步骤->Execute SonarQube Scanner->Analysis properties:sonar.projectKey=test-job
                                                                             sonar.projectName=test-job
                                                                             sonar.projectVersion=1.0.1
                                                                             sonar.sources=./
                                                                             sonar.language=html
                                                                             sonar.sourceEncoding=UTF-8

2 jenkins流水线实现代码自动部署、回滚

2.1 参数化构建实现部署与回滚

#在jenkins创建job
#新建任务->名称:master-web1-deploy
          构建一个自由风格的软件项目
 master-web1-deploy->General->丢弃旧的构建->保留7天5个
                              参数化构建过程->添加参数->选项参数->名称:METHOD
                                                             选项:deploy
                                                                  rollback_last_version
                                                             描述:deploy:部署代码
                                                                  rollback_last_version:回滚代码到上一个版本
                                            添加参数->选项参数->名称:BRANCH
                                                              选项:master
                                                                   develop
                                                              描述:master:主分支
                                                                   develop:开发分支
                                                                   #METHOD为回滚时,BRANCH为占位
                                            添加参数->选项参数->名称:GROUP
                                                              选项:GROUP1
                                                                   GROUP2
                                                                   GROUP3
                                                              描述:GROUP1:灰度环境
                                                                   GROUP2:线上剩余的服务器
                                                                   GROUP3:线上所有的服务器
                     构建环境->Delete workspace before build starts
                     构建->执行shell->/bin/bash /data/scripts/master-web1-deploy.sh $METHOD $BRANCH $GROUP

#jenkins配置ssh免密
 jenkins-server->root@gitlab-server
 jenkins-server_节点配置->root@jenkins-agent
 jenkins-server->root@web-server
 jenkins-server->www@web-server
 jenkins-agent->root@web-server
 jenkins-agent->www@web-server

#jenkins部署回滚脚本目录
# mkdir -p /data/scripts
# chmod +x /data/scripts/master-web1-deploy.sh

#git项目存放目录
# mkdir -p /data/git/linux39

#web-server目录
# mkdir -p /data/tomcat/tomcat_codedir
# mkdir -p /data/tomcat/tomcat_webapps

#web-server目录授权
# chown -R www.www /data/

2.2 参数化构建脚本

# cat /data/scripts/master-web1-deploy.sh
#!/bin/bash
#===========================jenkins节点配置==============================
#jenkins构建选项参数
METHOD=$1
BRANCH=$2
GROUP_LIST=$3

#==============================WEB节点配置===============================
#灰度环境WEB节点
PRE_WEB_HOST="
10.0.0.27
"
#线上剩余WEB节点
ONLINE_WEB_HOST="
10.0.0.37
"
#线上所有WEB节点
ALL_WEB_HOST="
10.0.0.27
10.0.0.37
"
#web服务启动用户
WEB_USER="www"
#web_code归档目录
CODE_TAR_DIR="/data/tomcat/tomcat_codedir"
#web_code解压目录
CODE_UNTAR_DIR="/data/tomcat/tomcat_webapps"
#web_code解压目录软链接
LINK_CODE_UNTAR_DIR="/data/web-app1"
#web_code归档日期
DATE=$(date +%F_%H-%M-%S)

#==============================LB节点配置===============================
#LB节点
HAPROXY_HOST="
10.0.0.27
10.0.0.37
"
#haproxy listen配置块名称
HAPROXY_LISTEN_NAME="test_web"

#============================gitlab节点配置=============================
#gitlab节点
GITLAB_HOST="10.0.0.7"
#项目path
PROJECT_PATH="/data/git/linux39"
#项目name
PROJECT_NAME="web-app1"

#========================================================================

ip_list() {
    if [ ${GROUP_LIST} = "GROUP1" ]; then
        SERVER_IP="${PRE_WEB_HOST}"
        echo "SERVER_IP: ${SERVER_IP}"
        if [ ${METHOD} = "deploy" ]; then
            for HAPROXY_IP in ${HAPROXY_HOST}; do
                for PRE_WEB_IP in ${PRE_WEB_HOST}; do
                    ssh root@${HAPROXY_IP} "echo disable server ${HAPROXY_LISTEN_NAME}/${PRE_WEB_IP} | socat stdio /var/lib/haproxy/haproxy.sock"
                    echo "灰度环境 ${PRE_WEB_IP} 从负载均衡 ${HAPROXY_IP} 下线成功"
                done
            done
        fi
    elif [ ${GROUP_LIST} = "GROUP2" ]; then
        SERVER_IP="${ONLINE_WEB_HOST}"
        echo "SERVER_IP: ${SERVER_IP}"
        if [ ${METHOD} = "deploy" ]; then
            for HAPROXY_IP in ${HAPROXY_HOST}; do
                for PRE_WEB_IP in ${PRE_WEB_HOST}; do
                    ssh root@${HAPROXY_IP} "echo enable server ${HAPROXY_LISTEN_NAME}/${PRE_WEB_IP} | socat stdio /var/lib/haproxy/haproxy.sock"
                    echo "灰度环境 ${PRE_WEB_IP} 从负载均衡 ${HAPROXY_IP} 上线成功"
                done
            done
        fi
    elif [ ${GROUP_LIST} = "GROUP3" ]; then
        SERVER_IP="${ALL_WEB_HOST}"
        echo "SERVER_IP: ${SERVER_IP}"
    fi
}

clone_code() {
    cd ${PROJECT_PATH} && rm -rf ${PROJECT_NAME}
    git clone -b ${BRANCH} git@${GITLAB_HOST}:${PROJECT_PATH##*/}/${PROJECT_NAME}.git
    echo "代码clone完成"
}

scanner_code() {
    cd ${PROJECT_PATH}/${PROJECT_NAME}
    /usr/local/sonar-scanner/bin/sonar-scanner
    echo "代码扫描完成,请打开sonarqube查看扫描结果"
}

code_maven() {
    #cd ${PROJECT_PATH}/${PROJECT_NAME}
    #mvn clean package -Dmaven.test.skip=true
    echo "代码编译完成"
}

make_zip() {
    cd ${PROJECT_PATH}/${PROJECT_NAME}
    tar zcf code.tar.gz ./
    echo "代码打包完成"
}

down_node() {
    for HAPROXY_IP in ${HAPROXY_HOST}; do
        for NODE_IP in ${SERVER_IP}; do
            ssh root@${HAPROXY_IP} "echo disable server ${HAPROXY_LISTEN_NAME}/${NODE_IP} | socat stdio /var/lib/haproxy/haproxy.sock"
            echo "${NODE_IP} 从负载均衡 ${HAPROXY_IP} 下线成功"
        done
    done
}

stop_tomcat() {
    for NODE_IP in ${SERVER_IP}; do
        ssh ${WEB_USER}@${NODE_IP} "/etc/init.d/tomcat stop"
    done
}

scp_tarfile() {
    for NODE_IP in ${SERVER_IP}; do
        scp ${PROJECT_PATH}/${PROJECT_NAME}/code.tar.gz ${WEB_USER}@${NODE_IP}:${CODE_TAR_DIR}/code-${DATE}.tar.gz
        ssh ${WEB_USER}@${NODE_IP} "mkdir -p ${CODE_UNTAR_DIR}/code-${DATE} && tar xf ${CODE_TAR_DIR}/code-${DATE}.tar.gz -C ${CODE_UNTAR_DIR}/code-${DATE} && rm -f ${LINK_CODE_UNTAR_DIR} && ln -s ${CODE_UNTAR_DIR}/code-${DATE} ${LINK_CODE_UNTAR_DIR}"
        echo "代码拷备完成"
    done
}

start_tomcat() {
    for NODE_IP in ${SERVER_IP}; do
        ssh ${WEB_USER}@${NODE_IP} "/etc/init.d/tomcat start"
    done
}

web_test() {
    sleep 20
    for NODE_IP in ${SERVER_IP}; do
        HTTP_CODE=$(curl -I http://${NODE_IP}:8080/${LINK_CODE_UNTAR_DIR##*/}/index.html 2> /dev/null | awk 'NR==1{print $2}')
        if [ ${HTTP_CODE} -eq 200 ]; then
            echo "${NODE_IP} 测试通过,即将添加到负载"
            add_node
        else
            echo "${NODE_IP} 测试失败,请检查该服务器是否成功启动tomcat"
        fi
    done
}

add_node() {
    if [ ${METHOD} = "deploy" ] && [ ${GROUP_LIST} = "GROUP1" ]; then
        echo "灰度环境部署完毕,请进行代码测试!"
    else
        for HAPROXY_IP in ${HAPROXY_HOST}; do
            ssh root@${HAPROXY_IP} "echo enable server ${HAPROXY_LISTEN_NAME}/${NODE_IP} | socat stdio /var/lib/haproxy/haproxy.sock"
            echo "${NODE_IP} 从负载均衡 ${HAPROXY_IP} 上线成功"
        done
    fi
}

delete_history_version() {
    for NODE_IP in ${SERVER_IP}; do
        ssh ${WEB_USER}@${NODE_IP} "rm -f ${CODE_TAR_DIR}/code-*.tar.gz"
        NUM=$(ssh ${WEB_USER}@${NODE_IP} "/bin/ls -ldrt ${CODE_UNTAR_DIR}/code-* | wc -l")
        echo "版本数: $NUM"
        if [ ${NUM} -gt 10 ]; then
            DEL_CODE_UNTAR_DIR=$(ssh ${WEB_USER}@${NODE_IP} "/bin/ls -ldrt ${CODE_UNTAR_DIR}/code-* | awk 'NR==1{print \$NF}'")
            ssh ${WEB_USER}@${NODE_IP} "rm -rf ${DEL_CODE_UNTAR_DIR}"
            echo "${NODE_IP} 删除历史版本 ${DEL_CODE_UNTAR_DIR} 成功!"
        fi
    done
}

rollback_last_version() { 
    for NODE_IP in ${SERVER_IP}; do
        NOW_VERSION=$(ssh ${WEB_USER}@${NODE_IP} "/bin/ls -l ${LINK_CODE_UNTAR_DIR} | awk '{print \$NF}'")
        OLD_VERSION=$(ssh ${WEB_USER}@${NODE_IP} "/bin/ls -ldrt ${CODE_UNTAR_DIR}/code-* | grep -B1 ${NOW_VERSION} | awk 'NR==1{print \$NF}'")
        ssh ${WEB_USER}@${NODE_IP} "rm -f ${LINK_CODE_UNTAR_DIR} && ln -s ${OLD_VERSION} ${LINK_CODE_UNTAR_DIR}"
        echo "${NODE_IP} 从当前版本 ${NOW_VERSION} 回滚到旧版本 ${OLD_VERSION} 成功!"
    done
}

main() {
    case $1 in
        deploy)
            ip_list
            clone_code
            scanner_code
            code_maven
            make_zip
            down_node
            stop_tomcat
            scp_tarfile
            start_tomcat
            web_test
            delete_history_version
            ;;
        rollback_last_version)
            ip_list
            down_node
            stop_tomcat
            rollback_last_version
            start_tomcat
            web_test
            ;;
    esac
}

main $1 $2 $3
posted on 2023-05-18 11:01  不期而至  阅读(28)  评论(0)    收藏  举报