DevOps 运维实践经验+实例

DevOps 实践经验

以下列举了一些 DevOps 最佳实践:

  • 持续集成
  • 持续交付
  • 微服务
  • 基础设施代码
  • 监控和日志记录
  • 沟通与合作

持续集成-CI

采用持续集成时,开发人员会定期将他们的代码变更合并到一个中央存储库中,之后系统会自动运行构建和测试操作。持续集成的主要目标是更快发现并解决错误,提高软件质量,并缩短验证和发布新软件更新所需的时间。

持续交付-CD

是通过持续交付系统可以自动构建和测试代码更改,并为将其发布到生产环境做好准备。持续交付可以在构建阶段后将所有代码变更都部署到测试环境和/或生产环境中,从而实现对持续集成的扩展。当持续交付得以正确实施时,开发人员将始终能够获得一个已通过标准化测试流程的部署就绪型构建工件。

微服务

微服务架构是一种将单个应用程序构建为一系列小服务的设计方法。其中每个服务均按各自的流程运行,并利用一种轻型机制(通常为基于 HTTP 的应用程序编程接口 (API))通过一个明确定义的接口与其他服务进行通信。微服务围绕着业务能力进行构建,每项服务均限定到单个目的。您可以使用不同的框架或编程语言来编写微服务,并将其作为单个服务或一组服务进行独立部署。

基础设施代码

通过代码和软件部署技术(例如版本控制和持续集成)得以预置和管理。开发人员和系统管理员能够以编程方式与基础设施进行大规模互动,而无需手动设置和配置资源。因此,工程师可以使用基于代码的工具来连接基础设施,并且能够以处理应用程序代码的方式来处理基础设施。基础设施和服务器由代码进行定义,因此可以使用标准化模式进行快速部署、使用最新补丁和版本进行更新,或者以可重复的方式进行复制。组织可以自动跟踪、验证和重新配置由代码描述的基础设施。

配置管理

开发人员和系统管理员使用代码将操作系统和主机配置、操作性任务等自动化。代码的使用实现了配置变更的可重复性和标准化。它将开发人员和系统管理员从手动配置操作系统、系统应用程序或服务器软件的任务中解放出来。

监控和日志记录

组织对各项指标和日志进行监控,以了解应用程序和基础设施性能如何影响其产品的最终用户体验。通过对应用程序和基础设施生成的数据进行采集、分类和分析,组织可以了解变更或更新如何影响用户,同时深入了解出现问题或意外变故的根本原因。由于服务必须全天候持续可用,而且应用程序和基础设施的更新频率不断提高,因此主动监控变得日益重要。此外,创建警报或对这些数据执行实时分析也能帮助组织更主动地监控其服务。

沟通与合作

增强组织内部的沟通与合作是 DevOps 文化的一个重要方面。DevOps 工具的使用和软件交付流程的自动化能够以物理方式将开发和运行的工作流程及职责结合起来,从而建立团队之间的相互协作。在此基础上,这些团队树立了强大的文化规范,提倡信息共享和通过聊天应用程序、问题或项目追踪系统以及 Wikis 来促进沟通。这有助于加快开发人员、运营团队甚至其他团队之间的沟通,从而使组织的各个部门围绕共同的目标和项目更紧密地结合在一起。

DevOps 工具

DevOps 模式依赖于有效的工具来帮助团队快速可靠地部署并针对客户进行创新。这些工具可以自动执行手动任务,帮助团队大规模管理复杂环境,并使工程师能够控制 DevOps 实现的高速度。

DevOps 运维实践经验+实例_第1张图片

gitlab runner 流水线 CICD 实例

描述

当固定分支代码有提交触发编译,触发gitlab runner 编译代码并上传网盘或者服务器,部署到虚拟机需要手动触发。

gitlab-runner 部署及关联gitlab,可以参照下方帖子

https://segmentfault.com/a/11...

.gitlab-ci.yml

before_script:
    - echo "before script!"

