当管理主机到达一个量级,手动去完成一个个主机的配置是一件很痛苦和枯燥的事情。这一点在还没有出现一个很好的自动化批量管理工具之前对于运维人员而言是一个很大的痛点,并且脚本的执行效率也并不是非常高。本篇博文旨在简单介绍一个开源自动化运维工具--ansible.

一、ansible是什么?

       “Ansible is Simple IT Automation”,这是官方对于ansible的解释,即absible是一个简单的IT自动化工具。官方对于ansible这个工具的目标有如下几个:让我们自动化部署APP;自动化管理配置项;自动化的持续交付;自动化的(AWS)云服务管理。所有的这几个目标本质上来说都是在被管控的多台服务器上,执行一系列的命令而已。

二、Ansible的特性:

1模块化,调用特定的模块完成特定任务。

2、基于Python语言实现,由Paramiko,PyYAML和jinjia2三个关键模块实现;Paramiko它是一个纯Python实现的ssh协议库,实现ansible的基本工作模式是基于ssh协议通信来完成管控主机。PyYAML是Python语言支持YAML(YAML Ain't a Markup Language,YAML不是一个标记语言)实现的一个函数库,以下的playbook就是按照这种语言写成。Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全。

3、部署简单,通过ssh协议互信的基础下来完成远程管控的效果。

4、主从模式,即一台主机是管理主机,而多个主机被管控。

5、支持自定义模块。

6、支持playbook(剧本任务),剧本任务即定义一系列的任务写入后缀名为.yaml的文件来一次运行所有任务。

7、期望达到幂等性,即不论将相同的命令运行多次都可以达到相同的结果,可通过条件判断消除不具备幂等性的任务。举个例子,如mkdir命令建立一个文件之后,第二次输入相同命令时会提示文件已经存在,此时加入判断,如果要创建的目标文件夹存在则不创建,

不存在就创建。这样就可以在多次执行此命令都达到幂等性。

浅析ansible_ansible

ansible程序架构图


三、Ansible的使用

1、在一台主机上安装ansible,我以CentOS 7为例。从EPEL源下载程序包至本地

https://dl.fedoraproject.org/pub/epel/7/x86_64/a/ansible-1.9.4.1.el7.noarch.rpm

[root@ansible~]# yum -y localinstall ansible-1.9.4.1.el7.noarch.rpm

2、同被管控主机建立ssh互信。

2.1环境介绍

      我采用三台CentOS 7主机来进行ansible的介绍,分别是host1(172.16.25.71)host2(172.16

.25.72)ansible(172.16.25.74);其中主机名为ansible的主机装有ansible

2.2 ansible主机上的hosts文件中写入

 #/etc/hosts
172.16.25.71 host1
172.16.25.72 host2

2.3ansible主机上使用工具生成一对密钥,并将公钥复制到host1host2.

[root@ansible ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
1a:92:2f:55:61:01:48:54:91:ab:8c:d2:9e:98:7c:c9 root@ansible
The key's randomart p_w_picpath is:
+--[ RSA 2048]----+
|   ooo+++.       |
|    . .. .       |
|       ..        |
|     ...         |
| . oo.o S        |
|. o o+ o         |
|.=..o o          |
|o.oE .           |
|  .              |
+-----------------+
[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub host1
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@host1's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'host1'"
and check to make sure that only the key(s) you wanted were added.

[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub host2
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@host2's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'host2'"
and check to make sure that only the key(s) you wanted were added.

2.4 测试可以基于密钥连接host1和host2

[root@ansible ~]# ssh host1
Last login: Wed Mar  9 19:53:57 2016 from ansible
[root@host1 ~]# 

[root@ansible ~]# ssh host2
Last login: Wed Mar  9 19:53:57 2016 from ansible
[root@host2 ~]#


四、Ansible的简单使用

  在开始介绍ansible的基本使用之前,还需要在ansible的hosts文件中写入如下内容。

# /etc/ansible/hosts #被写入此文件的主机才可以被管控
[test]
host1
host2

  因为ansible是模块化实现,所以它依靠各种模块去实现各种任务;现在我们可以正式介绍基本模块了,先来使用ansible-doc -l来列出所有的模块来看看。另外再提一点,我们可以使用

ansible-doc -s MODULE_NAME这个命令来查看某一个模块的帮助信息。

[root@ansible ~]# ansibl-doc -l
a10_server                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices     a10_service_group             Manage A10 Networks AX/SoftAX/Thunder/vThunder devices     a10_virtual_server            Manage A10 Networks AX/SoftAX/Thunder/vThunder devices     acl                           Sets and retrieves file ACL information.                   add_host                      add a host (and alternatively a group) to the ansible-playbook in-memory inventory                        
airbrake_deployment           Notify airbrake about app deployments                      alternatives                  Manages alternative programs for common commands           apache2_module                enables/disables a module of the Apache2 webserver         apt                           Manages apt-packages                                       apt_key                       Add or remove an apt key                                   apt_repository                Add and remove APT repositories                            apt_rpm                       apt_rpm package manager                                    assemble                      Assembles a configuration file from fragments              assert                        Fail with custom message                                   at                            Schedule the execution of a command or script file via the at command.                                    
authorized_key                Adds or removes an SSH authorized key                      azure                         create or terminate a virtual machine in azure             bigip_facts                   Collect facts from F5 BIG-IP devices                       bigip_monitor_http            Manages F5 BIG-IP LTM http monitors                        bigip_monitor_tcp             Manages F5 BIG-IP LTM tcp monitors                         bigip_node                    Manages F5 BIG-IP LTM nodes                                bigip_pool                    Manages F5 BIG-IP LTM pools                                bigip_pool_member             Manages F5 BIG-IP LTM pool members                         bigpanda                      Notify BigPanda about deployments      

[root@ansible ~]# ansible-doc -s at
less 458 (POSIX regular expressions)
Copyright (C) 1984-2012 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
- name: S c h e d u l e   t h e   e x e c u t i o n   o f   a   c o m m a n d   o r   s c r i p t   f i l e   v i a   t h e   a t   c o m m 
  action: at
      command                # A command to be executed in the future.
      count=                 # The count of units in the future to execute the command or script file.
      script_file            # An existing script file to be executed in the future.
      state                  # The state dictates if the command or script file should be evaluated as present(added) or absent(deleted).
      unique                 # If a matching job is present a new job will not be added.
      units=                 # The type of units in the future to execute the command or script file.
(END)

  ansible的模块有很多,基本使用格式如下ansible <host-pattern> [-f forks] [-m module_name] [-a args],其中host-pattern指的是主机列表,可以使用global风格的通配方式来指出;-m module_name指出要使用的模块,-a args指出要使用的模块的一些使用参数。


1、command:默认模块,可省略,仅发送命令。但不可通过管道的方式发送命令

[root@ansible ~]# ansible test -m command -a 'ifconfig'
host1 | success | rc=0 >>
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.25.71  netmask 255.255.0.0  broadcast 172.16.255.255
        inet6 fe80::20c:29ff:feac:df9c  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:ac:df:9c  txqueuelen 1000  (Ethernet)
        RX packets 347169  bytes 25411280 (24.2 MiB)
        RX errors 0  dropped 178  overruns 0  frame 0
        TX packets 18238  bytes 1668202 (1.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 2088  bytes 166204 (162.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2088  bytes 166204 (162.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

host2 | success | rc=0 >>
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.25.72  netmask 255.255.0.0  broadcast 172.16.255.255
        inet6 fe80::20c:29ff:fe21:5a02  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:21:5a:02  txqueuelen 1000  (Ethernet)
        RX packets 345740  bytes 25207965 (24.0 MiB)
        RX errors 0  dropped 178  overruns 0  frame 0
        TX packets 17311  bytes 1501437 (1.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 2008  bytes 159712 (155.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2008  bytes 159712 (155.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2、user:创建用户或删除用户

-a 'name= state={present|absent} remove={yes|no} system= uid= shell= home='

其中state=present是创建用户,state=absent是删除用户,remove=yes删除家目录

# 添加一个用户
[root@ansible ~]# ansible test -m user -a 'name=test state=present uid=5000 shell=/bin/bash home=/home/test'
host1 | success >> {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 5000, 
    "home": "/home/test", 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 5000
}

host2 | success >> {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 5000, 
    "home": "/home/test", 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 5000
}

# 删除用户,并删除家目录
[root@ansible ~]# ansible test -m user -a 'name=test state=absent remove=yes'
host2 | success >> {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent"
}

host1 | success >> {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent"
}

3、group:创建或者删除用户组

-a 'name= state={present|absent} gid=  system= '

[root@ansible ~]# ansible test -m group -a 'name=test gid=5000 state=present'
host2 | success >> {
    "changed": true, 
    "gid": 5000, 
    "name": "test", 
    "state": "present", 
    "system": false
}

host1 | success >> {
    "changed": true, 
    "gid": 5000, 
    "name": "test", 
    "state": "present", 
    "system": false
}

[root@ansible ~]# ansible test -m group -a 'name=test gid=5000 state=absent'
host1 | success >> {
    "changed": true, 
    "name": "test", 
    "state": "absent"
}

host2 | success >> {
    "changed": true, 
    "name": "test", 
    "state": "absent"
}

4、cron: 添加和删除周期性计划

-a 'name= state= minute= hour= day= month= weekday= job='

name= 此项必须指出,靠此项来删除管理

[root@ansible ~]# ansible test -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 172.16.0.1 &> /dev/null' name='sync time'"
host2 | success >> {
    "changed": true, 
    "jobs": [
        "sync time"
    ]
}

host1 | success >> {
    "changed": true, 
    "jobs": [
        "sync time"
    ]
}

[root@ansible ~]# ansible test -a 'crontab -l'
host1 | success | rc=0 >>
#Ansible: sync time
*/5 * * * * /usr/sbin/ntpdate 172.16.0.1 &> /dev/null

host2 | success | rc=0 >>
#Ansible: sync time
*/5 * * * * /usr/sbin/ntpdate 172.16.0.1 &> /dev/null

# 删除一个计划任务
[root@ansible ~]# ansible test -m cron -a 'state=absent name="sync time"'
host1 | success >> {
    "changed": true, 
    "jobs": []
}

host2 | success >> {
    "changed": true, 
    "jobs": []
}

5、ping 探测主机是否在线

[root@ansible ~]# ansible test -m ping
host1 | success >> {
    "changed": false, 
    "ping": "pong"
}

host2 | success >> {
    "changed": false, 
    "ping": "pong"
}

6、file 更改远程主机文件的属性

-a 'path= mode= owner= group= state={file|directory|link|hard|touch|absent} src= '

若为链接文件则src指明链接知何处

[root@ansible ~]# ansible test -a 'ls -l /tmp/test'
host1 | success | rc=0 >>
-rw-r--r--. 1 root root 0 Mar  9 20:54 /tmp/test

host2 | success | rc=0 >>
-rw-r--r--. 1 root root 0 Mar  9 20:53 /tmp/test

[root@ansible ~]# ansible test -m file -a 'path=/tmp/test owner=fly group=fly mode=0644 state=file'
host2 | success >> {
    "changed": true, 
    "gid": 1000, 
    "group": "fly", 
    "mode": "0644", 
    "owner": "fly", 
    "path": "/tmp/test", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1000
}

host1 | success >> {
    "changed": true, 
    "gid": 1000, 
    "group": "fly", 
    "mode": "0644", 
    "owner": "fly", 
    "path": "/tmp/test", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1000
}

# 增加链接文件

[root@ansible ~]# ansible test -m file -a 'path=/tmp/testlink state=link src=/tmp/test'
host2 | success >> {
    "changed": true, 
    "dest": "/tmp/testlink", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 9, 
    "src": "/tmp/test", 
    "state": "link", 
    "uid": 0
}

host1 | success >> {
    "changed": true, 
    "dest": "/tmp/testlink", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 9, 
    "src": "/tmp/test", 
    "state": "link", 
    "uid": 0
}

[root@ansible ~]# ansible test -a 'ls -l /tmp/testlink'
host2 | success | rc=0 >>
lrwxrwxrwx. 1 root root 9 Mar  9 20:59 /tmp/testlink -> /tmp/test

host1 | success | rc=0 >>
lrwxrwxrwx. 1 root root 9 Mar  9 20:59 /tmp/testlink -> /tmp/test

7、copy 把管理端的文件给被管控主机都复制一份文件(通常用于复制配置文件)

-a 'dest= src= content= owner= group= mode='

[root@ansible ~]# ansible test -m copy -a 'src=/root/file_for_copy dest=/tmp owner=root group=root mode=0644'
host1 | success >> {
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/file_for_copy", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1457528584.38-152003395414429/source", 
    "state": "file", 
    "uid": 0
}

host2 | success >> {
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/file_for_copy", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1457528584.42-247271880750250/source", 
    "state": "file", 
    "uid": 0
}

# content是指将指定内容写入文件并复制过去。
[root@ansible ~]# ansible test -m copy -a 'content="hello ansible" dest=/tmp/test owner=root group=root mode=0644'
host2 | success >> {
    "changed": true, 
    "checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f", 
    "dest": "/tmp/test", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "37bc018071eae9a0e879c31b2f9aa554", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1457528652.8-204214907282859/source", 
    "state": "file", 
    "uid": 0
}

host1 | success >> {
    "changed": true, 
    "checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f", 
    "dest": "/tmp/test", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "37bc018071eae9a0e879c31b2f9aa554", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1457528652.84-119899540486523/source", 
    "state": "file", 
    "uid": 0
}

[root@ansible ~]# ansible test -a 'cat /tmp/test'
host2 | success | rc=0 >>
hello ansible

host1 | success | rc=0 >>
hello ansible

8、yum

-a 'name= conf_file= state={present|lastest|absent} enablerepo= disablerepo= update-cache'

conf_file= 指明启用的yum配置文件路径

# 安装程序
[root@ansible ~]# ansible test -m yum -a 'name=zsh state=present'
host1 | success >> {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-7.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch              Version                 Repository       Size\n================================================================================\nInstalling:\n zsh            x86_64            5.0.2-7.el7             base            2.4 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.4 M\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : zsh-5.0.2-7.el7.x86_64                                       1/1 \n  Verifying  : zsh-5.0.2-7.el7.x86_64                                       1/1 \n\nInstalled:\n  zsh.x86_64 0:5.0.2-7.el7                                                      \n\nComplete!\n"
    ]
}

host2 | success >> {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-7.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch              Version                 Repository       Size\n================================================================================\nInstalling:\n zsh            x86_64            5.0.2-7.el7             base            2.4 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.4 M\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : zsh-5.0.2-7.el7.x86_64                                       1/1 \n  Verifying  : zsh-5.0.2-7.el7.x86_64                                       1/1 \n\nInstalled:\n  zsh.x86_64 0:5.0.2-7.el7                                                      \n\nComplete!\n"
    ]
}

# 卸载程序
[root@ansible ~]# ansible test -m yum -a 'name=zsh state=absent'
host2 | success >> {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-7.el7 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch              Version                Repository        Size\n================================================================================\nRemoving:\n zsh            x86_64            5.0.2-7.el7            @base            5.6 M\n\nTransaction Summary\n================================================================================\nRemove  1 Package\n\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Erasing    : zsh-5.0.2-7.el7.x86_64                                       1/1 \n  Verifying  : zsh-5.0.2-7.el7.x86_64                                       1/1 \n\nRemoved:\n  zsh.x86_64 0:5.0.2-7.el7                                                      \n\nComplete!\n"
    ]
}

host1 | success >> {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-7.el7 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch              Version                Repository        Size\n================================================================================\nRemoving:\n zsh            x86_64            5.0.2-7.el7            @base            5.6 M\n\nTransaction Summary\n================================================================================\nRemove  1 Package\n\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Erasing    : zsh-5.0.2-7.el7.x86_64                                       1/1 \n  Verifying  : zsh-5.0.2-7.el7.x86_64                                       1/1 \n\nRemoved:\n  zsh.x86_64 0:5.0.2-7.el7                                                      \n\nComplete!\n"
    ]
}

9、service

-a 'name= state={started|stopped|restarted} enabled={true|false} runlevel='

[root@ansible ~]# ansible test -m service -a 'state=restarted name=network'
host2 | success >> {
    "changed": true, 
    "name": "network", 
    "state": "started"
}

host1 | success >> {
    "changed": true, 
    "name": "network", 
    "state": "started"
}

10、shell 运行shell命令

与command不同之处在于,shell是新起一个子shell进程来运行命令;因此支持管道

11、script 可以指定本地的脚本文件,而后复制到被管控主机执行一遍

-a '/PATH/TO/SCTIPT'

[root@ansible ~]# ansible test -m script -a '/root/test.sh'
host2 | success >> {
    "changed": true, 
    "rc": 0, 
    "stderr": "OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to host2 closed.\r\n", 
    "stdout": "hello ansible\r\n"
}

host1 | success >> {
    "changed": true, 
    "rc": 0, 
    "stderr": "OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to host1 closed.\r\n", 
    "stdout": "hello ansible\r\n"
}

12、setup 手动收集指定被管控主机的facts变量信息,用于自定义ansible的配置文件脚本。实现批处理,多次执行。

[root@ansible ~]# ansible test -m setup -a 'filter=ansible_user_*'
host1 | success >> {
    "ansible_facts": {
        "ansible_user_dir": "/root", 
        "ansible_user_gecos": "root", 
        "ansible_user_gid": 0, 
        "ansible_user_id": "root", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 0
    }, 
    "changed": false
}

host2 | success >> {
    "ansible_facts": {
        "ansible_user_dir": "/root", 
        "ansible_user_gecos": "root", 
        "ansible_user_gid": 0, 
        "ansible_user_id": "root", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 0
    }, 
    "changed": false
}


  至此,关于ansible的简单用法已经有了了解。关于ansible的更强大的功能,限于篇幅,在此篇博文不给出,诸如playbook剧本任务实现一系列任务等,将在另一篇博文给出用法。