热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于Ansible和Devops的一键测试环境部署实践

转载本文需注明出处:微信公众号EAWorld,违者必究。随着网络架构的不断升级和业务的复杂化,对产品多环境支持的要求越来越高。产品支持的数

转载本文需注明出处:微信公众号EAWorld,违者必究。

随着网络架构的不断升级和业务的复杂化,对产品多环境支持的要求越来越高。产品支持的数据库、应用服务器、中间件、操作系统等的多样化,使测试环境的组合越来越多,导致测试环境的部署难度不断增加。

如何选择一个合适的工具,实现多样化环境部署的同时保证部署操作的易用性。下面分享一下我们基于Ansible和Devops实现的一键式测试环境部署的过程。

Ansible



Ansible是一款自动化运维工具,基于Python开发,集合了众多运维工具(Saltstack、puppet、chef等)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作,具有丰富的内置模块,同时也支持自定义模块开发。以下是对Ansible和其他常见运维工具的对比:

而ansible在自动化运维过程时具有如下优势:

1. 基于模块运行,有丰富的内置模块支持

2. 基于Python开发,方便二次开发

3. 基于SSH交互,被管机器不要安装 Agent

4. 无Server,在任何安装ansible的机器上执行命令即可

5. 脚本用YAML编写,易读和易维护


正因为ansible操作简单、易上手,功能丰富,已被很多公司纳入使用。

Ansible主要有ad-hoc和playbook两种执行方式,Ansible Ad-hoc是一次性命令,适合执行单个、简单的任务,一次只调用一个模块执行,如执行:

ansible  -m yum -a “name=net-toolsstate=present“ 

(左右滑动查看全部代码)

即可完成通过yum方式在远程机器上安装net-tools;执行

ansible -m service -a “name=httpd state=started“

(左右滑动查看全部代码)

可以在远程服务其上启动httpd服务,若服务已启动,在远程机器上不会发生任何改变。

AnsiblePlaybook模式使用YAML格式定义操作,通过模块编排完成复杂的操作,以角色(role)为执行单位,一个role包含多个文件目录,不同目录放置不同作用的文件,一个简单的playbook脚本目录结构如下所示:

├── group_vars
│ └── all.yml
├── install.yml
├── linux.inventory
├── roles
│ └── test
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── update.sh
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── server.xml
│ └── vars
│ └── main.yml
└── windows.inventor

(左右滑动查看全部代码)

每个目录下放置文件的具体作用为:

files:存放copy模块或script模块调用的文件
templates:存放jinja2模板
tasks:目录包含一个main.yml文件,该角色执行入口
handlers: 角色中触发条件时执行的动作
vars: 定义此角色用到的变量
defaults:为当前角色设定默认变量

Playbook模式在安装有ansible 的机器上执行如下命令即可:

ansible-playbook -ilinux.inventory install.yml --extra-vars “host=192.168.1.1”

(左右滑动查看全部代码)

-i: 用来指定具体的host inventory文件,默认使用/etc/ansible/hosts文件里面定义的主机或分组

 --extra-vars: 通过命令行方式指定部署用到的参数,通过命令行指定的参数优先级高于脚本中定义的参数

下面介绍几个ansible中常用的一些模块。

1

set_fact

set_fact模块主要用来在部署过程中修改和新增变量,设置的变量可以在后面的role中使用。如依赖mysql数据库时,可通过set_fact 设置db_driver_class、db_driver_jar、db_url等参数,避免在执行时传入复杂的参数,减少执行时参数定义的复杂度,如下所示通过set_fact设置mysql数据库的连接信息

- name: set driver versionwhen: db_version|string == '5.7'set_fact:db_driver_name: mysql-connector-java-5.1.32.jardb_platform: "org.hibernate.dialect.MySQLDialect"- name: Set ipv4 db_url and driver namewhen: use_net4|boolset_fact:db_url: "jdbc:mysql://{{ db_ip }}:{{ db_port }}/{{ db_name }}"db_driver: "com.mysql.jdbc.Driver"

(左右滑动查看全部代码)

2

with_items

with_items模块用来执行循环,可与include_vars配合完成配置文件修改等操作。

- include_vars: "common_vars.yml"- name: modify install.propertieslineinfile:path: "{{ user_dir }}/config/install.properties"regexp: "{{ re_item.original }}"line: "{{ re_item.replace }}"with_items: "{{ deploy_var }}"loop_control:loop_var: re_item

(左右滑动查看全部代码)

3

include_tasks\include_role

include_tasks\include_role模块主要用来引用其他task或role文件,实现功能复用和动态加载。在实际部署中可将不同类型的关联操作定义在相同的task或role中,执行中根据参数动态加载,如windows和linux下模块定义不一样,将windows和linux下的操作定义在不同的task中,根据执行时传入的os_type去执行不同的操作。