variables:
    SCID: 'sc1765'
    PGID: 'sc1765_82'
    PG1_NAME: 'tkzjframe-conline-consumption'
    PG1_PORT: '8080'
    PG2_NAME: 'tkzjframe-conlineSys-consumption'
    PG2_PORT: '8081'
    PG3_NAME: 'tkzjframe-conline-core'
    PG4_NAME: 'tkzjframe-conlineSys-core'
    env1: 'pro'
    IP_801: '10.130.105.121'
    IP_802: '10.130.105.122'
    tomcat_LIST: "${PG1_NAME} ${PG2_NAME}"
    jar_LIST: "${PG3_NAME} ${PG4_NAME}"
    IP_LIST: "${IP_801} ${IP_802}"
    PASS_FILE: '/etc/rsync_user.password'
    RS800_SERVER: '10.130.159.1'
    RS500_SERVER: '10.154.140.130'

stages:
    - build
    - deploy
    - rollback
    - restart
    - logs

build_job:
    stage: build
    script:
        - pwd
        - ip a
        - pathpwd=`pwd`
        - mvn clean install -Dmaven.test.skip=true -P${env1}
        - echo $jar_LIST
        - for i in ${jar_LIST};do cd ${pathpwd}/${i}/target;ls ; APPNAME=`ls -l *.jar | grep $i | grep -v original | head -n 1 | awk -F ' ' '{print $9}'`;mv $APPNAME ${i}-${env1}.jar; done
        - ls -l
        - for k in ${jar_LIST};do cd ${pathpwd}/${k}/target ;ls ; rsync -avz ${k}-${env1}.jar rsync_user@${RS800_SERVER}::rsync_server/${SCID}/ --password-file=${PASS_FILE} ;done
        - echo $tomcat_LIST
        #- for i in ${tomcat_LIST};do cd ${pathpwd}/${i}/target;ls ; APPNAME=`ls -l *.war | grep $i | head -n 1 | awk -F ' ' '{print $9}'`;mv $APPNAME ${i}.war; done
        - ls -l
        - for k in ${tomcat_LIST};do cd ${pathpwd}/${k}/target ;ls ; rsync -avz ${k}.war rsync_user@${RS800_SERVER}::rsync_server/${SCID}/ --password-file=${PASS_FILE} ;done
    only:
        - master
    tags:
        - prod-deploy-106.76


deploy_tkzjframe-conline-consumption_tomcat1:
    stage: deploy
    script:
        - for i in ${IP_LIST};do ssh appadmin@${i} "cd /home/appadmin/tomcat && wget -O update.sh http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}/update.sh && sh +x update.sh -t tomcat -d ${PG1_PORT} -e ${env1} -s ${SCID} -p ${PG1_NAME} -a deploy"; done
        #- ssh appadmin@${IP_801} "cd /home/appadmin/tomcat && wget -O update.sh http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}/update.sh && sh -x update.sh -t tomcat -d ${PG1_PORT} -e ${env1} -s $SCID -p ${PG1_NAME} -a 'deploy'"
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76
        
        
        
deploy_tkzjframe-conlineSys-consumption_tomcat2:
    stage: deploy
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && wget -O update.sh http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}/update.sh  && sh +x update.sh -t tomcat -d ${PG2_PORT} -e ${env1} -s ${SCID} -p ${PG2_NAME} -a 'deploy'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76        

deploy_tkzjframe-conline-core_jar1:
    stage: deploy
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && wget -O update.sh http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}/update.sh && sh -x update.sh -s ${SCID} -e ${env1} -p ${PG3_NAME} -a 'deploy'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76

deploy_tkzjframe-conlineSys-core_jar2:
    stage: deploy
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && wget -O update.sh http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}/update.sh && sh +x update.sh -s ${SCID} -e ${env1} -p ${PG4_NAME} -a 'deploy'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76


restart_tkzjframe-conline-consumption_tomcat1:
    stage: restart
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat  && sh +x update.sh -d ${PG1_PORT} -t tomcat -e ${env1} -s ${SCID} -p ${PG1_NAME} -a 'restart'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76
        
        
        
restart_tkzjframe-conlineSys-consumption_tomcat2:
    stage: restart
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && sh +x update.sh -d ${PG2_PORT} -t tomcat -e ${env1} -s ${SCID} -p ${PG2_NAME} -a 'restart'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76        

restart_tkzjframe-conline-core_jar1:
    stage: restart
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && sh +x update.sh -s ${SCID} -e ${env1} -p ${PG3_NAME} -a 'restart'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76

