天天看点

05-Ansible模块的基本使用

一、如何使用模块

由前面的学习可知,当我们使用 ansible 完成实际任务时,需要依靠 ansible 的各个模块,比如,我们想要去 ping 某主机,则需要使用 ping 模块,命令如下:

ansible all -m ping

除了 ping 模块,ansible 还有很多模块可供我们使用。我们可以使用如下命令,查看 ansible 都有哪些模块:

[root@ansible-manager ~]# ansible-doc -l
a10_server                                           Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' server object.                                           
a10_server_axapi3                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices                                                           
a10_service_group                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' service groups.                                          
a10_virtual_server                                   Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' virtual servers.                                         
accelerate                                           Enable accelerated mode on remote node                                                                           
aci_aaa_user                                         Manage AAA users (aaa:User)                                                                                      
aci_aaa_user_certificate                             Manage AAA user certificates (aaa:UserCert)                                                                      
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:RsAccBaseGrp, infra:PortBlk)
aci_aep                                              Manage attachable Access Entity Profile (AEP) objects (infra:AttEntityP, infra:ProvAcc)                          
aci_aep_to_domain                                    Bind AEPs to Physical or Virtual Domains (infra:RsDomP)                                                          
aci_ap                                               Manage top level Application Profile (AP) objects (fv:Ap)                                                        
aci_bd                                               Manage Bridge Domains (BD) objects (fv:BD)                                                                       
aci_bd_subnet                                        Manage Subnets (fv:Subnet)                                                                                       
aci_bd_to_l3out                                      Bind Bridge Domain to L3 Out (fv:RsBDToOut)       
......
           

通过上面命令可以看到 ansible 中各个模块的名称,以及模块的大概功能。当然,通过ansible-doc -l命令获取到的模块信息比较概括,并不是特别详细,如果想要获取到各个模块更加详细的用法,可以使用ansible-doc -s命令。比如,我们想要获取 ping 模块的详细使用方法,则可以使用如下命令:

[root@ansible-manager ~]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
  ping:
      data:                  # Data to return for the `ping' return value. If this parameter is set to `crash', the module will cause an exception.
           

即使使用ansible-doc -s ping命令查看 ping 模块的描述,得到的信息也是比较少的。这是因为 ping 模块本来就比较简单,而且 ping 模块并没有太多参数可用。但是并非所有模块都像 ping 模块一样简单,有的模块在使用时必须使用参数,比如 fetch 模块,fetch 为”拿来”之意,当我们需要将被管理主机中的文件拉取到 ansible 主机时,则可以使用此模块。首先,我们可以使用ansible-doc -s fetch命令,查看一下 fetch 模块的用法:

[root@ansible-manager ~]# ansible-doc -s fetch
- name: Fetches a file from remote nodes
  fetch:
      dest:                  # (required) A directory to save the file into. For example, if the `dest' directory is `/backup' a `src' file named `/etc/profile' on host
                               `host.example.com', would be saved into `/backup/host.example.com/etc/profile'
      fail_on_missing:       # When set to 'yes', the task will fail if the remote file cannot be read for any reason.  Prior to Ansible-2.5, setting this would only fail
                               if the source file was missing. The default was changed to "yes" in Ansible-2.5.
      flat:                  # Allows you to override the default behavior of appending hostname/path/to/file to the destination.  If dest ends with '/', it will use the
                               basename of the source file, similar to the copy module. Obviously this is only handy if the filenames are
                               unique.
      src:                   # (required) The file on the remote system to fetch. This `must' be a file, not a directory. Recursive fetching may be supported in a later
                               release.
      validate_checksum:     # Verify that the source and destination checksums match after the files are fetched.
           

从帮助信息中可以看出,fetch 模块的作用就是”Fetches a file from remote nodes”,即”从被管理主机中拉取文件”之意,而且 fetch 模块提供了一些参数供我们使用,可用的参数有 dest、fail_on_missing、flat、src、validate_checksum ,而且帮助信息中注释了每个参数的作用。

比如 src 参数的作用就是指定从被管理主机中拉取哪个文件。

比如 dest 参数的作用就是指定拉取文件到本地以后文件存放的位置。

dest 参数和 src 参数的注释中都包含”(required)”字样,这表示在使用 fetch 模块时,dest 参数与 src参数是必须提供的,如果在使用 fetch 模块时,没有提供这两个参数,将会报错。想想也对,如果我们想要从远程主机中拉取文件,那么我们必须告诉 ansible,从哪里拉取文件,然后将文件存放到哪里。所以,在学习怎样使用一个模块时,要注意这些必选参数。

现在,我们就以 fetch 模块为例,看看怎样使用带有参数的模块。

首先来看一下主机清单配置:

[demoA]
ansible-demo1
[demoB]
ansible-demo2
ansible-demo3
[demo:children]
demoA
demoB
           

假如我们想要将 demoB 组中所有主机的 /testdir/testfile1 文件拉取到本地,则可以使用如下命令:

ansible demoB -m fetch -a "src=/testdir/testfile1 dest=/testdir/ansible/"