- include_tasks: "common/{{os_type}}/main.yml"- include_tasks: "dbinfo/set-{{db_type|lower}}.yml"- include_role: "name={{product_type}}"

(左右滑动查看全部代码)

4

template

template模块主要将本地文件推送到远端,并将文件中的变量定义替换为运行时变量值,实现可变的配置。在实际部署中可以通过template修改tomcat的默认监听端口:

- name: create dir file:state: directorydest: "{{ app_server_home }}/conf"- name: change tomcat server porttemplate:src: "tomcat/server-{{ app_server_version }}.xml"dest: "{{ app_server_home }}/conf/server.xml"

(左右滑动查看全部代码)

5

wait_for

wait_for模块主要用来判断端口监听、文件内容等条件是否满足条件。在实际部署中可以通过端口去判断服务是否启动,或者通过文件中是否包含指定内容去判断是否继续下一步操作。

- name: wait server startwhen: have_app_server_portwait_for: state: startedport: "{{app_server_port}}"timeout: 60- name: wait install successwait_for: path: "{{ user_dir }}/logs/install.log"search_regex: "esb.* installed successfully"

(左右滑动查看全部代码)

工作量,增加脚本的复用性,我们将产品的部署过程分为了以下几个步骤:

1

设置参数

为了保证整个部署脚本的扩展性和对不同产品、不同版本的支持,在部署过程中会有很多值需要参数化。部署过程中用到的很多参数,有些是不易理解和记忆的,如jdbc url、drive class等,每次执行脚本的时候需要再去查;还有一些参数对某个产品某个版本是固定的,可以根据一两个值确定下来。设置参数这一步主要是为了解决这个问题,预定义好部署过程中的诸多参数,通过参数控制部署流程和操作。

- include_vars: "vars/{{os_type}}/main.yml"- include_vars: "vars/{{ product_type }}/main.yml"- when: install_var_file == ''include_vars: "vars/{{ product_type }}/var-{{ product_version| string|lower }}.yml"- when: install_var_file != ''include_vars: "{{ install_var_file }}"- include_tasks: ./common/silentinstall.yml- include_tasks: "{{ product_type }}/setfactor.yml"- include_tasks: "dbinfo/set-{{ db_type | lower }}.yml"- include_tasks: "dbinfo/set-url.yml"

(左右滑动查看全部代码)

2

虚拟机设置

在测试过程中,为了保证测试环境的有效性,每次部署的基础依赖环境是要干净的。但有些基础环境的准备如有些应用服务器或中间件等的安装是比较耗时的。为了保证干净的基础依赖环境并尽量简化部署过程的前提下,我们利用了虚拟机的快照功能。对于一些复杂的依赖环境,提前安装好并生成虚拟机快照,在部署过程中通过恢复快照的方式来简化部署过程。

- include_vars: defaults/main.yml- name: manage vm snapshotvmware_guest_snapshot:hostname: "{{ vsphere_hostname }}"username: "{{ vsphere_username }}"password: "{{ vsphere_password }}"datacenter: "{{ vsphere_datacenter }}"validate_certs: "{{ validate_certs }}"name: "{{ vm_name }}"folder: "{{ vm_folder }}"state: "revert"snapshot_name: "{{ vm_snapshot_name }}"delegate_to: localhostregister: revertstate

(左右滑动查看全部代码)

3

清理环境

为了保证产品安装目录未被占用,产品监听的端口处于空闲状态,需要对目录和端口进行清理操作。在执行清理环境过程中,对与有停止、卸载脚本的产品,调用脚本进行清理;没有停止、卸载服务的使用系统命令进行清理。对于不存在的目录进行删除操作时的错误忽略。

- name: copy killport filewhen: have_porttemplate:src: killport.shdest: "{{ user_dir }}//killport.sh"mode: 0755- name: close {{ deploy_type }} applicationwhen: have_portshell: bash killport.shargs:chdir: "{{ user_dir }}/"ignore_errors: yes- name: close {{ deploy_type }} applicationwhen: not have_portshell: bash {{ stopFile }} args:chdir: "{{ user_dir }}/"ignore_errors: yes- name: close {{ deploy_type }} applicationwhen: not have_portshell: ps -ef |grep "{{ user_dir }}/{{ deploy_type }}" |grep -v grep |awk '{print $2}' |xargs kill -9 args:chdir: "{{ user_dir }}/"ignore_errors: yes

(左右滑动查看全部代码)

4

部署依赖

部署依赖主要进行产品部署前的准备工作,包括JDK的安装、tomcat 端口配置等。通过参数定义,进行指定版本JDK,应用服务器等依赖的安装,并可对不同产品进行自定义配置。对于JDK安装、应用服务配置等操作都封装为单独的role以便复用。