restart_tkzjframe-conlineSys-core_jar2:
    stage: restart
    script:
        - for i in ${IP_LIST};do  ssh appadmin@${i} "cd /home/appadmin/tomcat && sh +x update.sh -s ${SCID} -e ${env1} -p ${PG4_NAME} -a 'restart'"; done
    when: manual
    only:
        - master
    tags:
        - yly-prod-10.130.105.98


rollback_tkzjframe-conline-consumption_tomcat1:
    stage: rollback
    script:
        - for i in ${IP_LIST};do  ssh ${i} "cd /home/appadmin/tomcat && sh +x update.sh -t tomcat  -d ${PG1_PORT} -e ${env1} -s ${SCID} -p ${PG1_NAME} -a 'rollback'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76
        
        
        
rollback_tkzjframe-conlineSys-consumption_tomcat2:
    stage: rollback
    script:
        - for i in ${IP_LIST};do  ssh ${i} "cd /home/appadmin/tomcat && sh +x update.sh -t tomcat  -d ${PG2_PORT} -e ${env1} -s ${SCID} -p ${PG2_NAME} -a 'rollback'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76        

rollback_tkzjframe-conline-core_jar1:
    stage: rollback
    script:
        - for i in ${IP_LIST};do ssh ${i} "cd /home/appadmin/tomcat && sh +x update.sh -s ${SCID} -e ${env1} -p ${PG3_NAME} -a 'rollback'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76

rollback_tkzjframe-conlineSys-core_jar2:
    stage: rollback
    script:
        - for i in ${IP_LIST};do ssh ${i} "cd /home/appadmin/tomcat && sh +x update.sh -s ${SCID} -e ${env1} -p ${PG4_NAME} -a 'rollback'"; done
    when: manual
    only:
        - master
    tags:
        - prod-deploy-106.76




update.sh

#!/bin/bash
. /etc/rc.d/init.d/functions
. /etc/profile

printUsage(){
    echo "usage: update.sh -t  -s  -d  -p  -e  -a "
    exit -1
}
if [ $# -eq 0 ];then
    printUsage
fi
while getopts :s:p:d:e:t:a: opts;do
    case "$opts" in
        t)
            TYPE=$OPTARG
            ;;
        s)
            SCID=$OPTARG
            ;;
        p)
            PG_NAME=$OPTARG
            ;;
        d)
            PG_PORT=$OPTARG
            ;;
        e)
            ENVe=$OPTARG
            ;;
        a)
            ACTOINS=$OPTARG
            ;;
        :)
            echo "$0 must supply an argument to option -$OPTARG!"
            printUsage
            ;;
        ?)
            echo "invalid option -$OPTARG ignored!"
            printUsage
            ;;
    esac
done
if [ -z "$SCID" ];then
    printUsage
    exit -1
