一个purge参数引发的惨案——从线上hbase数据被删事故说起
在写这篇blog前,我的心情久久不能平静,虽然明白运维工作如履薄冰,但没有料到这么一个细小的疏漏会带来如此严重的灾难。这是一起其他公司误用puppet参数引发的事故,而且这个参数我也曾被“坑过”。
0. 一个purge参数引发的事故
file {'/var/lib/data_directory':
xxxx => xxx,
......
recurse => true,
purge => true
}
1. 语法检查
puppet parser validate logserver.pp
Error: Could not parse for environment production: Syntax error at 'eth0_netmask' at sunfire/manifests/logserver.pp::
route-eth.erb:1: syntax error, unexpected '<'
<%= @internal_network %> via <%= @internal_gateway %>
^
2. 代码风格检查
puppet-lint manifests/init.pp
WARNING: class inheriting from params class on line 339
WARNING: line has more than 80 characters on line 47
WARNING: line has more than 80 characters on line 167
puppet-lint --no-80chars-check /path/to/my/manifest.pp
3. 模块测试
it { should contain_package('keystone').with(
'ensure' => param_hash['package_ensure']
) } it { should contain_group('keystone').with(
'ensure' => 'present',
'system' => true
) }
it { should contain_user('keystone').with(
'ensure' => 'present',
'gid' => 'keystone',
'system' => true
) }
随后执行rspec来验证这些测试能否通过。
如果希望集成到rake命令中去,我们可以在Rakefile里添加:
require 'puppetlabs_spec_helper/rake_tasks'
随后使用以下命令来完成相应的spec执行模块测试:
rake spec # Run spec tests in a clean fixtures directory
rake spec_clean # Clean up the fixtures directory
rake spec_prep # Create the fixtures directory
rake spec_standalone # Run spec tests on an existing fixtures directory
因此,在使用从github或者puppetforge下载的module时,阅读README和测试用例是非常重要的,如果我当时仔细阅读了apache::init的测试用例,也不会出现所谓被坑的问题,因为人家明明在apache_spec.rb里写有对/etc/apache/sites-enabled目录的测试:
it { should contain_file("/etc/httpd/conf.d").with(
'ensure' => 'directory',
'recurse' => 'true',
'purge' => 'true',
'notify' => 'Class[Apache::Service]',
'require' => 'Package[httpd]'
)
}
所以说,其实并不存在坑,只是因为在使用他人编写的模块前没有去阅读其文档和测试,完全可以避免的。
4.开发环境和测试环境的验证
最终部署逻辑能否上线到生产环境,还需要在开发环境和测试环境进行验证。可以使用目前流行的vagrant,Openstack等工具搭建一个测试平台,调用API创建符合生产环境的集群,通过puppet做软件安装和配置,验证部署逻辑是否符合预期。开发环境和测试环境的不同点在于,测试环境的所有变更与线上环境完全一致,不允许有任何的人工干预。
至此,一个通过验证的puppet部署逻辑可以release了,打上tag,可以准备发布到线上了。当然不能少了线上变更流程,写下在此次线上变更的详细操作以及回滚机制。
尾声
故事的尾声,我想告诉大家不幸中的万幸,那个可怜的同学,最终找回了大部分的数据。
一个purge参数引发的惨案——从线上hbase数据被删事故说起的更多相关文章
- 【MySQL】实现线上千万数据表添加字段操作以及缓存刷新
需求背景: 由于业务需求,需要在线上用户表添加渠道字段,用于区分不同渠道注册的用户,目前该表有20+个字段,8个索引 线上用户数据大概1500W左右,需要不停机增加数据库字段,同时需要刷新Redis缓 ...
- Redis中一个String类型引发的惨案
曾经看到这么一个案例,有一个团队需要开发一个图片存储系统,要求这个系统能快速记录图片ID和图片存储对象ID,同时还需要能够根据图片的ID快速找到图片存储对象ID.我们假设用10位数来表示 ...
- 一个随意list引发的惨案(java到底是值传递还是引用 传递?)
前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentMo ...
- 一个 curl 配置引发的惨案
问题 这两天想装新版本的 node,发现 nvm 一直报下面这个错误.我反复 Google 了,但是并没有找到一条我能用的. 痛苦 我起初一直怀疑是我用的 zsh-nvm 抽疯,所以今天有空就把它还有 ...
- charles抓取线上接口数据替换为本地json格式数据
最近要做下拉刷新,无奈测试服务器的测试数据太少,没有足够的数据做下拉刷新,所以用charles抓取了测试服务器的接口,然后在伪造了很多数据返回到我的电脑上,下面来说说使用方法: 第一步: 安装FQ软件 ...
- gor实现线上HTTP流量复制压测引流
一.使用背景 gor 是一款go语言实现的简单的http流量复制工具,它的主要目的是使你的生产环境HTTP真实流量在测试环境和预发布环境重现.只需要在 代理例如nginx入口服务器上执行一个进程,就可 ...
- TCPCopy 线上流量复制工具
TCPCopy是一种重放TCP流的工具,使用真实环境来测试互联网服务器上的应用程序. 一.描述: 虽然真实的实时流量对于Internet服务器应用程序的测试很重要,但是由于生产环境中的情况很负责,测试 ...
- 线上bug的解决方案--带来的全新架构设计
缘由 本人从事游戏开发很多年一直都是游戏服务器端开发. 因为个人原因吧,一直在小型公司,或者叫创业型团队工作吧.这样的环境下不得不逼迫我需要什么都会,什么做. 但是自我感觉好像什么都不精通..... ...
- 线上bug分析
昨天下午大神把组内几十号人召集在一起开Online bug分析大会,主要是针对近期线上事故从事故原因和解决方案两个维度来分析. 对金融软件来说,每一次的线上事故都有可能给公司带来重大的损失,少扣了用户 ...
随机推荐
- window 2003 配置FTP +防火墙设置
2保险的做法是 不允许匿名登录,吧钩去掉 后面我们会添加一个用户,并且赋予权限 3 主目录 可以设置时当前计算机目录或者是另一台计算机目录(映射) FTP站点目录:浏览定位FTP文件所在站点,给予是否 ...
- NET Framework 4.0的安装失败处理
如果是XP系统,这么做:1.开始——运行——输入cmd——回车——在打开的窗口中输入net stop WuAuServ2.开始——运行——输入%windir%3.在打开的窗口中有个文件夹叫Softwa ...
- MSSERVER创建链接服务器
exec sp_addlinkedserver 'DB_RASS','','SQLOLEDB','127.0.0.1' ' exec sp_serveroption 'DB_RASS','rpc ou ...
- a:link,a:visited,a:hover,a:active
1:解释 link:连接平常的状态 visited:连接被访问过之后 hover:鼠标放到连接上的时候 active:连接被按下的时候 详细的: :hover版本:CSS1/CSS2 兼容性 ...
- log4net详细配置说明
原文地址:http://blog.sina.com.cn/s/blog_671486bc01011rdj.html 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记 ...
- Controller将Model数据传给View层,View层应该如何处理?
首先,我们在Model层中添加一个Person类. namespace MVCTest.Models{ public class Person { public string ...
- Ubuntu远程开机 (Wake on Lan)
启动者(A) 被远程开启者(B) 一.被远程开启的电脑(电脑B):1. 重新开机,并进到BIOS设定2. 把Wake On Land / Wake On PCI(E)设为Enable3. 储存并进入U ...
- Yaf零基础学习总结3-Hello Yaf
Yaf零基础学习总结3-Hello Yaf 上一次我们已经学习了如何安装yaf了,准备工作做好了之后我们来开始实际的编码了,码农都知道一个经典的语句就是“Hello World”了,今天我们开始入手Y ...
- URAL - 1917 Titan Ruins: Deadly Accuracy(水题)
水题一个,代码挫了一下: 题意不好理解. 你去一个洞窟内探险,洞窟内有许多宝石,但都有魔法守护,你需要用魔法将它们打下来. 每个宝石都有自己的防御等级,当你的魔法超过它的防御等级时它就会被你打下来. ...
- 使用lock和condition实现的阻塞队列-字符串
在jdk 的API中提供了一个字符串的阻塞队列 : class BoundedBuffer { final Lock lock = new ReentrantLock(); final Conditi ...