无标题文章

第3章 Ansible Ad-Hoc命令集

在前面章节中,为大家介绍了掌握Ansible所必须了解的基础,如变量命名方式,facts, register,变量传递,inventory等. 如上内容是掌握Ansible的基础,请务必熟练掌握. 本章为大家介绍的是Ansible Ad-Hoc命令集。作为Ansible最常用的命令,本节内容显得尤为重要。

3.1 Ad-Hoc及其使用场景

所谓的Ad-Hoc简而言之可以称之为“临时命令”(英文中作为形容词Ad-Hoc有“特别的,临时”的含义)。大家按各自习惯称谓均可(就笔者而言平时直呼“临时操作”,Ad-Hoc实在有些拗口)。
Ad-Hoc就其功能上是相对Ansible-playbook而言,Ansible提供两种方式完成任务:
一种是Ad-Hoc命令集,即命令ansible,另外一种就是Ansible-playbook了,即命令ansible-playbook。前者更注重于解决一些简单或者平时工作中临时遇到的任务,相当于Linux系统命令行下的Shell命令,后者更适合于解决复杂或需固化下来的任务,相当于Linux系统的Shell Scripts。通常,深入Ansible是从接触Ansible-playbook后开始,灵活运用Ansible-playbook才能更好地体会到Ansible的强大所在。
具体来讲,什么样的场景下我们需要用到Ad-Hoc,什么样的情况下需要使用Ansible-playbook呢?

  • (1)需要使用Ad-Hoc的场景
    情景1:
    春节将至(好吧,写这个章节的时候,离过年已经不到半个月了),我们需要关闭所有不必要的服务器,并对所有服务器进行节前健康检查。
    情景2:
    我临时更新了Apache &Nginx的配置文件,同时需要将其分发至所有需更新该配置的Web Servers。
  • (2)需要使用Ansible-playbook的场景
    情景1:
    新购置的服务器安装完系统后需做一系列固化的初始化工作,诸如:定制防火墙策略,添加NTP时间同步配置,添加EPEL源等。
    情景2:
    业务侧每周定期对生产环境发布更新程序代码。

Ansible-playbook其实两者之间关系用急行军(Ad-Hoc)和远征军(Ansible-playbook)来形容可能更容易理解。急行军需轻装上阵,注重灵活机动; 远征军需稳扎稳打,注重长远规划。正如我们上面所讲,Ad-Hoc更注重于解决一些简单或者平时工作中临时遇到的任务,Ansible-playbook更适合于解决复杂或需固化下来的任务。后面的章节中我们会介绍大量企业实战场景,相信大家会有更深刻的体会。

3.2Ad-Hoc命令集介绍

3.1节我们介绍了Ad-Hoc的使用场景,本小节为大家介绍通过Ad-Hoc 命令集Ansible查看系统设置,通过Ad-Hoc研究Ansible的并发特性,通过Ad-Hoc研究Ansible的模块使用。磨刀不误砍柴工,开始之前做一些简单的初始化化检查,如系统时间正确与否,磁盘容量是否充足等,这些检查工作是很有必要的。


** 参考提示 **
在实际工作中,很多“诡异”问题迫使我们花费大量时间排查,最终却发现是非常简单的基础环境问题导致的,这其实还是挺常见的,不论对新手还是老鸟均是如此,谨记!
我们前面做的系统时间正确与否,磁盘容量是否充足等工作,其实Linux下是有开源工具可以帮助我们自动监控。这里也为大家推荐几款Linux下耳熟能详的监控工具,如Zabbix,Nagios,Cacti,falcon,Cat等。


3.2.1 Ad-Hoc命令集用法简介