fi
echo "$SCID:$PG_NAME:${ENVe}:${ACTOINS}:${PG_PORT}"
shift $(($OPTIND-1));
if [ $# -gt 0 ];then
    echo "other arguments:$@";
fi

DATEtmp=$(date +%Y%m%d%H%M)
DATE=$(date +%Y%m%d%H)
PG_PID_LINE=$(ps aux | grep java | grep $PG_NAME | wc -l)
PG_PATH="/home/appadmin/tomcat"
NginxPG_PATH="/usr/local/openresty/nginx/html"
PG_DOWN_URL="http://mirrors.tkhealthcare.com/rsync_server/data/${SCID}"


backup() {
    cd $PG_PATH
    if [ -f ${PG_PATH}/${PG_NAME}.${DATE}.bak.jar ]; then
        echo "Bakup files ${PG_NAME}.${DATE}.bak.jar has already."
    else
        mv ${PG_NAME}-${ENVe}.jar ${PG_PATH}/${PG_NAME}.${DATE}.bak.jar || echo "first time deploy-project"
        action "Backup files is ok, bk_file is : ${PG_NAME}.${DATE}.bak.jar" /bin/true
    fi
}

tomcat_backup() {
    cd ${PG_PATH}/tomcat_${PG_PORT}/webapps/
    if [ -f ${PG_NAME}.${DATE}.war.bak ]; then
        echo "Bakup files ${PG_NAME}.${DATE}.war.bak has already."
    else
        mv ${PG_NAME}.war ${PG_PATH}/tomcat_${PG_PORT}/webapps/${PG_NAME}.${DATE}.war.bak || echo "first time deploy-project"
        action "Backup files is ok, bk_file is : ${PG_NAME}.${DATE}.war.bak " /bin/true
    fi
}


frontbackup() {
    cd $NginxPG_PATH
    if [ -d ${NginxPG_PATH}/${PG_NAME}.${DATE} ]; then
        echo "Bakup files  has already."        
    else
        mv ${NginxPG_PATH}/${PG_NAME}-${ENVe} ${NginxPG_PATH}/${PG_NAME}.${DATE} || echo "first time deploy-project"
        action "Backup files is ok, bk_file is : ${PG_NAME}.${DATE}" /bin/true
    fi
}

stopproject() {
    if [ $PG_PID_LINE -eq 0 ]; then
        echo "$PG_NAME is not running ."
    else
        ps aux | grep java | grep $PG_NAME | awk -F ' ' '{print $2}' | xargs kill -9 
        #cd ${PG_PATH} && sh +x ${PG_NAME}.sh stop
        action "$PG_NAME stop ..." /bin/true
    fi
}

tomcat_stopproject() {
    echo "stop tomcat"
    #${PG_PATH}/${PG_PORT}/bin/catalina.sh stop || (ps -ef | grep 8080 | awk '{print $2}'| xargs kill -9 )
    (ps -ef | grep ${PG_PATH}/tomcat_${PG_PORT} | grep -v grep | grep -v catalina.sh |awk '{print $2}' | xargs kill -9) || echo "stop--- service is not running"
}


tomcat_startproject() {
    sh +x ${PG_PATH}/tomcat_${PG_PORT}/bin/startup.sh

}


startproject() {
    cd ${PG_PATH} && echo "nohup java -jar ${PG_NAME}-${ENVe}.jar ${ENVe} > ${PG_NAME}-${ENVe}.log &" > ${PG_NAME}_start.sh
    sh +x ${PG_NAME}_start.sh
    if [ -f ${PG_NAME}-${ENVe}.jar ]; then
        cd 
        echo "$PG_NAME starting"
    else
        action "${PG_NAME}-${ENVe}.jar is no found." /bin/false
        exit
    fi
}

checkpg() {
    sleep 15
    new_pid_line=`ps aux | grep java | grep $PG_NAME | wc -l`
    if [[ ${new_pid_line} -eq 0 ]]; then
        echo "$PG_NAME 服务[进程]启动失败."
            exit 777
        else
        echo "$PG_NAME 服务[进程]及[端口]启动成功 . --OK"
    fi
}


tomcat_checkpg() {
    sleep 15
    new_pid_line=$(netstat -tnlp | grep  $PG_PORT | wc -l)

    if [ $new_pid_line -eq 0 ]; then
        #kill -9 $new_pid
        action "$PG_NAME 服务[端口]启动失败." /bin/false
        exit 777
    fi
}


checkend() {
    sleep 30
    new_pid_line=$(ps aux | grep java | grep $PG_NAME | wc -l)
    new_pid=$(ps aux | grep java | grep $PG_NAME | awk -F ' ' '{print $2}')
    port_wc=$(netstat -tunlp | grep $new_pid | wc -l)

    if [ $port_wc -eq 0 ] && [ $new_pid_line -eq 1 ]; then
        kill -9 $new_pid
        action "$PG_NAME 服务[端口]启动失败." /bin/false
        exit 777
    fi
}

update() {
    cd $PG_PATH
    [ -f ${PG_NAME}-${ENVe}.jar ] && rm -rf ${PG_NAME}-${ENVe}.jar
    wget -O ${PG_NAME}-${ENVe}.jar ${PG_DOWN_URL}/${PG_NAME}-${ENVe}.jar
    ls -l ${PG_NAME}-${ENVe}.jar
}

tomcat_update() {
    cd $PG_PATH/tomcat_${PG_PORT}/webapps/
    [ -f ${PG_NAME}.war ] && rm -rf ${PG_NAME}.war
    rm -rf ${PG_NAME}
 pwd 
 wget -qO ${PG_NAME}.war ${PG_DOWN_URL}/${PG_NAME}.war || echo "download war failed"
    ls -l ${PG_NAME}.war
}

frontupdate() {
    cd $NginxPG_PATH
    [ -d ${PG_NAME}-${ENVe} ] && rm -rf ${PG_NAME}-${ENVe}
    wget -O ${PG_NAME}-${ENVe}.tar.gz ${PG_DOWN_URL}/${PG_NAME}-${ENVe}.tar.gz
    ls -l ${PG_NAME}-${ENVe}.tar.gz
    tar -xf ${PG_NAME}-${ENVe}.tar.gz && mv dist ${PG_NAME}-${ENVe}
}

frontrollbackupdate() {
    cd $NginxPG_PATH
    [ -d ${PG_NAME}.${DATE} ] && mv ${PG_NAME}-${ENVe} /tmp/${PG_NAME}-${ENVe}.${DATEtmp}
    cp -a ${PG_NAME}.${DATE} ${PG_NAME}-${ENVe}
}


tomcat_rollbackupdate() {
    cd ${PG_PATH}/tomcat_${PG_PORT}/webapps/
    [ -f ${PG_NAME}.${DATE}.war.bak ] || exit 777 
    rm -rf ${PG_NAME}.war ${PG_NAME}
    cp -a ${PG_NAME}.${DATE}.war.bak ${PG_NAME}.war

}


rollbackupdate() {
    cd ${PG_PATH}/
    [ -f ${PG_NAME}.${DATE}.bak.jar ] || exit 777
    mv ${PG_NAME}-${ENVe}.jar /tmp/${PG_NAME}-${ENVe}-${DATEtmp}.jar
    cp -a ${PG_NAME}.${DATE}.bak.jar ${PG_NAME}-${ENVe}.jar
}

jenkinsupdate() {
    cd $PG_PATH
    [ -f ${PG_NAME}-${ENVe}.jar ] && rm -rf ${PG_NAME}-${ENVe}.jar
    mv ../${PG_NAME}-${ENVe}.jar .
    ls -l ${PG_NAME}-${ENVe}.jar
}


echo $ACTOINS 
if [ $ACTOINS == 'restart' ]; then
    if [[ $TYPE == 'tomcat' ]]; then
        tomcat_stopproject
        tomcat_startproject
        tomcat_checkpg
    else
        stopproject
        startproject
        checkpg
    fi
elif [ $ACTOINS == 'stop' ]; then
    stopproject
    checkpg
elif [ $ACTOINS == 'jenkins-deploy' ]; then
    stopproject
    backup
    jenkinsupdate
    startproject
    checkpg
elif [ $ACTOINS == 'deploy' ]; then
    if [[ $TYPE == 'front' ]]; then
        frontbackup
        frontupdate
    elif [[ $TYPE == 'tomcat' ]]; then
        tomcat_backup
        tomcat_stopproject
        tomcat_update
        tomcat_startproject
        tomcat_checkpg    
    else
        backup
        stopproject
        update
        startproject
        checkpg    
    fi
        
elif [ $ACTOINS == 'rollback' ]; then
    if [ $TYPE == 'front' ]; then
        frontrollbackupdate
    elif [[ $TYPE == 'tomcat' ]]; then
        tomcat_stopproject
        tomcat_rollbackupdate
        tomcat_startproject
        tomcat_checkpg
    
    else
        stopproject
        rollbackupdate
        startproject
        checkpg
    fi
fi

DevOps 运维实践经验+实例_第2张图片

jenkins cicd

  • 安装ant及checkstyle,配置代码语法检查

    判断生成的report.html 是否有问题,从而判断编译是否进行
    DevOps 运维实践经验+实例_第3张图片
  • 描述

    Jenkins 通过gitlab的钩子,当固定代码分支有提交时触发编译,然后构建docker镜像上传harbor,然后手动触发部署更新,发布时Jenkins的pipeline配合着自己开发的CMDB匹配项目信息 通过shell 替换固定的yaml实现k8s 上的服务滚动更新。
  • jenkins pipeline

    #!/usr/bin/env groovy
    import groovy.util.XmlSlurper
    import groovy.lang.GroovyObjectSupport
    import groovy.util.slurpersupport.GPathResult
    import groovy.util.slurpersupport.NodeChild
    import groovy.util.Eval
    import groovy.json.JsonSlurper
    import java.lang.Integer
    import java.lang.String
    import jenkins.model.Jenkins
    
    @Library('htjfPipeline@master') _
    def dockerbuild = new org.devops.dockerbuild()
    
    
    node {
    
      stage('获取environment变量') {
          projectname = JOB_NAME.split("_")[1].toLowerCase()
          //发版所用的环境 //如果环境的变量中含有_字符DEV_service,环境就获取_下划线分隔的0数组DEV
          //jenvironment = JOB_NAME.split("_")[0].toLowerCase().indexOf("-")!=-1 ? JOB_NAME.split("_")[0].toLowerCase().split("-")[0].toLowerCase() : JOB_NAME.split("_")[0].toLowerCase()
          //echo environment_rdb
          //projectname = JOB_NAME.split("_")[0].toLowerCase().indexOf("-")!=-1 ? JOB_NAME.split("-")[1].split("_")[0]+"-"+${projectname} : ${projectname}
    
          appName = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/build_name", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          repoUrl = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/git_url", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          topicsPattern = "${projectname}"
          ifusek8s = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/if_use_k8s", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          ServiceType = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/service_type", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          toPortDev = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/node_port_dev", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          toPortQasa = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/node_port_qasa", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          toPortUata = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/node_port_uata", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          toPortProd = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/node_port_prod", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          toPortuse = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/node_port_${deployEnv}", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          build_sh = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/build_command", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          appDomain = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/${deployEnv}_domainzone", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          zone = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/${deployEnv}_zone_name", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
          domainzone = "${appDomain}.${zone}"
    
          profile = "profile-a"
          targetPort = "8080"
          harborHost = "harbor.reg"
      }
      parameters {
          gitParameter(branch: '',
                  branchFilter: 'origin/(.*)',
                  defaultValue: 'master',
                  description: '选择分支',
                  name: 'repoBranch',
                  quickFilterEnabled: true,
                  selectedValue: 'NONE',
                  sortMode: 'NONE',
                  tagFilter: '*',
                  useRepository: '.*insurance.*',
                  type: 'PT_BRANCH_TAG')
          choice(name: 'deployEnv', choices: 'dev\nqasa\nuata', description: '选择发布环境:dev开发环境,qasa测试环境,uata预发布环境')
      }
    
    }
    
    
    node {
      stage('getBranch') {
          script {
              try {
                  if ("${branch}" != "") {
                      println "----------webhook式触发-----------"
                      branchName = branch - "refs/heads"
                      env.branchName = sh(returnStdout: true, script: "echo ${branchName}|awk -F '/' '{print \$NF}'").trim()
                      println "webhook触发的分支是: " + "${branchName}"
                  }
              } catch (exc) {
              }
              if ("${params.repoBranch}" != "") {
                  println "-----------手动方式触发------------"
                  env.branchName = "${params.repoBranch}"
                  println "手动触发的分支是: " + "${branchName}"
              }
          }
      }
      stage('checkOut') {
          checkout([$class: 'GitSCM', branches: [[name: "${branchName}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanBeforeCheckout']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '4a83a964-0fa4-4e2c-a448-2d40ed71d9a7', url: "${repoUrl}"]]])
          script {
              //gitTag = sh(returnStdout: true,script: 'git describe --tags --always').trim()
              gitTagTmp = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
              env.gitTag = "${gitTagTmp}-${BUILD_NUMBER}"
          }
          println "${gitTag}"
          println "${appName}"
          println "${projectname}"
          println "${toPortProd}"
          println "${toPortDev}"
          println "${toPortQasa}"
          println "${repoUrl}"
          println "${toPortUata}"
          println "${appDomain}.${zone}"
          println "${ServiceType}"
          println "${build_sh}"
          println "${toPortuse} --in use port"
          echo "test print data"
      }
    
    
      stage('gradlewBuild') {
          stage("${deployEnv}环境targetBuild") {
              if (ServiceType == "java" || ServiceType == "tomcat") {
                  println "发布测试环境,分支为 ${branchName}"
                  sh "ls"
                  def build_sh1 = "${build_sh}".replace('bbuild_namee', "${appName}").replace('eenvv', "${deployEnv}")
                  println("${build_sh1}")
                  sh "${build_sh1}"
                  //sh "sh +x gradlew clean --no-daemon  :job-task:buildTar -x test  -PprojectEnv=qasa"
                  //build_sh1 = "http://172.16.188.27:9999/get_project_itme/${projectname}/build_command".toURL().text.replace("\"","").replace('bbuild_namee',"${appName}").replaceAll("(\r\n|\r|\n|\n\r)", "").replace('eenvv',"${deployEnv}").replace("\"","")
                  //build_sh = "${build_sh1}".replace('bbuild_namee',"${appName}").replaceAll("(\r\n|\r|\n|\n\r)", "").replace('eenvv',"${deployEnv}").replace("\"","")
                  //sh "sh +x gradlew clean --no-daemon  :job-task:buildTar -x test  -PprojectEnv=dev"
                  //def Wstart_command = ['/bin/bash','-c',"${build_sh1}"].execute(null, new File(WORKSPACE))
                  //        Wstart_command.waitFor()
                  //       println(Wstart_command.text)
              }
    
          }
      }
    
      stage("${deployEnv}环境dockerBuild") {
          if (ifusek8s == "yes" && ServiceType == "java") {
              if (deployEnv == "dev") {
                  println "开发环境dockerBuild,dockerVersion为 ${gitTag}-${branchName}"
                  dockerImage = "test_jinfu/devpipeline-${appName}"
                  dockerbuild.dockerBuild(harborHost, appName, dockerImage, gitTag, branchName)
    
              } else if (deployEnv == "qasa") {
                  println "测试环境dockerBuild,dockerVersion为 ${gitTag}-${branchName}"
                  dockerImage = "test_jinfu/qasapipeline-${appName}"
                  dockerbuild.dockerBuild(harborHost, appName, dockerImage, gitTag, branchName)
    
              } else if (deployEnv == "uata") {
                  println "预发布环境dockerBuild,dockerVersion为 ${gitTag}-${branchName}"
                  dockerImage = "pre_jinfu/uatapipeline-${appName}"
                  dockerbuild.dockerBuild(harborHost, appName, dockerImage, gitTag, branchName)
    
              }
          }
    
    
      }
      stage('deployToK8s') {
          stage("${deployEnv}部署到测试环境k8s") {
              script {
                  if (ifusek8s == "yes" && ServiceType == "java") {
                      println "部署到${deployEnv}环境k8s,分支为 ${branchName}"
                      projectName1 = "${deployEnv}pipeline-${appName}"
                      dockerTag = "${gitTag}"
                      usehost = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/${deployEnv}usehostip", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
                      println "${dockerTag}"
                      sh "~/docker/scripts/install_insurance_standard.sh -a ${projectName1} -v ${dockerTag} -f ${profile} -p ${targetPort}  -t ${toPortuse} -m ${usehost}"
                  }
              }
          }
      }
    }
    
    pipeline {
      agent any
      environment {
          appPath = "/home/nfs/insurance/${domainzone}"
          servicetype_node = sh(script: "curl -s http://172.16.188.27:9999/get_project_itme/${projectname}/service_type", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
      }
    
    
    
      stages('nodejsBuild') {
          stage('before-nodejsBuild-rm_dist') {
              when { environment name: 'servicetype_node', value: "node" }
              steps {
                  script {
                      println "发布${deployEnv}环境,删除dist"
                      sh "rm -rf dist.tar.gz"
                      sh "rm -rf dist"
                  }
              }
          }
      
          stage('nodejsBuild-for_docker') {
              when { environment name: 'servicetype_node', value: "node" }
              agent { docker 'harbor.reg/library/node:10.22.0' }
              steps {
                  script {
                      git branch: "${branchName}", credentialsId: "4a83a964-0fa4-4e2c-a448-2d40ed71d9a7", url: "${repoUrl}"
                      println "发布${deployEnv}环境,容器中编译"
                      sh "node -v && npm -v && npm config set registry http://172.16.196.111:8081/repository/npm-all/"
                      sh "${build_sh}"
                      stash includes: 'dist.tar.gz', name: 'app'
                  }
              }
          }
      
    
    
      
    
    
    
      
          stage('部署到环境Nginx') {
              when { environment name: 'servicetype_node', value: "node" }
              steps {
                  unstash 'app'
                  sh "ls"
                  echo "${deployEnv} 环境nginx"
                  script {
                      nginxIp = sh(script: "curl -s http://172.166.188.27:9999/get_project_itme/${projectname}/${deployEnv}usehostip", returnStdout: true).replaceAll("(\r\n|\r|\n|\n\r)", "").replace("\"", "")
                      println "${nginxIp}"
                      def remote = [:]
                      remote.name = "server-${nginxIp}"
                      remote.host = nginxIp
                      remote.port = 22
                      remote.allowAnyHosts = true
                      withCredentials([sshUserPrivateKey(credentialsId: "jenkins-6-88-private-key", keyFileVariable: 'id_rsa', passphraseVariable: '', usernameVariable: 'userName')]) {
                          remote.identityFile = id_rsa
                          remote.user = userName
                          // 需要注意的是,远程操作命令的作用域在withCredentials中,如果和用户名密码方式一样写在withCredentials外则会报错。
                          sshCommand remote: remote, command: "if [ ! -d ${appPath} ]; then mkdir -p ${appPath}; fi && ls ${appPath}"
                          sshPut remote: remote, from: "dist.tar.gz", into: "${appPath}"
                          sshCommand remote: remote, command: "tar xf ${appPath}/dist.tar.gz -C ${appPath}/"
                          sshRemove remote: remote, path: "${appPath}/dist.tar.gz"
                      }
                  }
              }
          }
    
      }
    }
    
    
#!/bin/bash
#author:silence_ltx
#date:20210127
#describe: for env dev,sit,uat 

while getopts :a:v:f:p:t:m: opts; do
    case $opts in
        a) a=$OPTARG ;;
        v) v=$OPTARG ;;
        f) f=$OPTARG ;;
        p) p=$OPTARG ;;
        t) t=$OPTARG ;;
        m) m=$OPTARG ;;
        ?) ;;
    esac
