回滚方案:
一般回滚方案:
• 重新走一步流程发布上一次版本代码
• 部署之前备份程序文件
回滚流程设计:

回滚实现步骤:
安装Extended Choice Parameter插件并配置生成对应的语法



生成连接Jenkins服务器用户名和密码语法


此处是使用下面参数生成的凭据语法(避免脚本中用户名密码的敏感信息泄露)


1、在原有Pipeline脚本中增加生成“备份版本记录文件”脚本
备份的文件名格式最好是统一规范的,例如:项目名-文件名-日期-构建编号 项目名:当前创建的项目 文件名:部署war包的名称(ROOT.war) 日期:date +%F 构建编号:jenkins自带的变量(build_number)
ls /data/backup |awk '{print $0}' ls /data/backup |awk '{print $0","}' ls /data/backup |awk '{printf $0","}' ls /data/backup |awk 'BEGIN{printf "abc="}{printf $0","}'
ls /data/backup |awk 'BEGIN{printf "abc="}{printf \$0","}' > /tmp/backup_version.txt ls /data/backup |sort -t - -k 6 -nr |head -n 3|awk 'BEGIN{printf "abc="}{printf \$0","}' > /tmp/backup_version.txt
sshpass -p"123.com" scp /tmp/backup_version.tx t root@x.x.x.x:/opt/jenkins_home/
|
新建项目–>配置–>最下面配置流水线脚本进行发布项目
pipeline { agent { label "task1" } environment { git_address = "http://gitlab.ctnrs.com/my-group/ansible.git" git_password = "4cfc8d8f-489b-4c29-9f10-4a1b265e0cb3" ansible_ssh_auth = "a14ad8a7-5ad6-43de-bac6-221000c8015c" } parameters { gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '请选择你要发布的分支', name: 'branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH' choice choices: ['webservers1', 'webservers2', 'webservers3'], description: '''灰度发布策略,分批次部署 webservers1 192.168.0.2 192.168.0.5 webservers2 192.168.0.2 webservers3 192.168.0.5''', name: 'ENV' } triggers { pollSCM '*/1 * * * * ' } stages { stage('拉取代码') { steps { checkout([$class: 'GitSCM', branches: [[name: "${params.branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "$git_password", url: "$git_address"]]]) } } stage('编译构建') { steps { sh "/usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true" } } stage('拷贝构建文件到远程主机并部署') { steps { // 读取连接Jenkins服务器用户名和密码 withCredentials([usernamePassword(credentialsId: 'ad3b7fb3-897e-4dc3-a7cf-0975ffc7b4ec', passwordVariable: 'jenkinspass', usernameVariable: 'jenkinsroot')]) { // =========================================== sh """ ###################### 主机清单文件 ############################ cat > /opt/jenkins/.hosts << EOF [webservers1] 192.168.0.2 192.168.0.5 [webservers2] 192.168.0.2 [webservers3] 192.168.0.5 EOF ###################### Playbook文件 ############################ cat > /opt/jenkins/.playbook.yaml << "EOF" - hosts: $ENV # Jenkins参数化变量 gather_facts: no vars: # 定义playbook变量,下面{{}}引用这里的变量 workspace: $WORKSPACE # WORKSPACE和BUILD_NUMBER引用Jenkins变量 build_number: $BUILD_NUMBER tomcat_dir: "/usr/local/tomcat" # 自定义变量 backup_dir: "/data/backup" backup_filename: "demo-ROOT-\$(date +%F)-{{ build_number }}.war" # 格式:项目名-文件名-日期-构建编号 jenkins_ip: "192.168.0.4" username: $jenkinsroot password: $jenkinspass tasks: - name: 推送部署包到远程服务器 copy: src="{{ item }}" dest={{ tomcat_dir }}/webapps with_fileglob: - "{{ workspace }}/target/*.war" - name: 部署新程序并重启Tomcat shell: | cd {{ tomcat_dir }}/webapps mv ROOT.war {{ backup_dir }}/{{ backup_filename }} mv *.war ROOT.war pid=\$(ps -ef |grep {{ tomcat_dir }} |egrep -v 'grep' |awk '{print \$2}') [ -n "\$pid" ] && kill -9 \$pid export JAVA_HOME=/usr/local/jdk nohup {{ tomcat_dir }}/bin/startup.sh ls /data/backup |sort -t - -k 6 -nr |head -n 3|awk 'BEGIN{printf "abc="}{printf \$0","}' > /tmp/backup_version.txt sshpass -p{{ password }} scp /tmp/backup_version.txt {{ username }}@{{ jenkins_ip }}:/opt/jenkins_home/ EOF """ // =========================================== } ansiblePlaybook( playbook: '/opt/jenkins/.playbook.yaml', inventory: '/opt/jenkins/.hosts', credentialsId: "${ansible_ssh_auth}" ) } } } }
|
2、在Jenkins创建一个独立的回滚项目
新建项目–>配置–>最下面配置流水线脚本(回滚项目中部署脚本只做根据选择的备份版本名称重新部署)
pipeline { agent { label "task1" } environment { ansible_ssh_auth = "a14ad8a7-5ad6-43de-bac6-221000c8015c" } parameters { extendedChoice description: '请选择你要回滚的版本', multiSelectDelimiter: ',', name: 'RollbackVersion', propertyFile: '/var/jenkins_home/backup_version.txt', propertyKey: 'abc', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_SINGLE_SELECT', visibleItemCount: 5 choice choices: ['webservers1', 'webservers2', 'webservers3'], description: '''灰度发布策略,分批次部署 webservers1 192.168.0.2 192.168.0.5 webservers2 192.168.0.2 webservers3 192.168.0.5''', name: 'ENV' } stages { stage('拷贝构建文件到远程主机并部署') { steps { // =========================================== sh """ ###################### 主机清单文件 ############################ cat > /opt/jenkins/.hosts << EOF [webservers1] 192.168.0.2 192.168.0.5 [webservers2] 192.168.0.2 [webservers3] 192.168.0.5 EOF ###################### Playbook文件 ############################ cat > /opt/jenkins/.playbook.yaml << "EOF" - hosts: $ENV # Jenkins参数化变量 gather_facts: no vars: # 定义playbook变量,下面{{}}引用这里的变量 workspace: $WORKSPACE # WORKSPACE和BUILD_NUMBER引用Jenkins变量 tomcat_dir: "/usr/local/tomcat" # 自定义变量 backup_dir: "/data/backup" backup_filename: $RollbackVersion tasks: - name: 恢复备份程序并重启tomcat # 脚本中\$必须转义,否则会认为是Jenkins变量 shell: | cd {{ tomcat_dir }}/webapps [ ! -d {{ backup_dir }} ] && mkdir {{ backup_dir }} -p [ ! -d /tmp/new_root ] && mkdir /tmp/new_root mv ROOT.war /tmp/new_root mv {{ backup_dir }}/{{ backup_filename }} ROOT.war pid=\$(ps -ef |grep {{ tomcat_dir }} |egrep -v 'grep' |awk '{print \$2}') [ -n "\$pid" ] && kill -9 \$pid export JAVA_HOME=/usr/local/jdk nohup {{ tomcat_dir }}/bin/startup.sh EOF """ // =========================================== ansiblePlaybook( playbook: '/opt/jenkins/.playbook.yaml', inventory: '/opt/jenkins/.hosts', credentialsId: "${ansible_ssh_auth}" ) } } } }
|
最终实现如下:

3.验证结果:
模拟场景:公司一套软件要发布上线,代码测试后发布开始构建部署,此次代码版本稳定运行。后期更新了新的功能,要开始第二次的构建部署(代码更新),发布上线后出现了严重的bug,需要回退到上一个版本,那么此时进入回滚项目,选择要回滚的代码版本即可回滚到上一个版本,保障业务能够正常运行。
①发布一次构建代码(查看页面功能)—>②修改代码—>再次构建代码(查看页面功能出现了严重bug)—>③开始回滚—>选择要回滚的上一次的代码版本—>开始构建