【Anisble 文档】【译文】测试策略
最近在琢磨 ansible,想使用这个搞一个自动发布部署系统,google以下发现了中文文档,但是里面很多感觉不专业,念都念不顺。看英文版又费劲,只能啃完中文啃英文。
本篇是译文第一篇,后续持续维护。
Testing Strategies 测试策略
Integrating Testing With Ansible Playbooks 集成测试到 Ansible Playbooks
很多时候,人们经常会问,“我怎么更好的把测试集成到Ansible Playbooks”,这有很多种选项。Ansible被涉及为一个“快速失败”和顺序执行系统,因此很容易就可以将测试直接集成到Playbooks中。
本章我们将学习一些基础设施测试的一些方式,并且讨论合适的测试等级。
注意:
本章是讨论测试你正在开发的应用,而不是如何测试Ansible模块。测试Ansible模块移步“开发部分”
通过将一定程度的测试包含到你的部署工作流中,当是在在生产环境中运行代码时,这将减少意外的产生,同时大多数情况下,测试可以被用来避免在生产中因为更新失败而导致在整个安装过程中迁移。
因为Ansible是推模式,非常容易在本机或者测试服务器运行一些步骤。Ansible 允许你按照你想要的方式,添加尽可能多的检查和考量(权衡-balances)在你的升级流程中.
The Right Level of Testing 测试的正确等级
Ansible 是理想状态的模型。正因如此,没有必要测试已经启动的服务,已安装的软件包或者其他的事情。Ansible是那样一个系统,其会确保事物想声明的那样正确。否则,你就要assert来保证这些事情。
- tasks:
- - service: name=foo state=started enabled=yes
如果你认为服务可能没有启动,最好是请求启动它。如果服务启动失败,Ansible会适时报警。
(这不应该和服务是否正在做一些功能性的事情混淆,这将在后续详细描述)
Check Mode As A Drift Test 检查模式作为Drift Test
在上面的设置中,Ansible的-check模式,也可以被用作测试层。如果对一个现有的系统运行一个开发Playbook,使用-check标识时,ansible 命令将会报告出 Ansible 使系统进入一个期望状态所做的任何更改。
这可以让你提前知道,是否有任何必要部署到给定的系统。普通scripts 和 commands模块不运行在检查模式, 所以如果你想要某些步骤总是在检查模式下执行, 例如调用 script 模块, 添加 ‘always_run’ 标记。
- roles:
- - webserver
- tasks:
- - script: verify.sh
- check_mode: no
Modules That Are Useful for Testing支持测试的模块
某些模块对测试特别友好。以下是一个例子,确保端口打开:
- tasks:
- - wait_for: host={{ inventory_hostname }} port=22
- delegate_to: localhost
下面的例子是使用URI模块确保一个web服务返回:
- tasks:
- - action: uri url=http://www.example.com return_content=yes
- register: webpage
- - fail: msg='service is not happy'
- when: "'AWESOME' not in webpage.content"
很容易将脚本(任意语言)推送到远端,并且脚本会自动的失败,如果其返回一个非0返回值
- tasks:
- - script: test_script1
- - script: test_script2 --parameter value --parameter2 value
如果你使用角色(你应该使用,角色非常棒)。脚本由script模块推送,其可以放在一个角色下的files目录。
并且assert模块使得很容易验证各种结果。
- tasks:
- - shell: /usr/bin/some-command --parameter value
- register: cmd_result
- - assert:
- that:
- - "'not ready' not in cmd_result.stderr"
- - "'gizmo enabled' in cmd_result.stdout"
你也许会想要检查没有在Ansible配置中声明的设置的文件的存在性,此时,stat是一个好的选择:
- tasks:
- - stat: path=/path/to/something
- register: p
- - assert:
- that:
- - p.stat.exists and p.stat.isdir
正如上述,没有必要检测命令的返回值。Ansible自动的检测它们。对于检测用户的存在性来说,使用user模块来检测。
Ansible是一个“快速失败”的系统,因此,当创建用户失败时,他会停止执行playbook运行,你无须检查其后面的部分。
Testing Lifecycle 测试生命周期
如果把应用的一些基本验证写到playbook中,他们会在每次部署时都会运行。
正因如此,部署到一个本地的开发虚拟机以及一个阶段性的环境,都会根据你的生产环境之前的部署计划来验证这一切。
你的工作流可能会是如下这样:
使用相同的playbook在开发过程中嵌入测试
使用相同的playbook部署到阶段性环境,仿真生产环境
运行集成测试,QA团队针对阶段性环境编写的测试用例
部署到生产环境,使用相同的集成测试,译者注:使用验证用例集合来确保上线成功
如果你们是一个产品服务,集成测试这样的事情应该是由QA团队来编写。这包含Selenium测试和自动化API测试,其通常不会嵌入到你的AnsiblePlaybooks。
然而,包含一些健康性检查到Playbook中是非常有意义的。在某些情况下,他应该是QA测试的子集,同时,你可以根据这个成功还是失败来决定是否将该机器添加到负载均衡中。
Integrating Testing With Rolling Updates 集成测试到滚动更新
如果你已经阅读了代理、滚动更新、本地动作,滚动更新可以被扩展是非常明显的。同时,你可以根据这个成功还是失败来决定是否将该机器添加到负载均衡中
以下是嵌入测试的显著效果
- ---
- - hosts: webservers
- serial: 5
- pre_tasks:
- - name: take out of load balancer pool
- command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
- delegate_to: 127.0.0.1
- roles:
- - common
- - webserver
- - apply_testing_checks
- post_tasks:
- - name: add back to load balancer pool
- command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
- delegate_to: 127.0.0.1
当然,在上面,the “take out of the pool” and “add back” steps可以通过调用Ansible的负载均衡模块或者合适的shell命令替换。
你也可以有这样的步骤:使用监控模块来开启或者结束一个空窗期(停止监控报警),对指定的机器。
同时,你从上面看到的测试被用作了一扇门:如果 “apply_testing_checks” 步骤没有被执行,机器不会回到池中。
阅读 delegation 章节,你可以了解到 “max_fail_percentage”,同时,你可以控制多少失败的测试会停止滚动更新继续。
上面的这个测试方式,可以修改为下面的方法,在远端机器执行测试:
- ---
- - hosts: webservers
- serial: 5
- pre_tasks:
- - name: take out of load balancer pool
- command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
- delegate_to: 127.0.0.1
- roles:
- - common
- - webserver
- tasks:
- - script: /srv/qa_team/app_testing_script.sh --server {{ inventory_hostname }}
- delegate_to: testing_server
- post_tasks:
- - name: add back to load balancer pool
- command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
- delegate_to: 127.0.0.1
Achieving Continuous Deployment 实现持续部署
如果需要,上面的技术可以被扩展用来启用持续部署实践。
工作流如下所示:
编写并使用自动化,来部署本地虚拟机
对每一次代码提交,使用一个CI系统,例如 Jenkins,部署到极端性环境
对每一次部署,部署JOB调用测试脚本,来通过或者失败一个构建
如果所有的部署job成功,它会在生产环境运行相同的Playbooks,针对相同的inventory清单文件。
一些Ansible用户,使用上面的方法,在一个小时内部署五六次,同时他们的基础设施服务不会下线。一个自动 QA 系统是至关重要的。
如果你仍然大量使用手工QA,你仍然需要做一下决策:是否同样进行手工的部署。使用模块“script”,“stat”,“uri”和assert对于滚动更新方式和包含一些基本健康检查仍然是有用的。
Conclusion 结论
- Ansible认为你不需要其他框架来验证基础设施的基础事物是正常的。这是因为Ansible是一个基于顺序执行的系统,对某台主机的未处理异常会立刻失败,同时阻止在那台主机上的进一步操作。这迫使 Ansible 在运行结束后将错误作为摘要显示在顶端。
- 同时,因为Ansible 被设计为多层编排系统,他非常容易嵌入测试到一个Playbook运行的尾部,或者使用松散的任务或者角色。当使用滚动更新时,测试步骤可以决定是否把主机添加会负载均衡器中。
- 最后,因为Ansible错误通过所有的方式将返回码传递给Ansible程序本身,同时Ansible默认运行在推模式,如果你希望使用Ansible来推出系统作为持续集成/持续交付管道的一部分,Ansible是放入构建环境中一个极好的步骤,如上面描述。
Ansible的关注点不是基础设施的测试,而是应用测试,我们强烈建议和你的团队的QA一起,并询问哪一种测试在每次部署开发机虚拟机有意义,哪一种测试应该在每次部署时运行在阶段性环境中。很明显,在开发阶段,单元测试是极好的。
不是单元测试你的Playbook。
综上,测试是一个组织性和特定位置的事情。每一个人都应该这样做, 但是要根据你要部署什么以及谁在使用它们来确定最适合的方案 – 但每个人肯定都会从一个更加强大和可靠的部署系统中受益
【Anisble 文档】【译文】测试策略的更多相关文章
- 【VR】Leap Motion 官网文档 FingerModel (手指模型)
前言: 感谢关注和支持这个Leap Motion系列翻译的朋友们,非常抱歉因为工作原因非常久没有更新,今后这个翻译还会继续(除非官方直接给出中文文档).本篇献给大家的是 <FingerModel ...
- 【Ansible 文档】【译文】Playbooks 变量
Variables 变量 自动化的存在使得重复的做事情变得很容易,但是我们的系统不可能完全一样. 在某些系统中,你可能想要设置一些与其他系统不一样的行为和配置. 同样地,远程系统的行为和状态也可以影响 ...
- 【Ansible 文档】【译文】网络支持
Networking Support 网络支持 Working with Networking Devices 使用网络设备 自从Ansible 2.1开始,你现在可以使用成熟模型 - 编写 play ...
- 【Ansible 文档】【译文】Windows 支持
see also:List of Windows Modules Windows Support Windows 支持 Windows: How Does It Work Windows:如何工作 正 ...
- 【Ansible 文档】【译文】配置文件
这里说明一下配置文件的内容,原文地址:http://docs.ansible.com/ansible/latest/intro_configuration.html 这个与[Ansible 文档]配置 ...
- 【Ansible 文档】【译文】Ad-Hoc 命令介绍
Introduction To Ad-Hoc Commands Ad-Hoc命令介绍 下面的例子展示了如何使用 /usr/bin/ansible 来运行ad hoc任务. 什么是ad hoc命令? 一 ...
- 【Ansible 文档】【译文】入门教程
http://docs.ansible.com/ansible/latest/intro_getting_started.html Foreword 前言 到这里,你应该已经安装了Ansible,是时 ...
- 【Ansible 文档】【译文】常见问题
http://docs.ansible.com/ansible/latest/faq.html 如何为一个task或者整个Playbook设置PATH或者任意其他环境变量? 通过environment ...
- Sqlite3中存储类型和数据类型结合文档解析。
sqlite3是个很小的数据库,运行在手机,机顶盒上....那它就不可能像musql,sqlserver那么规范,有很多的数据类型,之前我也以为它定义了很多数据类型,其实不是他就5个存储类,那么多数据 ...
随机推荐
- [转]WebForm中使用MVC
本文转自:https://www.cnblogs.com/encoding/articles/3556046.html 前言 掐指一算,3年没写博了,好懒的说... 众所周知,MVC现在越来越火了,不 ...
- c#基础学习(0724)之可变参数、ref和out
params可变参数,无论有几个参数,必须出现在参数列表的最后,可以为可变参数直接传递一个对应类型的数组 #region 可变参数 //1.如果方法有多个参数,可变参数可以作为最后一个参数 //2.可 ...
- JS原型与原型链终极讲解
function Person () { this.name = 'John'; } var person = new Person(); Person.prototype.say = functio ...
- 记录一次读取memcache缓存的优化
我们是用mvc做web,大部分数据都用memcache做了缓存 有2台memcache缓存服务器 数据并不大. 某页面响应较慢,大概在4s左右. 页面本身很简单只是显示一个表单. 但是layout相对 ...
- CentOS 忘记root密码(重置root密码)
首先开机选择Advanced options for ****这一行按回车: 然后选中最后是(recovery mode)这一行按"E"进入编辑页面: 将ro recovery改为 ...
- ef和mysql使用(二)--让mysql支持EntityFramework.Extended实现批量更新和删除
我们都知道Entity Framework 中不能同时更新多条记录,但是一个老外写的扩展库可以实现此功能EntityFramework.Extended,但是如何是mysql数据库要怎么实现呢 首先实 ...
- wamp 安装monggo扩展
1.下载对应的monggo扩展 http://pecl.php.net/package/mongo 2. 找对应的版本 放在D:\program\wamp\bin\php\php5.5.12\ext ...
- MUI框架 选择器的使用
js.css引用 <script type="text/javascript" src="librarys/mui/js/mui.min.js">& ...
- js中list 和 map还有string的部分操作
1.创建list或者数组 var list = []; list中添加元素:list.push("hello"); 如果没有先定义为数组类型不能使用 push方法 判断list ...
- js与native的交互
WebView与Javascript交互(Android): WebView与Javascript交互是双向的数据传递,1.H5网页的JS函数调用Native函数 2.Native函数调用JS函数,具 ...