1
2
3
4
5
作者:李晓辉

微信联系:Lxh_Chat

联系邮箱: 939958092@qq.com

调整任务并发数

在Ansible里,forks其实就是用来控制你一次连接几个机器执行任务的。默认情况下,Ansible会一个一个任务慢慢地做,但有时候任务特别多,你就想加快速度对吧?这时就可以调整forks,让它同时做多个任务。

举个例子,如果你有很多台机器,要执行相同的操作,默认情况下Ansible会一台台机器去执行,但如果你设置forks,比如指定10个,它就会同时在10台机器上执行任务,省下很多时间。

你可以在几种地方设置这个:

  1. 在命令行加-f,比如:ansible-playbook -f 10 playbook.yml,这样它就会并行做10个任务。
  2. 在配置文件ansible.cfg里设置,能让它每次都按照你设定的方式跑。
  3. 如果你写Playbook,也可以通过strategy来设置并行数。

不过要注意,forks的数量不能太大,不然可能会把机器搞得很慢。要根据你的系统和目标主机的数量来调整,找个合适的平衡点就好。

修改 Ansible 配置⽂件或者ansible-navigator run 命令的-f参数可以修改具体的数字

1
2
3
[student@workstation ~]$ ansible-navigator config dump -m stdout
...output omitted...
DEFAULT_FORKS(default) = 5
1
2
3
4
[student@workstation ~]$ ansible-navigator config list -m stdout
...output omitted...
DEFAULT_FORKS:
default: 5

假设你在Ansible配置了五个forks的默认值,然后有十个受管主机,Ansible的执行方式会是这样的:

  1. 任务执行顺序:Ansible会首先在前五个主机上执行play的第一个任务。完成后,接着在接下来的五个主机上执行同样的任务,直到所有主机都执行完第一个任务。
  2. 任务切换:当第一个任务在所有主机上都执行完后,Ansible就开始执行下一个任务,同样也是分批次,每批五个主机同时执行。
  3. 任务循环:这种方式会持续进行,每个任务都按照这个分叉方式逐个轮流执行,直到play完成。

分批运行整个play

通常情况下,Ansible在执行play时,会确保所有受管主机完成一个任务后,才会开始下一个任务。所有主机完成所有任务之后,才会处理任何通知的处理程序(比如重启服务之类的)。

但是,有时候这种“所有主机一起干”的方式可能会出问题。例如,假设你正在更新一个负载均衡的Web服务器集群,你可能需要在更新过程中让每个Web服务器停服务。如果所有服务器在同一个play里同时更新,那它们可能都在同一时刻停服务,这样就有可能导致整个Web服务集群都挂了。

解决这个问题的方法之一是使用serial关键字,这样你就可以让play按批次来逐个处理主机。也就是说,它会先处理第一批主机,完成后再处理下一批,这样就避免了所有主机同时停服务的问题。

我们看一下这个案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---
- name: Update web servers in batches
hosts: web_servers
serial: 2 # 每次处理2台主机
tasks:
- name: Update package on web server
yum:
name: httpd
state: latest

- name: Restart web server
service:
name: httpd
state: restarted

handlers:
- name: Restart nginx if needed
service:
name: nginx
state: restarted

解释:

  1. serial: 2 — 这表示Ansible每次会处理两台主机,直到所有的主机都完成更新。
  2. tasks部分是你要执行的任务,在这里我们更新httpd包并重启Web服务器。
  3. handlers部分定义了如果有任何主机通知需要执行的处理程序,在更新和重启Web服务器后,Ansible会运行相应的处理程序(比如重启Nginx服务)。

执行流程:

  1. Ansible会先在前两台web_servers上执行httpd包的更新和重启任务。
  2. 如果这两台主机触发了处理程序(比如需要重启Nginx),那么Ansible会立即执行相应的处理程序。
  3. 完成前两台主机的任务后,Ansible会继续处理接下来的两台主机,直到所有主机都完成更新。

有时候,每次处理的主机批次就当作一个整体来执行。意思就是,如果某一批主机的任务失败了,那整个play就会失败,导致playbook停止执行。

比如,在前面的例子里,serial设置为2,如果前两台主机出现问题,play就会失败,接下来的主机就不再继续执行。这其实挺实用的,因为这样就能确保只有一部分服务器出问题,服务可能会降级,但不会完全崩溃。

serial关键字也可以设置为百分比,这个百分比是基于play中所有主机的总数来决定每次滚动更新时的批次大小。不管你设置的百分比是多少,每批处理的主机数至少为1,最多是总主机数的百分比大小。这样,你就能根据总主机数动态调整每批次更新的数量了,关于这一点,我们下一节再聊。