本节我们介绍Ad-Hoc命令集用法。Ad-Hoc命令集的由/usr/bin/ansible实现。/usr/bin/ansible命令使用介绍如下。
命令用法:
ansible [options]
可用选项:

   -v, --verbose:输出更详细的执行过程信息,-vvv可得到所有执行过程信息。
   -i PATH, --inventory=PATH:指定inventory信息,默认/etc/ansible/hosts。
   -f NUM, --forks=NUM:并发线程数,默认5个线程。
   --private-key=PRIVATE_KEY_FILE:指定密钥文件。
   -m NAME, --module-name=NAME:指定执行使用的模块。
   -M DIRECTORY, --module-path=DIRECTORY:指定模块存放路径,默认/usr/share/ansible,也可以通过ANSIBLE_LIBRARY设定默认路径。
   -a 'ARGUMENTS', --args='ARGUMENTS':模块参数。
   -k, --ask-pass SSH:认证密码。
   -K, --ask-sudo-pass sudo:用户的密码(--sudo时使用)。
   -o, --one-line:标准输出至一行。
   -s, --sudo:相当于Linux系统下的sudo命令。
   -t DIRECTORY, --tree=DIRECTORY:输出信息至DIRECTORY目录下,结果文件以远程主机名命名。
   -T SECONDS, --timeout=SECONDS:指定连接远程主机的最大超时,单位是:秒。
   -B NUM, --background=NUM:后台执行命令,超NUM秒后kill正在执行的任务。
   -P NUM, --poll=NUM:定期返回后台任务进度。
   -u USERNAME, --user=USERNAME:指定远程主机以USERNAME运行命令。
   -U SUDO_USERNAME, --sudo-user=SUDO_USERNAM:E使用sudo,相当于Linux下的sudo命令。
   -c CONNECTION, --connection=CONNECTION:指定连接方式,可用选项paramiko (SSH), ssh, local。Local方式常用于crontab 和 kickstarts。
   -l SUBSET, --limit=SUBSET:指定运行主机。
   -l ~REGEX, --limit=~REGEX:指定运行主机(正则)。
   --list-hosts:列出符合条件的主机列表,不执行任何其它命令。

下面的示例有助于加深对其理解程度。
情景1:检查proxy组所有主机是否存活
执行命令:
ansible proxy –f 5 –m ping
返回结果如下如图3-1

Paste_Image.png

图3-1 ansibleping命令返回结果如下
执行结果诠释:

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

其中192.168.37.159是指命令执行的主机,Success表示命令执行成功,>> {} 表示详细返回结果如下。"changed": false表示没有对主机做变更,"ping": "pong"表示执行了ping命令返回结果为pong。

情景2:返回proxy组所有主机的hostname并打印最详细的执行过程到标准输出
执行命令:ansible proxy -s -m command -a 'hostname' -vvv
返回结果如下如图3-2所示。

无标题文章_第1张图片
Paste_Image.png

图3-2 ansiblehostname命令返回结果
执行结果诠释:

<192.168.37.159> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO 192.168.37.159  #远程主机192.168.37.159监听ROOT用户的22号端口
<192.168.37.159> REMOTE_MODULE command hostname #远程执行命令hostname
<192.168.37.159> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443 && echo $HOME/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443' #生成临时临时目录用于存放Ansible远程执行脚本
<192.168.37.159> PUT /tmp/tmp5sawsq TO /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/command #改名临时脚本并存放至临时目录
<192.168.37.159> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=urvzacjxvaagwvlrywymxpxfhjkirkqb] password: " -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-urvzacjxvaagwvlrywymxpxfhjkirkqb; LANG=C LC_CTYPE=C /usr/bin/python /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/command; rm -rf /root/.ansible/tmp/ansible-tmp-1455684626.83-94958346638443/ >/dev/null 2>&1'"'"'' #使用sudo方式并以Python脚本方式执行命令
192.168.37.159 | success | rc=0 >> #返回结果为success,CodeResult为0
Linuxlst #返回的命令返回结果如下

使用-vvv参数可以清楚了解Ansible命令执行流程,执行流程如图3-3所示。

无标题文章_第2张图片
Paste_Image.png

图3-3 Ansible命令执行流程图

情景3:列出Web组所有主机列表
执行命令:
ansible web --list
返回结果如下:

    10.3.33.21
    10.3.33.23

执行结果诠释:
--list选项列出web组所有主机列表信息,Web组中包括 10.3.33.21 和 10.3.33.23两台主机。
Ok,接下来我们模拟较为复杂的场景,
情景4:对10.21.40.61服务器以root执行sleep 20,并设置最大连接超时时长为2s,且设置为后台运行模式,执行过程每2s输出一次进度,如5s还未执行完则kill终止该任务
执行命令:time ansible 10.21.40.61 -B 5 -P 2 -T 2 -m command -a 'sleep 20' -u root(注:time命令可省,为方便观察结果这里使用time命令查看执行时长)
返回结果如图3-4所示。

无标题文章_第3张图片
Paste_Image.png

图3-4 结果返回
执行结果诠释:

第一行:[WARNING]不用理会,需升级gmp,该提醒不影响命令返回结果如下
第二行:background launch...表示使用-B使该命令后台运行
每隔2s输出一次执行进度
 polling on 10.21.40.61, 3s remaining表示执行时长剩余3s
每隔2s输出一次执行进度
 polling on 10.21.40.61, 1s remaining表示执行时长剩余1s

real    0m10.268s程序执行总时长
user    0m1.898s系统用户层执行时长
sys     0m0.163s系统内核层执行时长

