LabHub
学习 学习路径 课程

基础设施即代码

跑两次也得一样

在 LabHub 中继续学习

一句话总结

对称性是指即使多次执行相同的工作,结果也是相同的性质,如果没有这一点,自动化就会变成每次运行都会产生不同结果的赌博。

概念图: 稳态性是即使多次进行相同的工作,结果也会保持不变 · 收敛是将现在的状态拉向想要的状态 · 我拥有到什么程度的领域? · 在那个领域内发现陌生东西时,是删除还是通知。

为什么需要这个?

自动化不会只执行一次。运行者因超时而死亡,重新执行,其他人又转来转去同样的游戏本,调度器每小时都应用同样的东西。如果此时不保证“已经完成了就什么都不做”,那么重新执行本身就变得危险。最终人们会害怕自动化,因为害怕就用手做,因为用手做就又变成了雪花服务器。

证明方法出乎意料地简单。连续运行两次apply,看第二个plan是否没有变化(结束代码0)就可以了。这条一行的检查没有通过的自动化还不能被信任。

怎么行动

“执行前确认当前状态”是“执行前确认当前状态”中的“执行前确认当前状态”。在创建目录之前,检查是否存在;在写文件之前,检查内容是否相同;在更改权限之前,读取当前权限。因此,好的模块总是有两个分支。更改后为changed,已经正确为unchanged。

偏执症破裂最常见的地点是直接用shell或command执行命令时,而不是用专用模块。因为工具不知道该命令做什么,所以每次都执行。所以creates=removes=加上相同的条件,让已经结束的工作跳过。代表性的错误是说在设置文件中添加一行>>是加上的。每次执行时,一行一行地堆积起来,转十圈就会变成十行。正确的实现是先确认这条行是否已经存在,如果有相同键的其他值,就替换那个位置。

在应用之前,为了提前看看会发生什么变化,请同时使用check mode和diff(--check --diff).实际上不会改变,只会显示要改变的内容,所以在第一次应用于运营服务器时是必须的。而且结果必须分清显示。必须有汇总了changed和unchanged的报告,才能在第二次运行时让人们确认changed为0的事实。

在现场相遇的样子

一半的问题是关于Playbook成功了,为什么设置很奇怪。虽然日志上只写了ok,但实际上同一行出现了三次,或者每次都会重启,服务会周期性地中断。所以成熟的团队会在CI中运行Playbook两次。如果第二次执行的changed不是0,就会破解构建。强制不一致性不是通过文档,而是通过测试来实现的。

另外,如果记录状态,就会产生检测能力。在应用时留下每个资源的路径和哈希值,以后只要通过比较就可以知道该文件是否在外面被更改。有状态文件的工具所做的事情正是这个。

极值性和收敛是不一样的

虽然这两个词经常混用,但保证的范围不同。稳态性是即使多次进行相同的工作,结果也会保持不变收敛是将现在的状态拉向想要的状态。大多数自动化只满足前面的,忽略了后面的。

区别在“删除”中体现出来。如果旋转两次放置三个设置文件的游戏本,changed为0。到此为止是均衡性。但是,如果有人用手制作了第四个文件,这个游戏本永远不会发现它。这是因为只写了“有这三个”而不是“只有这三个”的想要的状态。要收敛,必须将目录的全部内容声明为管理对象,然后删除不在列表中的内容。

所以设计自动化时,明确规定两个点。**我拥有到什么程度的领域?以及在那个领域内发现陌生东西时,是删除还是通知。**悄悄删除的话会破坏别人的工作,什么都不做的话服务器会慢慢变得彼此不同。

即使在有副作用的工作中也需要同样的区分。服务重新启动是最典型的。只有在设置文件发生变化时才需要重新启动,但如果每次都无条件地执行这个,即使播放本本身看起来是一样的(因为文件内容总是一样的),实际上每次运行都会中断服务。通知(handler)方式存在的理由就是这个,如果在结果报告中留下实际重新启动了几次,以后就能在几秒钟内回答“为什么每小时会断开几次”的问题。

最后,总结一下重试与的关系。不失败的工作,失败时只要重新执行就可以了,但不失败的工作,重试就是重复执行。网络错误无法收到响应时,无法知道该工作是否实际执行是关键。如果计划重试,该工作必须失败,如果不能失败,就只能在每个工作上贴上唯一的标记,确认是否已经处理完毕。

下次实习要做的事情

制作四个保证目录、文件、行、权限的小脚本,让每个脚本准确区分changed和unchanged。然后连续运行两次将这四个脚本绑定的运行程序,第二次证明changed是否为0。最后附加状态文件、漂移检测,以及防止同时执行的锁定。