• 对于注定会优秀的人来说,他所需要的,只是时间!
  • 手懒得,必受贫穷,手勤的,必得富足----《圣经》
  • 帮助别人,成就自己。愿君在本站能真正有所收获!
  • 如果你在本站中发现任何问题,欢迎留言指正!
  • 宝剑锋从磨砺出,梅花香自苦寒来!

<三十九>Jenkins-pipeline学习笔记–pipeline结合ansible剧本进行批量的部署与回滚配置

Jenkins eryajf 12个月前 (12-14) 19987°C 已收录 2个评论
本文预计阅读时间 19 分钟

之前还在头疼批量部署与回滚的事情,最近各方面接触ansible开始多起来,于是将ansible接入到了部署流程中,从而将批量部署与回滚变得简化起来。

先看一下ansible的剧本构造:

[root@ops-eryajf-test-1 deploystatic]$tree
.
├── hosts
├── README.md
├── roles
│   ├── deploy
│   │   ├── files
│   │   │   └── keepfive.sh
│   │   └── tasks
│   │       └── main.yml
│   └── rollback
│       └── tasks
│           └── main.yml
└── site.yml

6 directories, 7 files

其中hosts文件不固定,由项目构建中灵活定义。

然后逐个查看内容:

$cat site.yml
---
- hosts: "remote"
  name: "项目部署脚本"
  remote_user: "root"

  roles:
    - deploy
    - rollback

然后看两个剧本的具体内容:

$ cat roles/deploy/files/keepfive.sh

while true;do
A=`ls . | wc -l`
B=`ls -lrX . | tail -n 1 | awk '{print $9}'`
if [ $A -gt 5 ];then rm -rf ./$B;else break;fi;done

这个脚本定义了令远程版本库保留5个构建历史的操作。

$ cat roles/deploy/tasks/main.yml

---
- name: "创建远程主机上的版本目录"
  file: path=/release/{{project}}/{{_version}} state=directory
  tags: deploy
- name: "将代码同步到远程主机版本目录"
  synchronize:
    src: /{{WORKSPACE}}/
    dest: /release/{{project}}/{{_version}}/
    delete: yes
    rsync_opts: --exclude-from=/{{WORKSPACE}}/excludefile
  tags: deploy
- name: "将项目部署到生产目录"
  file: path=/data/www/{{project}} state=link src=/release/{{project}}/{{_version}}
  tags: deploy
- name: "使版本目录保持五个版本历史"
  script: chdir=/release/{{project}} keepfive.sh
  tags: deploy
- name: "生成远程版本号"
  shell: "ls /release/{{project}} > /release/{{project}}.log"
  tags: deploy
- name: "同步版本号到本地"
  synchronize: "src=/release/{{project}}.log dest=/root/.jenkins/version/{{project}}.log mode=pull"
  tags: deploy

定义了主要的部署流程

$ cat roles/rollback/tasks/main.yml
---
- name: "将项目回滚到对应期望的构建"
  file: path=/data/www/{{project}} state=link src={{Version}}
  tags: rollback

定义了回滚的流程。

看起来就这么多,也并不算复杂,只要里边的变量,以及参数定义好即可。现在将整个剧本放在Jenkins主机的 /root/.jenkins/ansible/deploystatic目录下,以便如下脚本调用。

接下来就是核心的Jenkinsfile的定义了,目前初步定义为如下样子:

def createVersion() {
    return new Date().format('yyyyMMddHHmmss') + "_${env.BUILD_ID}"
}