** 参考提示 ** 细心的朋友会发现,我们sleep 20表示sleep 20s,即该命令最少执行时长为20s,但为什么real程序实际运行时长只有10s呢?这就是-B选项的意义了,如果超过其指定时间则kill终止正在执行的任务(但real为什么是10.268s而不是5.268s,经笔者实测,-B功能生效但时间不精确,正式使用前请多测试)


如上为Ad-Hoc命令集的用法说明,后面的章节我们会通过更复杂的实战带大家深入了解其功能。
3.2.2通过Ad-Hoc 命令集查看系统设置
上节为大家介绍了Ad-Hoc的命令集用法,本节我们通过df,free命令查看系统设置,但是是通过Ad-Hoc实现,在此过程中了解Ansible。我们模拟如下两个场景:
情景1:
批量查看apps组所有主机的磁盘容量(使用command模块)
执行命令:
ansible apps -a "df -lh"
返回结果如下:

192.168.37.130 | success | rc=0 >>
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_linuxlst-lv_root
                       19G  3.6G   14G  21% /
tmpfs                 123M     0  123M   0% /dev/shm
/dev/sda1             485M   29M  431M   7% /boot

192.168.37.155 | success | rc=0 >>
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_linuxlst-lv_root   18G  4.9G   12G  30% /
tmpfs                            144M     0  144M   0% /dev/shm
/dev/sda1                        485M   33M  427M   8% /boot

192.168.37.142 | success | rc=0 >>
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_linuxlst-lv_root   18G  5.4G   12G  33% /
tmpfs                            144M     0  144M   0% /dev/shm
/dev/sda1                        485M   33M  427M   8% /boot

192.168.37.156 | success | rc=0 >>
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_linuxlst-lv_root  8.4G  6.4G  1.6G  81% /
tmpfs                            140M     0  140M   0% /dev/shm
/dev/sda1                        485M   35M  426M   8% /boot
/dev/sdb5                         20G  3.0G   16G  16% /data2

执行结果诠释:

以192.168.37.130的返回为例,success表示命令执行成功,rc=0表示ResultCode=0即命令返回结果如下返回码为0,表示命令执行成功,>>后面跟的内容相当于在主机本地执行df –lh后的结果返回。

情景2:
批量查看远程主机内存使用情况 (shell模块)
执行命令:
ansible apps -m shell -a "free -m"
返回结果如下:

192.168.37.142 | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           286        282          4          0         34        119
-/+ buffers/cache:        128        158
Swap:         2015        668       1347

192.168.37.130 | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           244        188         56          0         30        101
-/+ buffers/cache:         56        187
Swap:         1023          0       1023

192.168.37.155 | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           286        217         69          0         84         63
-/+ buffers/cache:         68        218
Swap:         2015          0       2015

192.168.37.156 | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           279        251         28          0         29         33
-/+ buffers/cache:        188         91
Swap:         1023         22       1001

** 执行结果诠释: **
以192.168.37.142的返回为例,success表示命令执行成功,rc=0表示ResultCode=0即命令返回结果如下返回码为0,表示命令执行成功,>>后面跟的内容相当于在主机本地执行free-m后的结果返回。
通过上面两个场景的示例相信大家对Ad-Hoc的用法有一定的了解,接下来的章节我们更进一步学习Ad-Hoc的并发特性。

3.2.3通过Ad-Hoc研究Ansible的并发特性

如3.2.1章节所示,Ansible和Ansible-playbook默认会 fork 5个线程并发执行命令,但在实际工作中,如果主机数量众多,Ansible并发5个线程是远不能满足企业所需,所以本节我们带大家了解Ansible的并发特性。我们通过如下测试来更深入了解Ansible的并发工作模式。
场景如下:
我们定义[apps]组,多次执行同样的Ad-Hoc命令来查看其返回的结果
执行步骤:
步骤1定义[apps]组,编辑/etc/ansible/hosts的配置,在文件示添加如下配置:
执行命令 vi /etc/ansible/hosts键入i进行vi编辑模式跳转到文件最末尾添加如下配置

[apps]
192.168.37.130
192.168.37.155
192.168.37.142
192.168.37.156

步骤2 多次执行Ansible命令。
执行命令ansible apps -m ping -f 3
步骤3 对比返回结果。
表3-1 返回结果如下对比

无标题文章_第4张图片
Paste_Image.png

** 返回结果如下分析:**
1)同样的命令多次执行但每次的输出结果都不一定一样
2)输出结果不是按照/etc/ansible/hosts中 [apps]定义的主机按序输出。
3)结果输出基本上遵循每次输出3条记录(线程池始终保持3个线程,所以这里如果每次输出小于等于3都是正常的哦)。