如上述命令所示,-m 选项用于调用指定的模块,”-m fetch“表示调用 fetch 模块,-a 选项用于传递模块所需要使用的参数, -a "src=/testdir/testfile1 dest=/testdir/ansible/" 表示我们在使用 fetch 模块时,为 fetch 模块传入了两个参数,src 与 dest。

我们看一下上述命令的执行效果:

从命令的执行结果可以看出,上述命令执行成功了,因为两个主机对应的返回信息都返回了”SUCCESS”字样。

为什么命令执行成功了,返回的信息却是”黄色”的,在我们的印象中,执行成功,返回的信息不应该是”绿色”的吗?这个后面我们再解释。

从返回信息可以看出,执行上述 ansible 命令后,主机 ansible-demo2 和主机 ansible-demo3 中的文件已经拉取成功,ansible-demo2 的 testfile1 文件被拷贝到了本机的 /testdir/ansible目录中,而且,ansible在 /testdir/ansible 目录中自动创建了目录结构 ansible-demo2/testdir/,由于我们是同时从多台被管理主机中拉取相同名称的文件,所以 ansible 会自动为我们创建各个主机对应的目录,以区分存放不同主机中的同名文件。是不是很方便,很人性化呢?

二、关于幂等性

在00节介绍 ansible 特点时说过,ansible 具有幂等性,幂等性能够保证我们重复的执行一项操作时,得到的结果是相同的,下面详细介绍一下幂等性的概念。

举个例子,你想把一个文件拷贝到目标主机的某个目录上,但是你不确定此目录中是否已经存在此文件,当你使用 ansible 完成这项任务时,就非常简单了,因为如果目标主机的对应目录中已经存在此文件,那么 ansible 则不会进行任何操作,如果目标主机的对应目录中并不存在此文件,ansible 就会将文件拷贝到对应目录中。说白了,ansible 是”以结果为导向的”,我们指定了一个”目标状态”,ansible 会自动判断,”当前状态”是否与”目标状态”一致,如果一致,则不进行任何操作,如果不一致,那么就将”当前状态”变成”目标状态”,这就是”幂等性”,”幂等性”可以保证我们重复的执行同一项操作时,得到的结果是一样的。

现在我们就来实验一下,看看重复执行相同的 ansible 命令时,会得到什么效果,如下图所示:

从上图可以看出,返回信息仍然包含”SUCCESS”字样,证明 ansible 命令执行成功,不过很明显,这次的返回信息为”绿色”,而且细心的你一定发现了,这次绿色的返回信息中,”changed” 字段的值为false,而之前黄色的返回信息中,”changed” 字段的值为 true。

当返回信息为绿色时,”changed” 为 false,表示 ansible 没有进行任何操作,没有”改变什么”。

当返回信息为黄色时,”changed” 为 true,表示 ansible 执行了操作,”当前状态”已经被 ansible 改变成了”目标状态”。

这就是幂等性的体现,当第一次执行上述命令时,ansible 发现当前主机中并没有我们需要的 testfile1文件,ansible 就会按照我们指定的操作,拉取 testfile1 文件,也就是说,ansible “改变”了”当前状态”,将当前”没有 testfile1 文件的状态”变为了”有 testfile1 文件的状态”。当我们再次执行同样的命令时,ansible 发现对应文件已经存在于对应目录中,于是 ansible 并没有做出任何操作,也没有进行任何改变,因为”当前状态”与我们预期的”目标状态”一致,没有必要再做出重复的无用功。

看到这里,你应该已经明白,为什么执行 ansible 命令时,会返回黄色的成功信息或者绿色的成功信息了吧?我们可以通过返回信息的颜色,更加精准的判断执行命令之前的状态是否与我们预期的一致。

从返回信息中可以看到,当 ansible 进行 fetch 操作时,会对对应文件进行哈希计算,算出文件哈希值,也就是说,如果我们改变了文件中的内容,哈希值也将随之发生改变,这个时候,即使对应目录中存在同名的文件,ansible 也会判断出两个文件属于不同的文件,因为它们的哈希值并不相同,我们来实验一下,操作如下:

如上图所示,我们在 /testdir/ansible/ansible-demo2/testdir/testfile1文件的尾部加入一个”空格”,以改变文件内容,然后又执行了 fetch 命令,结果发现,ansible-demo2 的返回信息为黄色,ansible-demo3 主机的返回信息为绿色,证明 ansible 已经做出了正确的判断,将修改过的文件替换为重新拉取的文件。

三、总结

我们对上面的一些命令进行总结,方便以后回顾:

1.列出ansible所支持的模块。

ansible-doc -l

2.查看模块的详细帮助信息,比如查看 fetch 模块的帮助。

ansible-doc -s fetch

3.调用模块,比如调用 ping模块。

ansible 192.168.128.83 -m ping

4.调用模块的同时传入模块所需要的参数,以 fetch 模块为例。

ansible 192.168.128.83 -m fetch -a "src=/testdir/testfile1 dest=/testdir/ansible/"

继续阅读