Ansible自动化(二十二) Ansible并行与分批执行
1 | 作者:李晓辉 |
调整任务并发数
在Ansible里,forks
其实就是用来控制你一次连接几个机器执行任务的。默认情况下,Ansible会一个一个任务慢慢地做,但有时候任务特别多,你就想加快速度对吧?这时就可以调整forks
,让它同时做多个任务。
举个例子,如果你有很多台机器,要执行相同的操作,默认情况下Ansible会一台台机器去执行,但如果你设置forks
,比如指定10个,它就会同时在10台机器上执行任务,省下很多时间。
你可以在几种地方设置这个:
- 在命令行加
-f
,比如:ansible-playbook -f 10 playbook.yml
,这样它就会并行做10个任务。 - 在配置文件
ansible.cfg
里设置,能让它每次都按照你设定的方式跑。 - 如果你写Playbook,也可以通过
strategy
来设置并行数。
不过要注意,forks
的数量不能太大,不然可能会把机器搞得很慢。要根据你的系统和目标主机的数量来调整,找个合适的平衡点就好。
修改 Ansible 配置⽂件或者ansible-navigator run 命令的-f参数可以修改具体的数字
1 | [student@workstation ~]$ ansible-navigator config dump -m stdout |
1 | [student@workstation ~]$ ansible-navigator config list -m stdout |
假设你在Ansible配置了五个forks的默认值,然后有十个受管主机,Ansible的执行方式会是这样的:
- 任务执行顺序:Ansible会首先在前五个主机上执行play的第一个任务。完成后,接着在接下来的五个主机上执行同样的任务,直到所有主机都执行完第一个任务。
- 任务切换:当第一个任务在所有主机上都执行完后,Ansible就开始执行下一个任务,同样也是分批次,每批五个主机同时执行。
- 任务循环:这种方式会持续进行,每个任务都按照这个分叉方式逐个轮流执行,直到play完成。
分批运行整个play
通常情况下,Ansible在执行play时,会确保所有受管主机完成一个任务后,才会开始下一个任务。所有主机完成所有任务之后,才会处理任何通知的处理程序(比如重启服务之类的)。
但是,有时候这种“所有主机一起干”的方式可能会出问题。例如,假设你正在更新一个负载均衡的Web服务器集群,你可能需要在更新过程中让每个Web服务器停服务。如果所有服务器在同一个play里同时更新,那它们可能都在同一时刻停服务,这样就有可能导致整个Web服务集群都挂了。
解决这个问题的方法之一是使用serial
关键字,这样你就可以让play按批次来逐个处理主机。也就是说,它会先处理第一批主机,完成后再处理下一批,这样就避免了所有主机同时停服务的问题。
我们看一下这个案例
1 |
|
解释:
serial: 2
— 这表示Ansible每次会处理两台主机,直到所有的主机都完成更新。tasks
部分是你要执行的任务,在这里我们更新httpd
包并重启Web服务器。handlers
部分定义了如果有任何主机通知需要执行的处理程序,在更新和重启Web服务器后,Ansible会运行相应的处理程序(比如重启Nginx服务)。
执行流程:
- Ansible会先在前两台
web_servers
上执行httpd
包的更新和重启任务。 - 如果这两台主机触发了处理程序(比如需要重启Nginx),那么Ansible会立即执行相应的处理程序。
- 完成前两台主机的任务后,Ansible会继续处理接下来的两台主机,直到所有主机都完成更新。
有时候,每次处理的主机批次就当作一个整体来执行。意思就是,如果某一批主机的任务失败了,那整个play就会失败,导致playbook停止执行。
比如,在前面的例子里,serial
设置为2,如果前两台主机出现问题,play就会失败,接下来的主机就不再继续执行。这其实挺实用的,因为这样就能确保只有一部分服务器出问题,服务可能会降级,但不会完全崩溃。
serial
关键字也可以设置为百分比,这个百分比是基于play中所有主机的总数来决定每次滚动更新时的批次大小。不管你设置的百分比是多少,每批处理的主机数至少为1,最多是总主机数的百分比大小。这样,你就能根据总主机数动态调整每批次更新的数量了,关于这一点,我们下一节再聊。