热门标签 | 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,数据治理,移动架构原创技术分享。长按二维码关注!


推荐阅读
  • 在开发板的启动选项中看到如下两行:7:LoadBootLoadercodethenwritetoFlashviaSerial.9:LoadBootLoadercodethenwri ... [详细]
  • 实现Win10与Linux服务器的SSH无密码登录
    本文介绍了如何在Windows 10环境下使用Git工具,通过配置SSH密钥对,实现与Linux服务器的无密码登录。主要步骤包括生成本地公钥、上传至服务器以及配置服务器端的信任关系。 ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • 本文详细介绍了如何搭建一个高可用的MongoDB集群,包括环境准备、用户配置、目录创建、MongoDB安装、配置文件设置、集群组件部署等步骤。特别关注分片、读写分离及负载均衡的实现。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 在 Ubuntu 22.04 LTS 上部署 Jira 敏捷项目管理工具
    Jira 敏捷项目管理工具专为软件开发团队设计,旨在以高效、有序的方式管理项目、问题和任务。该工具提供了灵活且可定制的工作流程,能够根据项目需求进行调整。本文将详细介绍如何在 Ubuntu 22.04 LTS 上安装和配置 Jira。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 本文探讨了在一个物理隔离的环境中构建数据交换平台所面临的挑战,包括但不限于数据加密、传输监控及确保文件交换的安全性和可靠性。同时,作者结合自身项目经验,分享了项目规划、实施过程中的关键决策及其背后的思考。 ... [详细]
  • 本文介绍了Linux操作系统的核心组成部分——内核及其版本分类,以及市面上常见的几种Linux发行版,旨在为初学者提供一个清晰的学习路径。 ... [详细]
  • 本文介绍了Linux系统中的expect命令及其在自动化任务中的应用,同时探讨了Python中的pexpect模块如何实现类似功能。 ... [详细]
  • Vulnhub DC3 实战记录与分析
    本文记录了在 Vulnhub DC3 靶机上的渗透测试过程,包括漏洞利用、内核提权等关键步骤,并总结了实战经验和教训。 ... [详细]
  • 本文详细介绍了如何在 CentOS 7 及其衍生发行版(如 Red Hat, Oracle, Scientific Linux 7)上安装和完全卸载 GitLab。包括安装必要的依赖关系、配置防火墙、安装 GitLab 软件包以及常见问题的解决方法。 ... [详细]
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社区 版权所有