OK,通过上面的实验我们对Ansible并发特性有概念性的了解,回到前面的问题,企业实际应用中,如主机数量诸多我们需调大线程数该如何操作呢?这里Ansible为我们提供了便捷的选项,如3.2.1章节所讲, -f 指定线程数,如-f 1表示并发启动一个线程,-f 10则表示同时启动10个线程并发执行命令。其实查看源码可知ansible使用multiprocessing管理多线程。


** 参考提示 ** 单台主机的性能始终有限,大家根据自己机器实际的硬件配置做调整,建议CPU核数偶数倍就好。如4Cores8GB的服务器,最大建议同时20个线程。关于Ansible的性能,后面章节会为大家介绍Ansible的加速模式


3.2.4通过Ad-Hoc研究Ansible的模块使用

前面的章节为大家详细介绍了Ad-Hoc的命令集使用方法及其它并发特性等,那Ansible究竟有多少现成功能可供大家使用呢?本节来为大家介绍Ad-Hoc的模块使用。
截止本篇编写时间(2016-02-11),官方呈现的所有可用模块约 468 个,所有模块官方也做了详尽的功能分类。明细可参考官方链接http://docs.ansible.com/ansible/modules_by_category.html。另外,Ansible也提供了类似man功能的help说明工具ansible-doc ,直接回车或 -h 显示功能用法,和Linux下系统下的man命令一样重要,正式学习Ansible模块使用前,有必要先来了解ansible-doc 用法。
命令用法:ansible-doc [options] [module...]
可用选项:

   --version:显示工具版本号。
   -h, --help:显示该help说明。
   -M MODULE_PATH, --module-path=MODULE_PATH:指定Ansible模块的默认加载目录。
   -l, --list:列出所有可用模块。
   -s, --snippet:只显示playbook说明的代码段。
   -v:等同--version显示工具版本号。

ok,下面我们看些简单的示例。
情景1:显示所有可用模块。
执行命令:
ansible-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-playboo...
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_rpmapt_rpm package manager                                      
arista_interface              Manage physical Ethernet interfaces                          
arista_l2interface            Manage layer 2 interfaces                                    
arista_lag                    Manage port channel (lag) interfaces                         
arista_vlan                   Manage VLAN resources                                        
assemble                      Assembles a configuration file from fragments
…

情景2:以yum模块为例,我们希望获取yum模块的HELP说明。
执行命令:
ansible-doc yum

> YUM
  Installs, upgrade, removes, and lists packages and groups with the
  `yum' package manager.

Options (= is mandatory):

- conf_file
        The remote yum configuration file to use for the transaction.
        [Default: None]
…

其它模块HELP说明以此类推即可,下面通过Ansible内置模块来完成一些操作。

示例1安装redhat-lsb并查看服务器系统版本号
步骤1:安装redhat-lsb
执行命令ansible apps -m yum -a 'name=redhat-lsb state=present'。返回结果如下:

192.168.37.142 | success >> {
    "changed": false, 
    "msg": "", 
    "rc": 0, 
"results": [
        "redhat-lsb-4.0-7.el6.centos.i686 providing redhat-lsb is already installed"
    ]
}
…

部分:
"changed": 主机是否有变更 true:有 false:没有 (第一次运行或事先没有安装,返回值一般是true,否则为false)
"msg":安装过程信息
"rc": 0,resultcode结果返回码,非0返回码往往是红色并且错误的返回,非常明显
步骤2查看系统版本号。
执行命令:ansible apps -m command -a 'lsb_release -a'。返回结果如下:

192.168.37.155 | success | rc=0 >>
LSB Version:    :base-4.0-ia32:base-4.0-noarch:core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: CentOS
Description:    CentOS release 6.5 (Final)
Release:        6.5
Codename:       Final
…

部分执行结果诠释:
192.168.37.155表示执行的主机,success表示命令执行成功,rc=0表示返回结果如下返回码为0 ,>>后lsb_release –a 命令返回的结果

示例2为所有服务器安装ntp服务并设置为开机启动。
步骤1:安装ntp服务
执行命令:
ansible apps -s -m yum -a "name=ntp state=present"
步骤2:启动ntp服务并设置为开机启动
执行命令:
ansible apps -m service -a "name=ntpd state=started enabled=yes"
返回的结果不再一一为大家列举出来,相信上面那么多的示例,大家对如何判断结果是否正确有准备的了解了。


** 参考提示: ** 如LINUX所有的命令用法一样,我们只能记住日常工作中最常用到的那些,另外那些不常用的命令用法我们需要知道如何快速获取他们的用法,LINUX系统为我们提供了man工具来快速获取所需。ansible-doc则等同 man 的功能和作用,这样解释相信大家会更容易理解其重要性


你可能感兴趣的:(无标题文章)