done


confpath=~/docker/scripts/conf
repo=harbor.reg/test_jinfu
app=$a
version=$v
profile=$f
port=$p
toport=$t
master_host=$m
yaml_host=http://192.168.66.88:8999
#zk_servers=192.168.66.102:2181,192.168.66.104:2181,192.168.66.209:2181
if [ "$port" = "" ];then
  port=8080
fi

echo start to install:$repo/$app:$version
cd $confpath
mkdir -p $app/$profile
cat insurance-deploy-template_preproduct-web_k8s1.18.yaml | sed "s|#REPOSITORY_URL#|$repo|g" | sed "s|#APP_NAME#|$app|g" | sed "s|#APP_VERSION#|$version|g" | sed "s|#PROFILE#|$profile|g"| sed "s|#port#|$port|g"
cat insurance-deploy-template_preproduct-web_k8s1.18.yaml | sed "s|#REPOSITORY_URL#|$repo|g" | sed "s|#APP_NAME#|$app|g" | sed "s|#APP_VERSION#|$version|g" | sed "s|#PROFILE#|$profile|g" | sed "s|#port#|$port|g"  > $app/$profile/deploy.yaml
cat svc-template.yaml | sed "s|#APP_NAME#|$app|g"|sed "s|#PROFILE#|$profile|g" |sed "s|#port#|$port|g" |sed "s|#toport#|$toport|g"
cat svc-template.yaml | sed "s|#APP_NAME#|$app|g"|sed "s|#PROFILE#|$profile|g" |sed "s|#port#|$port|g" |sed "s|#toport#|$toport|g" > $app/$profile/svc.yaml
ssh $master_host "kubectl delete deploy $app-$profile" 
ssh $master_host "kubectl apply -f $yaml_host/$app/$profile/deploy.yaml"
ls  $confpath/$app/$profile/svc.yaml >/dev/null 2>&1 
if [ $? -eq 0 ];then
  #ssh $master_host "kubectl delete -f $yaml_host/$app/$profile/svc.yaml"
  ssh $master_host "kubectl apply -f $yaml_host/$app/$profile/svc.yaml"
fi

DevOps 运维实践经验+实例_第4张图片

DevOps 运维实践经验+实例_第5张图片

DevOps 运维实践经验+实例_第6张图片

curl -s http://172.16.188.27:9999/get...${projectname}/${itme},可以取出数据库中项目的不同字段的信息 用于给不同项目的pipeline 文件带入项目信息

DevOps 运维实践经验+实例_第7张图片

  • python3 调用python模块
    https://segmentfault.com/a/11...
  • 报警模块

    每个服务都有一个健康检查的接口,如果未启动会有机器人报警信息

DevOps 运维实践经验+实例_第8张图片

你可能感兴趣的