17

ansible的一个bug经历-breeze

 3 years ago
source link: https://blog.51cto.com/387249/2497465
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

ansible的一个bug经历

使用ansible在大规模(几百台以上规模比较容易遭遇)部署机器的时候,有时候会碰到ansible进程hang在某个点上,这个点不一定每次都一样。
研究了一个下午,发现hang住的时候,CI/CD的agent上并没有报错日志,被执行host上也没有ansible的日志输出,并且无论等待多长时间也不会退出。

期初怀疑是版本问题,因为之前线上一直用的2.7版本,最近刚切换到2.9,但是实际上这个部署的job在使用2.9版本的时候已经成功过不少次。然后检查CI/CD上部署job的VCS配置,发现虽然有更新,但是并没有什么很大的可能明显导致这种情况发生的changes。

启动google大法,发现ansible的github上有人提过一个issue,一个很老的2017年9月的issue,https://github.com/ansible/ansible/issues/30411
这个issue最后一个comment是提交了一个PR(竟然是20天前刚提交的),这个PR给task执行增加了一个硬超时,已经merge,虽然没有解释为什么会hang住,但是起码提供了一个解决方案。而且里面的comments提到了一个关键的复现方法,一个简单的"df"命令就可以让ansible进程hang住。
于是我找了两台机器,装了nfs,client端挂载了server端的一个目录,然后把server端的nfs进程stop掉,这时候在client中执行"df"命令,效果等同于进程hang住,原理也很简单,因为nfs链接断掉了,"df"在等待返回,等不到就“假死”在那里。
再然后,我配置了一个只有一条shell命令的ansible playbook,让多台机器(其中包括了这个nfs client节点)同时运行,结果果然是ansible在执行到这个nfs client节点的时候hang住再也不动了,并且如果我重新启动nfs server端,ansible立即就回正常执行完,说明ansible进程没有“死”,只是一直在“等待”。

现在在回过头来思考,结论应该是批量开机器的时候,因为我们用的是AWS,在规模很大的情况下,经常有实例会因为各种特例问题导致某些task挂起在机器上,而这个时候由于ansible没有超时机制,并且!最关键的来了,ansible没有收到任何错误值和返回值,于是就一直在“等待”,等到海枯石烂。
短期的解决方法,如果是云平台,干掉那些“不正常”的机器,重新run一次job,一般都会解决。
长期的话,超时是一个可行的方案,而且ansible还需要真正的解决是并行问题,不要让一个机器的问题导致整个job的失败(某一个实例有问题,那就提示出来,其他的继续跑)。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK