您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

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

时间:2020-09-03 10:56:58  来源:  作者:
基于Ansible和Devops的一键测试环境部署实践

 

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

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

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

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

 

而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-tools state=present“

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

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

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

Ansible Playbook模式使用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.inventory

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

files:用来存放copy模块或script模块调用的文件

templates:用来存放jinja2模板

tasks:目录包含一个main.yml文件,该角色执行入口

handlers: 角色中触发条件时执行的动作

vars: 定义此角色用到的变量

defaults:为当前角色设定默认变量

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

ansible-playbook -i linux.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 version

  when: db_version|string == '5.7'

  set_fact:

    db_driver_name: mysql-connector-JAVA-5.1.32.jar

    db_platform: "org.hibernate.dialect.MySQLDialect"

 

- name: Set ipv4 db_url and driver name

  when: use_net4|bool

  set_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.properties
  lineinfile:
    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_tasksinclude_role:

include_tasksinclude_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: directory
dest: "{{ App_server_home }}/conf"

- name: change tomcat server port
  template:
    src: "tomcat/server-{{ app_server_version }}.xml"
    dest: "{{ app_server_home }}/conf/server.xml"

5. wait_for

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

- name: wait server start
  when: have_app_server_port
  wait_for: 
    state: started
    port: "{{app_server_port}}"
timeout: 60

- name: wait install success
  wait_for:  
    path: "{{ user_dir }}/logs/install.log"
    search_regex: "esb.* installed successfully"

有了ansible丰富的模块支持,合理的对部署过程进行设计,就可以实现多种产品多组合环境的部署。为了尽可能的减少后期脚本维护、新产品支持带来的工作量,增加脚本的复用性,我们将产品的部署过程分为了以下几个步骤

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

 

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 snapshot
  vmware_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: localhost
  register: revertstate

3. 清理环境

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

- name: copy killport file

  when: have_port

  template:

    src: killport.sh

    dest: "{{ user_dir }}//killport.sh"

mode: 0755

 

- name: close {{ deploy_type }} application

  when: have_port

  shell: bash killport.sh

  args:

    chdir: "{{ user_dir }}/"

  ignore_errors: yes

 

- name: close {{ deploy_type }} application

  when: not have_port

  shell:  bash {{ stopFile }} 

  args:

    chdir: "{{ user_dir }}/"

  ignore_errors: yes 

 

 - name: close {{ deploy_type }} application

  when: not have_port

  shell:  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|bool

  include_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|bool
  include_role: name=startserver

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

- include_vars: "common_vars.yml"

- include_vars: "{{product_module|lower}}.yml"
- name: modify install.properties
  lineinfile:
    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.sh
  args:
    chdir: "{{ user_dir }}/"

- name: wait install success
  wait_for:  
    path: "{{ user_dir }}/logs/install.log"
    search_regex: "esb.* installed successfully"
    timeout: 60

6. 启动

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

- name: copy start.sh file
  template:
    src: start.sh
    dest: "{{ install_dir }}/start.sh"
mode: 0755 
  
- name: change vm options
  when: app_server_name | lower == 'jboss'
  lineinfile: 
    dest: "{{ install_dir }}/startServer.sh"
    regexp: 'Display our environment'
    line: 'JAVA_OPTS="$JAVA_OPTS -Xms2G -Xmx2G"'

- name: start Server
  shell:  bash start.sh
  args: 
    chdir: "{{ install_dir }}"

- name: wait server start
  when: have_app_server_port
  wait_for: timeout=60 port="{{ app_server_port }}" state=started

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

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

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

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

 

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

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

 

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

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

 


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

 

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

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

 

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

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

 

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

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

 

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/



Tags:测试环境   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
问题后端已经配置好了跨域,前端本地搭建vue-cli测试环境的时候如何解决跨域?(前提进行了基本的axios封装)分析这个时候后端API是一个明确的外网环境(使用外网IP或固定域名访问),...【详细内容】
2021-11-03  Tags: 测试环境  点击:(55)  评论:(0)  加入收藏
一、背景介绍Pikachu是一个带有各种漏洞的Web应用系统,这个系统是使用PHP搭建的,需要PHP环境和Mysql数据库支持。我们可以利用phpstudy在本地搭建这个渗透测试平台,如果你是一...【详细内容】
2021-10-09  Tags: 测试环境  点击:(52)  评论:(0)  加入收藏
背景试想一下这种情况,你负责的某个项目数据源有SQL Server、Oracle和MySQL,假设现在不让你访问生产库,也没有测试库给你用,你就只有一台开发电脑,要你做开发你怎么做?你肯定会说,...【详细内容】
2021-05-13  Tags: 测试环境  点击:(191)  评论:(0)  加入收藏
以下是详细的步骤1. JDK \Jmeter \ Ant安装:1.1.安装JDK:双击jdk-7u80-windows-x64.exe安装,默认安装到C:\ProgramFiles\Java目录1.2.安装Jmeter:在我的电脑—E盘(建议与...【详细内容】
2021-04-16  Tags: 测试环境  点击:(224)  评论:(0)  加入收藏
我想题主的题目提的不够准确,应该是更偏重如果部署测试环境。我的答案:Jenkins+git插件+shell脚本+python脚本。 A.Jenkins Jenkins是一款由Java编写的开源的持续集成工具。...【详细内容】
2021-03-01  Tags: 测试环境  点击:(349)  评论:(0)  加入收藏
随着网络架构的不断升级和业务的复杂化,对产品多环境支持的要求越来越高。产品支持的数据库、应用服务器、中间件、操作系统等的多样化,使测试环境的组合越来越多,导致测试环...【详细内容】
2020-09-03  Tags: 测试环境  点击:(62)  评论:(0)  加入收藏
导语:很多人在面试软件测试的过程中,经常被问到“你会搭建测试环境吗”面对这样的提问,你知道怎么回答么?一、如何回答面试的时候,遇到这样的提问,很多人的都会感觉脑子一下一片空...【详细内容】
2020-07-09  Tags: 测试环境  点击:(82)  评论:(0)  加入收藏
appium做app自动化测试,环境搭建是比较麻烦的。也是很多初学者在学习app自动化之时,花很多时间都难跨越的坎。但没有成功的环境,就没有办法继续后续的使用。在app自动化测试当...【详细内容】
2019-08-07  Tags: 测试环境  点击:(209)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条