任务需求: 有一组20台server组成的应用服务器,其每台server的应用服务已经配置了开机启动,但是服务要running well,那么服务必须按照顺序启动,对于这20台需要经常reboot的server, 如何通过ansible来实现reboot顺序的管理,从而保证服务都是按照顺序start的呢?
在这里,当重启服务器的时候,按照顺序reboot服务器就成为了关键,对于这个问题,可以manually 来按照顺序进行reboot, 这是最简单的,但是也是最效率低下的,在一个“自动化运维“的大环境下,我们也需要考虑自动化的实现方式. 在网上查了不少资料,主要考虑了以下的解决方法(基于ansible): A. 创建不同的分组,然后通过分组以及分组组合进行 reboot控制. 这个也是网上资料最多的一种. 然而这个不符合我们的环境,我们这20台是独立的,如果分组,要不就是20个为一组,这样就没有什么作用 。要不就需要每个单独一组,这样就需要20组,这样用起来看起来不是很合理。 B. ansible 默认为并发工作模式,也就是同时在多台server执行task , 但是ansible也支持对并发数量的限制,当限制为1的时候,就变成按照顺序执行了,看起来符合我们的要求,然而 ansible并不会按照inventory的group中描述的先后顺序来执行task, 它是一个随机的”依次“执行,每次执行一台没有问题,但无法保证 按照期望的顺序执行. C. 创建一个shell脚本,然后ansible来调用这个shell脚本到目标机器去执行reboot, 这样shell脚本需要判断其他server的状态,才能进而在目标机器执行合理的action. 实现起来比较麻烦. 如果是200台,估计脚本都写不下去了... D. 创建一个shell脚本,然后通过shell脚本调用ansible-playbook命令实现reboot, 因为shell脚本可以按照指定的顺序依次进行action, 而ansible 可以每次都只在一台server上进行reboot,这样看起来就可以实现按照顺序进行reboot了。详细的思路如下: 1)配置一个本地的文件,按照重启的顺序将 server 写入文件,示例中的顺序是server1, server2:
代码语言:javascript复制[root@localhost ~]# cat my_reboot.lst
server1
server2
[root@localhost ~]#
2)创建shell脚本,调用ansible-playbook命令:
代码语言:javascript复制[root@localhost ~]# cat my_reboot.sh
#!/bin/bash
f_path=./my_reboot.lst
for h in `cat ${f_path}`;do
ansible-playbook -i ./my_host.ini -l $h ./my_reboot.yml
done
[root@localhost ~]#
- 测试结果如下:
[root@localhost ~]# ./my_reboot.sh
PLAY [reboot the server and wait the reboot completed.] ***********************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [server1]
TASK [command] ****************************************************************************************************************
[WARNING]: Module invocation had junk after the JSON data: Broadcast message from root@localhost.localdomain (Sun
2020-06-28 15:29:56 CST): The system is going down for reboot at Sun 2020-06-28 15:30:56 CST!
changed: [server1]
TASK [wait_for] ***************************************************************************************************************
ok: [server1 -> localhost]
PLAY RECAP ********************************************************************************************************************
server1 : ok=3 changed=1 unreachable=0 failed=0
PLAY [reboot the server and wait the reboot completed.] ***********************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [server2]
TASK [command] ****************************************************************************************************************
[WARNING]: Module invocation had junk after the JSON data: Broadcast message from root@localhost.localdomain (Sun
2020-06-28 15:31:30 CST): The system is going down for reboot at Sun 2020-06-28 15:32:30 CST!
changed: [server2]
TASK [wait_for] ***************************************************************************************************************
ok: [server2 -> localhost]
PLAY RECAP ********************************************************************************************************************
server2 : ok=3 changed=1 unreachable=0 failed=0
[root@localhost ~]#
- 用于server reboot的playbook内容如下:
[root@localhost ~]# cat my_reboot.yml
---
- name: reboot the server and wait the reboot completed.
hosts:
- all
tasks:
- shell: "shutdown -r 1"
- delegate_to: localhost
wait_for:
host: "{{ (inventory_hostname|default(ansible_host))|default(inventory_hostname) }}"
port: 22
delay: 90
timeout: 180
[root@localhost ~]#
总结:
如果要实现reboot server in sequence, 那么可以用shell脚本来调用ansible-playbook命令达到目的,如果看你到本文的您有更好的解决方法,欢迎分享
2.
而如果要实现一台服务器内的多个服务按照顺序启动,那么可以 把服务的启动顺序写成shell脚本,然后直接用ansible在远程目标机器上执行shell脚本.
3.
对于上面的shell脚本,本例只是简单的例子,如果有类似需求,自己可以根据实际情形进行扩充.