Author: 本末丶
概述
在CI/CD流程中,项目的可持续迭代,版本回档都是十分重要的环节,本章重点说说怎么做回滚。我们知道,备份是很简单的,但是怎么去根据策略动态去回滚到我们备份的历史版本呢?
在这之前,我们先考虑一个问题,回滚需要哪些东西?
- 备份文件:备份的代码是基础,备份都没有怎么谈回滚?
- 备份的路径:需要获取的备份代码的所在位置
- 备份的还原点:即这是哪一次的备份,归档应该至少有一份
- 代码的所在路径:备份的代码需要还原到哪里去
- 应用的所在服务器地址:我们需要在哪台机器上做回滚的操作
- 应用名称:我们需要回滚哪个应用,一台服务器也可能有多个应用
- 还原的环境:我们所还原的应用是哪个环境的
- 应用的类型:我们回滚后可能会需要做重启服务的操作,不同类型的服务启动方式千差万别,所以还可能需要描述一个类型去区分启动方式(方便的是我们服务都写入了systemd)
- 启动账户:通过什么用户去启动应用
在之前讲spring boot/cloud的发布案例中,我们也做了一个回滚的案例,但是比较麻烦需要借助python去读取对应job的config.xml
来获取主机地址等信息,略嫌麻烦。有朋友可能已经发现,我们在上一篇(Tomcat基于Jenkins+Ansible的自动发布(1))中,我们在备份时候写入了一个备份日志,日志的内容大概如下:
# cat 2019053018 # BEGIN ANSIBLE MANAGED BLOCK { "backup_dir": "/data/deploy_release_library/web-8080-nc/2019053018", "backup_file": "/data/deploy_release_library/web-8080-nc/2019053018/web-8080-nc.zip", "backup_time": "2019053018", "env": "UAT", "project": "web-8080-nc", "project_dir": "/data/web-8080-nc", "run_user": "devops", "target": "10.18.4.50" } # END ANSIBLE MANAGED BLOC
可以看到,这个日志里有我们需要的大部分内容,接下来就好办了,只要我们通过Ansible动态读取到这个文件,就能根据这个JSON的东西来做应用回滚。
我们大概的流程如下:
相关配置
Jenkins Job的配置
这里我们使用Active choice
来读取$JENKINS_HOME/jobs
下的名称,拆分出相应的内容来拼接出环境
,分组名称
,以及应用名称
,并到/data/deploy_release_log
下动态读取出备份日志传递给Ansible.
1.获取环境名称
2.获取分组名称
3.获取应用名称
4.从归档目录里获取备份日志列表
5.获取应用名称的描述信息(可选)
6.Ansible Plugin配置
点开高级,附加参数里,添加指向到备份日志的extra vars
(通过拼接变量名)
Ansible Role的配置
Role结构
playbooks └──manager-rollback.yml # 入口文件 roles └──manager-rollback ├── defaults │ └── main.yml # 默认变量 ├── README.md └── tasks ├── other-server.yml # 其他服务的启动方式(之前说的,可能有些服务启动方式一样) ├── general.yml # 一般程序的启动(我这里是指注册到systemd里服务) └── main.yml # 主task文件
1.manager-rollback.yml
--- # target通过备份日志里的json获取 - hosts: "{{ target }}" # 直接root去操作 remote_user: root roles: - manager-rollbac
2.defaults/main.yml
--- # defaults file for rollback # 备份日志(那个json)里如果指定了app_type,否则全部当一般应用 APP_TYPE: "{{ app_type | default('general') }}"
3.tasks/main.yml
--- # 有些系统可能没装解压软件 - name: Install unzip yum: name=unzip # 将备份文件解压到项目路径下覆盖 - name: Rollback {{ project }} to {{ backup_time }} unarchive: src: "{{ backup_file }}" dest: "{{ project_dir }}" owner: "{{ run_user }}" group: "{{ run_user }}" remote_src: yes # 判断应用类型,默认调用general - include: "{{ APP_TYPE }}.yml"
4.tasks/general.yml
--- # 注册到systemd的一般服务启动 # CentOS7通过systemd启动服务 - name: 7 Restart service systemd: name={{ project }} state=restarted when: ansible_distribution_major_version|int >= 7 # CentOS6通过service启动服务 - name: 6 Restart service service: name={{ project }} pattern=/etc/init.d/{{ project }} state=restarted sleep=3 when: ansible_distribution_major_version|int < 7 become_user: "{{ run_user }}" become: yes
5.tasks/other-server.yml(这里是个示例,可以自己拓展)
--- # 这里是一个示例,备份日志里还写入了该程序的启动脚本在哪 # manager_script也是插入到了备份日志里。 - name: Restart GciTask shell: bash {{ manager_script }} -t all -a restart args: chdir: "{{ manager_script | dirname}}" become_user: "{{ run_user }}" become: yes
回滚演示
首先,我们进入应用路径/data/web-8080-nc/nc下,修改一个文件,我们插入了一段注释
接下来,我们回滚到昨天的版本(动图,PDF不会动,要动的自己看blog)。
我们看下文件是否还原
可以看到,文件正确的还原了!而且服务也正常的在启动中
说在最后的话
其实我们不管是tomcat还是其他类型的应用,备份回滚策略都大同小异,另外我们在填充备份日志的时候可以添加任何自己需要的字段,然后传递给Ansible做各种各样的判断和后续操作,十分的方便!本章也到此结束,如果有什么需要改进或者建议,欢迎留言。
没有帐号? 立即注册