1.1 快速上手

这篇文章我们会快速过一下Ansible的主要功能,面向新手可能无法理解部分细节,没关系后面都会展开讲

准备环境

由于我们用Ansible是批量管理多台机器的,因此我们准备多台机器以供测试,这里均使用CentOS7系统

[root@192-168-31-106 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.31.106 node1 manager
192.168.31.100 node2 
192.168.31.101 node3 
192.168.31.102 node4 

IP配置到管理节点的/etc/hosts上不是必须的,这里仅仅为了方便

  • 106是管理节点,即安装有Ansible的节点,其它节点是被管理节点,或者称为工作节点
  • 管理节点上需要安装Ansible,安装步骤参考上一节1.0-安装
  • 管理节点需要配置,到其它机器的免密登录,详情参考 https://blog.csdn.net/xys2015/article/details/110442383

配置完成后,记得都测试下,如

ssh ${IP_OR_DOMAIN} echo hello

主机清单

被Ansible管理的机器必须写到主机清单里去(inventory file),简单的主机清单格式非常简单,直接垂直排列IP地址即可,默认的主机清单文件是/etc/ansible/hosts,下面我们修改一下填上我们要使用的IP地址

cp /etc/ansible/hosts /etc/ansible/hosts.bak #查看这个默认文件可以看到一些基础帮助
cat /etc/ansible/hosts
[myservers]
192.168.31.106:22
192.168.31.100:22
192.168.31.101:22
192.168.31.102:22
#myservers是分组名,可根据实际情况填写
#主机清单文件里,#号开头是注释

生产环境中通常把主机清单文件放到git上管理

小试牛刀 Ad-Hoc

比如我们想查看一下远程某台机器的内存使用情况,用SSH我们可以这样实现

[root@192-168-31-106 ~]# ssh 192.168.31.100 free -h

如果我们想要同时查看多台机器的内存使用情况,我们可以写脚本循环实现,这里不再赘述,我们看看Ansible如何实现类似的功能

[root@192-168-31-106 ~]# ansible all -a "free -h"
192.168.31.106 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           3.9G        2.5G        741M        9.1M        651M        1.1G
Swap:            0B          0B          0B
192.168.31.101 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           3.9G        210M        3.5G        8.5M        110M        3.5G
Swap:            0B          0B          0B
192.168.31.102 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           3.9G        210M        3.6G        8.5M        103M        3.5G
Swap:            0B          0B          0B
192.168.31.100 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           3.9G        215M        3.5G        8.5M        103M        3.5G
Swap:            0B          0B          0B

这里的all是特殊用法,表示全部写在主机清单里的机器,默认即/etc/ansible/hosts

这里的CHANGED大家理解起来可能有点奇怪,因为我们知道free -h不会改变目标机器的状态,设计良好的Ansible语法可以实现一个很重要的功能即”幂等性”,说直白点就是一个脚本可以实现一个功能,而反复执行这个脚本目标状态不会有变化,如我们写一套脚本安装nginx,可能要包含下载包,启动服务等操作,具有良好幂等性的脚本应该保证,当我重复执行这个脚本,系统能够自动检测到nginx已经在运行,从而不再执行相关的安装操作,如果没有相关背景知识大家理解这点可能比较困难,暂时可以忽略

相信大家举一反三,已经可以实现很多Ansible的玩法如下面的命令

ansible all -a "df -h"
ansible all -a "cat /etc/hosts"

有一条指令很常用,通常都是我们首次执行的

ansible all -m ping
ansible myservers -m ping #myservers是我定义的机器分组名称,大家根据情况修改

可以探测Ansible到目标机器的连通性是否正常

剧本初探 Playbook

如果我们想自动化实现某些功能,最传统的方案是写Shell脚本,来把一组命令组织起来,在Ansible里可以使用一个YAML文件,称之为playbook来把Ansible命令有序有结构的组织起来,如下我们演示如何使用Ansible在机器上配置同步时间的服务

[root@192-168-31-106 ~]# cat ntpupdate.yaml
---
- hosts: all
  tasks:
  - name: Ensure ntpdate (for time synchronization) is installed.
    yum: 
      name: ntpdate 
      state: present 
  - name: Create a cron "*/10 * * * * /usr/sbin/ntpdate -u ntp1.aliyun.com &> /dev/null"
    cron:
      name: "sync_beijing_time"
      minute: "*/10"
      job: "/usr/sbin/ntpdate -u ntp1.aliyun.com &> /dev/null"

现阶段我们测试,这个文件放在哪里都无关系

YAML对空格的要求非常严格,可以用2个空格或4格,一般都是用2个空格(官方文档的示例也是2个),可使用下面的命令检查是否有语法错误:

ansible-playbook --syntax-check ntpupdate.yaml

看一下哪些机器被该剧本管理:

ansible-playbook ntpupdate.yaml --list-hosts

实际执行命令:

ansible-playbook ntpupdate.yaml
[root@192-168-31-106 ~]# ansible-playbook ntpupdate.yaml
PLAY [all] *******************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.31.102]
ok: [192.168.31.101]
ok: [192.168.31.106]
ok: [192.168.31.100]

TASK [Ensure ntpdate (for time synchronization) is installed.] *****************************************************
ok: [192.168.31.102]
ok: [192.168.31.100]
changed: [192.168.31.101]
ok: [192.168.31.106]

TASK [Create a cron "*/10 * * * * /usr/sbin/ntpdate -u ntp1.aliyun.com &> /dev/null"] ******************************
changed: [192.168.31.102]
changed: [192.168.31.101]
changed: [192.168.31.106]
changed: [192.168.31.100]

PLAY RECAP ********************************************************************************************************
192.168.31.100             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.31.101             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.31.102             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.31.106             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

执行观察输出的内容,ansible-playbook ntpupdate.yaml可以反复多执行几次,大家得到的截图可能与我不一样

  • 绿色OK表示目标机器没有做任何修改
  • 黄色表示目标机器做了修改(不一定是真正意义上的修改)

可以任意找一台机器,检查执行结果

[root@192-168-31-100 ~]# rpm -qa | grep update
geoipupdate-2.5.0-1.el7.x86_64
[root@192-168-31-100 ~]# crontab -l
#Ansible: sync beijing time
*/10 * * * * /usr/sbin/ntpdate -u ntp1.aliyun.com &> /dev/null

相信到这里大家已经能够直观的感受到Ansible的简洁和强大,上述自动配置时间同步的任务如果用Shell脚本来编写,还是有点工作量的,并且肯定没有Ansible来的简洁,尤其是用Shell脚本实现幂等,结果可观察等这样的功能,工作量大幅度增加。上面我们用到的YUM安装、管理定时任务,这种叫做Ansible支持的模块(module),后面我们会展开讲