- include_role: name=jdk- when: need_app_server|bool include_role: name=deployappserver

(左右滑动查看全部代码)

5

部署

部署主要为执行产品部署操作,主要进行安装包的获取,配置文件的修改、部署等操作。在执行过程中根据product_type参数选择对应的产品role,同一产品不同产品版本在同一role下定义不同的task执行不同的操作。

- include_role: name=setfactor- when: revert_state|boolinclude_role: name=revertsnapshot- include_role: name=cleanenv- include_role: name=getpackage- include_role: name=jdk- when: need_app_server|bool include_role: name=deployappserver- include_role: name={{ product_type }}- when: start_server|boolinclude_role: name=startserver

(左右滑动查看全部代码)

具体的部署过程根据product_type定义不同的操作,其中一个产品部署操作如下所示:

- include_vars: "common_vars.yml"- include_vars: "{{product_module|lower}}.yml"
- name: modify install.propertieslineinfile:path: "{{ user_dir }}/config/install.properties"regexp: "{{ re_item.original }}"line: "{{ re_item.replace }}"with_items: "{{ deploy_var }}"loop_control:loop_var: re_item
- name: update "install.sh"lineinfile:dest: "{{ user_dir }}/install.sh"regexp: "{{ item.line }}"line: "{{ item.insertafter }}"with_items:- { line: "^export P_I_JAVA_HOME=", insertafter: "export P_I_JAVA_HOME={{ local_java_home }}" }- name: install product shell: ./install.shargs:chdir: "{{ user_dir }}/"- name: wait install successwait_for: path: "{{ user_dir }}/logs/install.log"search_regex: "esb.* installed successfully"timeout: 60

(左右滑动查看全部代码)

6

启动

部署完成后修改启动参数,并启动服务,并检查服务的启动状态。

- name: copy start.sh filetemplate:src: start.shdest: "{{ install_dir }}/start.sh"mode: 0755- name: change vm optionswhen: app_server_name | lower == 'jboss'lineinfile: dest: "{{ install_dir }}/startServer.sh"regexp: 'Display our environment'line: 'JAVA_OPTS="$JAVA_OPTS -Xms2G -Xmx2G"'- name: start Servershell: bash start.shargs: chdir: "{{ install_dir }}"- name: wait server startwhen: have_app_server_portwait_for: timeout=60 port="{{ app_server_port }}" state=started

(左右滑动查看全部代码)

以上六个部署过程实现了不同产品测试环境的快速部署。

DevOps-发布流水线





部署脚本编写完成了,该如何有效的去执行部署脚本。每个产品部署时的数据库信息、应用服务器相关参数有十几二十个,每次去查看脚本定义来确定这些参数对每个测试人员是不友好的。结合普元Devops产品的发布流水线功能,就可快速便捷的实现测试环境部署。


首先通过在DevOps中定义发布流水线,将产品部署流程分为代码仓库拉取脚本、部署产品和发送邮件三部分。

对于部署过程中的参数,通过发布流水线的参数化功能实现。将需要修改的参数定义为入参,这样在执行发布的时候可根据实际需要修改参数值。

对于具有明确有限个值的参数,可定义为枚举类型的参数,并可以映射为易读易理解的名称,devops中对枚举类型的参数提供下拉选择框,方便部署过程中进行参数修改。可通过multiSelect属性定义实现单选和多选。

所有参数化完成后,利用devops中shell脚本执行功能调用ansible-playbook命令并将定义的参数通过extra-vars选项传递给ansible完成测试环境的部署。

定义的发布流水线既可以通过定时构建触发,定时构建触发时使用参数定义的默认值;也可以手动发布,手动发布时可以动态修改部署参数。这样就可以根据测试需求快速实现不同组合环境的部署。

对于不同的测试环境组合,也可以定义多个发布任务。根据实际的环境规划,对不同的任务通过标签进行分类管理,就可以快速定位部署任务,也可以有效实现环境部署任务的管理。

Ansible结合Devops,既实现了多产品多组合环境的快速部署,也完成了对环境部署任务的高效管理,为产品测试过程中环境提供保障。

参考资料

1:https://baike.baidu.com/item/ansible/20194655?fr=aladdin

2:https://www.edureka.co/blog/chef-vs-puppet-vs-ansible-vs-saltstack/

推荐阅读

DevOps之代码模块设计浅析

DevOps平台之测试管理设计

移动+DevOps,普元迎来小程序2.0时代

关于作者:dozeno,高级测试开发工程师,主要参与EOS、ESB等产品的自动化测试和持续部署工作,热衷于自动化测试、持续部署和Devops等相关技术。

关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!


推荐阅读
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
author-avatar
女院外语系10级商务英语一班
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有