ansible-playbook实战:为多台服务器批量安装zabbix-agent
1. 前言
在2021年的当下,Ansible得益于自身配置简单功能丰富等优点,已经是一个很流行的自动化运维工具了。
而在笔者日常的工作场景中,当首选方案企业版蓝鲸系统作业平台处于维护状态或者是不可用时,会使用ansible作为自动化部署的备用方案。
今天来简单假设一个需求,为多台服务器批量安装zabbix-agent,通过这个过程介绍一下ansible-playbook的使用和编排方法。
我会假设你已经成功安装好了ansible,并且掌握ansible的基本使用方法。如果你没有,这里有个好东西: Installation Guide。
2. 实验环境准备
2.1 拓扑图
2.2 主机列表
用于测试的ansible inventory文件test_server_list.txt
内容如下:
1 | [test_server] |
2.3 用ansible ping 验证ssh登录
使用配置好的RSA密钥去测试ansible到各个测试服务器的连接情况:
1 | ansible -i test_server_list.txt test_server --key-file=~/.ssh/id_rsa -m ping |
理想状态下,会得到返回:
1 | 192.168.0.211 | SUCCESS => { |
3. ansible without playbook
这是一个不优雅的方案。
假设你已经准备好了一个zabbix-agent安装脚本,类似这样的:
1 |
|
那要通过ansible调用也很简单:大概是这个流程,我只是随手一写,没有实际试过,因为这个不是重点 ;-)
1 | ansible -i test_server_list.txt test_server -m script -a '/data/my_ansible/scripts/centos-install-zabbix-agent.sh' |
如无意外,这个方案也是能成功的, 在这个部署思路下,我们再看看如何用ansible-playbook实现。
4. ansible with playbook
As you may have noticed,我在前言部分提到了“编排”这个词。
ansible-playbook最大的特点,就是能把各种运维场景中常用的操作,都整合成了众多可以直接调用的标准模块。而在编写playbook之前,我们需要提前拟出一个方案,把我们的需求划分成多个清晰的步骤。
下面我们从易到难,一步一步引入各个功能。
4.1 编写playbook
4.1.1 部署任务分析
回到我们的主题,当我要在服务器上面部署zabbix-agent,简单来说可以分成下面几个步骤:
- 安装zabbix的repo
- 使用yum安装zabbix-agent
- 设置开机启动zabbix-agent
- 根据环境修改zabbix-agent的配置文件
- 启动zabbix-agent
4.1.2 示例ansible-playbook
根据上文提到的各个步骤,我们便可以编写出一个纯粹的playbook。
1 | - name: install zabbix agent |
在上面的yaml文件中,使用了以下几个ansible模块:
yum: 提供yum管理工具的功能,在本例中通过yum模块添加了zabbix的repo,并使用yum完成了zabbix-agent的安装。
systemd: 用于管理systemd中的daemon。
template: 提供配置文件的模板渲染功能。
4.1.3 准备配置模板
熟悉zabbix监控的人都知道,zabbix-agent有主动和被动两种模式。当我们使用主动模式的时候,zabbix-agent会主动向zabbix-server上报监控数据。为了实现这个功能,需要提前在zabbix-agent的配置文件中加入ServerActive
和Hostname
两个配置项,前者会告诉zabbix-agent把监控数据上报到哪里,后者需要和zabbix-server的配置页面中Configuration -> Hosts所添加的服务器信息中的Host name
配置项一致。
也就是说,我们需要对这两个配置项进行可变的配置,尤其是Hostname
配置项,往往每台服务器都不一样。在这里,我要对每台服务器的Hostname
配置项填入该服务器的内网IP地址。
为了满足这个需求,在上面的playbook中,使用了template功能。配置模板如下:
1 | PidFile=/var/run/zabbix/zabbix_agentd.pid |
当playbook运行的时候,template中的变量会被渲染成具体的内容,再复制到目标路径中。在本例中,使用了zabbix_server_ip
和zabbix_server_port
两个自定义变量,至于另一个变量ansible_eth0.ipv4.address
最后会赋值为目标服务器上的内网IP。
4.1.4 触发运行handler
我们会看到,在上面的playbook示例的末尾,有一个handlers区段,同时,在task里面包含一个notify关键字。
Ansible的一个重要特征是幂等性(idempotent),意思是我们可以对服务器重复执行同一个任务多次,效果都是相同的。也就是说,当我们即将要进行一次批量部署的时候,或者是因为出错而重新运行部署任务的时候,我们都不用担心会有潜在隐患。
在任务执行过程中,当ansible识别到这个task任务使系统发生了变更,就会通知task中指定的handler,进而触发在handler中配置的操作。
在本例中,ansible只会在检测到zabbix-agent的配置文件被修改后,才会通知handler去重启zabbix-agent,使配置生效。反过来说,在重复执行这个playbook的时候,如果ansible发现服务器的zabbix-agent配置文件没有发生变更,则不会重启zabbix-agent。
4.2 运行前检查
经过上面的一顿操作猛如虎,我们已经万事俱备,就欠一句执行命令了。
总结一下,现在的playbook文件编排如下:
1 | ./playbooks/ |
4.2.1 检查playbook语法
一般来说,在执行之前,都会先进行一次语法检查:
1 | ansible-playbook -i playbooks/test_server_list.txt --syntax-check playbooks/install-zabbix-agent.yml |
4.2.2 检查主机列表
查看会有哪些服务器会执行这一次的任务:
1 | ansible-playbook -i playbooks/test_server_list.txt --list-tasks playbooks/install-zabbix-agent.yml |
4.2.3 试运行playbook(演习模式)
加入--check
参数后,ansible会模拟一次playbook的执行并返回各个任务的执行状态,但不会对hosts执行任何实际的修改:
1 | ansible-playbook -i playbooks/test_server_list.txt --key-file=~/.ssh/id_rsa --check playbooks/install-zabbix-agent.yml |
4.3 运行playbook
执行命令:
1 | ansible-playbook -i playbooks/test_server_list.txt --key-file=~/.ssh/id_rsa playbooks/install-zabbix-agent.yml |
输出结果节选如下:
1 | # ansible-playbook -i playbooks/test_server_list.txt --key-file=~/.ssh/id_rsa playbooks/install-zabbix-agent.yml |
可以看到,在ansible的带领下,目标服务器192.168.0.211
按照playbook中定义的顺序,顺利完成了zabbix-agent的安装。
5. 总结
实不相瞒,在笔者最初接触ansible的时候,使用的就是不优雅的方案。因为没有完成思维的转变,只把ansible当作一个批量跑脚本的工具。直到后来接触的服务种类多了,维护的部署脚本以及相应的配置文件变多了之后,才意识到ansible-playbook的香。
而且,使用ansible-playbook还有助于我们养成一个先把任务捋顺了再去编写过程的习惯,比起打开一个shell脚本疯狂输出,成竹在胸地去编写playbook文件是一件优雅得多的事情。更让人欣慰的是,ansible-playbook中的yaml格式比起零零碎碎的shell脚本,更显得赏心悦目(可读性更强)。
然而,ansible-playbook的玩法可不止于此,后面我会介绍更复杂的运维场景,看看如何继续挖掘ansible-playbook的潜力。