pipeline {
    agent any
    environment {
        _version = createVersion()
        // 需要修改此处,定义项目名称
        project="admin-ansible"
        // 定义项目git地址
        git_url = "git@10.3.0.42:jenkins-learn/breeze-college.git"
        remote_port="22"
        remote_user="root"
        // 定义项目的webroot目录        
        project_dir="/data/www/${project}"
        //定义项目的版本目录,一般不用更改
        version_dir="/release/$project/${_version}"
    }
    options {
        timestamps()
        disableConcurrentBuilds()
        timeout(time: 10, unit: 'MINUTES')
        buildDiscarder(logRotator(numToKeepStr: '10'))
    }
    triggers{
        gitlab( triggerOnPush: true,
                triggerOnMergeRequest: true,
                branchFilterType: 'All',
                secretToken: "${env.git_token}")
    }
    parameters {
        string(name: 'branch', defaultValue: 'master', description: '请输入将要构建的代码分支')        
        choice(name: 'mode', choices: ['deploy','rollback'], description: '请选择发布或者回滚?')
        string(name: 'version_id', defaultValue: '0', description: '回滚时用,默认回滚到上一次构建,如需要回滚到更早构建,请输入对应构建ID,只支持最近五次构建的回滚,部署请忽略此参数')
        choice(name: 'remote_ip', choices: ['all','10.3.9.32','10.3.20.4'], description: '选择要发布的主机')
    }
    stages {
        stage('拉取代码') {
            steps {
                echo 'Checkout'
                script {
                    try {
                        git branch: "${branch}",url: "${git_url}"
                    }catch(err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('定义部署主机列表'){
            steps{
                script{
                    try{
                        sh '''
                        if [ $remote_ip == "all" ];then
cat > /root/.jenkins/ansible/deploystatic/hosts << EOF
[remote]
10.3.9.32 ansible_port=34222
10.3.20.4 ansible_port=34222
EOF
else
cat > /root/.jenkins/ansible/deploystatic/hosts << EOF
[remote]
$remote_ip ansible_port=34222
EOF
fi
'''
                    }catch(err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('定义忽略文件'){
            steps{
                script{
                    try {
sh '''                        
cat > excludefile << EOF
Jenkinsfile
excludefile
EOF
'''                      
                    }catch(err) {
                        echo "${err}"
                    }
                }
            }
        }
        stage('部署') {
            when {
                environment name: 'mode',value: 'deploy'
            }
            steps {
              dir("/root/.jenkins/ansible/deploystatic"){
                  script {                    
                      try {
                          sh '''
                          ansible-playbook -i ./hosts --tags "deploy" site.yml -e "project"=$project  -e "WORKSPACE"=$WORKSPACE -e "_version"=${_version}
                          '''
                      } catch(err) {
                          echo "${err}"
                      }
                  }
              }
            }
        }
        stage('回滚') {
            when {
                environment name: 'mode',value: 'rollback'
            }
            steps {
                dir("/root/.jenkins/ansible/deploystatic"){
                  script {
                      try{
                          if (params.version_id == '0'){                        
                              sh '''
                                  echo "选择回滚的版本是默认,将回滚到上次制品,回滚即将进行..."
                                  Version="/release/$project/`tail -n2 /root/.jenkins/version/${project}.log | head -n1`"
                                  ansible-playbook -i ./hosts --tags "rollback" site.yml -e "project"=${project}  -e "Version"=${Version}
                                  echo "=============="
                                  echo "项目已回滚完成!"
                                  echo "=============="
                                  '''
                          } else{
                              sh '''
                                  echo "选择回滚的版本是:${version_id},将回滚到 ${version_id} 的制品,回滚即将进行..."
                                  Version="/release/$project/`grep "_$version_id" /root/.jenkins/version/${project}.log`"
                                  ansible-playbook -i ./hosts --tags "rollback" site.yml -e "project"=${project}  -e "Version"=${Version}
                                  echo "项目回滚到 ${version_id} 完成!"
                                  '''
                          }
                      } catch(err) {
                          echo "${err}"
                      }
                    }
                }
            }
        }
    }
    post {
        success {
            dingTalk accessToken:'https://oapi.dingtalk.com/robot/send?access_token=改成自己的',
            imageUrl:'https://ae01.alicdn.com/kf/Hdfe28d2621434a1eb821ac6327b768e79.png',
            jenkinsUrl: "${env.JENKINS_URL}",
            message:'构建成功 ✅',
            notifyPeople:'李启龙'
        }
        failure {
            dingTalk accessToken:'https://oapi.dingtalk.com/robot/send?access_token=改成自己的',
            imageUrl:'https://ae01.alicdn.com/kf/Hdfe28d2621434a1eb821ac6327b768e79.png',
            jenkinsUrl: "${env.JENKINS_URL}",
            message:'构建失败 ❌',
            notifyPeople:'李启龙'
        }
    }
}

核心脚本也不算复杂,只需要在新配置项目的时候调整一些参数即可投入使用。


weinxin
扫码订阅本站,第一时间获得更新
微信扫描二维码,订阅我们网站的动态,另外不定时发送WordPress小技巧,你可以随时退订,欢迎订阅哦~

二丫讲梵 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明<三十九>Jenkins-pipeline学习笔记–pipeline结合ansible剧本进行批量的部署与回滚配置
喜欢 (1)
[如果想支持本站,可支付宝赞助]
分享 (0)
eryajf
关于作者:
学无止境,我愿意无止境学。书山有路,我愿意举身投火,淬炼成金!永远不要忘记,激情的奋进,就是美好的未来!

您必须 登录 才能发表评论!

(2)个小伙伴在吐槽
  1. eryajf
    签到成功!签到时间:2020-01-15 08:42:49,每日打卡,生活更精彩哦~
    eryajf2020-01-15 08:43 Mac OS X | Chrome 79.0.3945.117
  2. eryajf
    签到成功!签到时间:2020-02-19 13:37:00,每日打卡,生活更精彩哦~
    eryajf2020-02-19 13:39 Mac OS X | Chrome 79.0.3945.130