ansible系列6 Ad-hoc与commands模块

2018-09-26 20:11:01  浏览:1340  作者:管理员

Ad-Hoc 是指ansible下临时执行的一条命令,并且不需要保存的命令,对于复杂的命令后面会说playbook。讲到Ad-hoc 就要提到模块,所有的命令执行都要依赖于事先写好的模块,默认安装好的ansible 里面已经自带了很多模块,如:command、raw、shell、file、cron等,具体可以通过ansible-doc -l 进行查看 。


一、Ad-hoc 

1、直接执行


这里还是先来一个上几篇幅经常用到的一个例子:


[root@linuxbaodian ~]# ansible 10.212.52.252 -a 'uptime' -k
SSH password:
.212.52.252 | success | rc=0 >>
:10am  up 27 days 19:33,  2 users,  load average: 0.39, 0.34, 0.33

一个ad-hoc命令的执行,需要按以下格式进行执行:

ansible 主机或组  -m 模块名 -a '模块参数'  ansible参数

主机和组,是在/etc/ansible/hosts 里进行指定的部分,当然动态Inventory 使用的是脚本从外部应用里获取的主机,这部分具体可以参考:Dynamic Inventory ;

模块名,可以通过ansible-doc -l 查看目前安装的模块,默认不指定时,使用的是command模块,具体可以查看/etc/ansible/ansible.cfg 的“#module_name = command ” 部分,默认模块可以在该配置文件中进行修改;

模块参数,可以通过 “ansible-doc 模块名” 查看具体的用法及后面的参数;

ansible参数,可以通过ansible命令的帮忙信息里查看到,这里有很多参数可以供选择,如是否需要输入密码、是否sudo等。

2、后台执行


当命令执行时间比较长时,也可以放到后台执行,这里会用到-B、-P参数,如下:


ansible all -B 3600 -a "/usr/bin/long_running_operation --do-stuff" \\后台执行命令 3600s,-B 表示后台执行的时间
ansible all -m async_status -a "jid=123456789"  \\检查任务的状态
ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff" \\后台执行命令最大时间是 1800s 即 30 分钟,-P 每 60s 检查下状态默认 15s

示例如下:


[root@linuxbaodian ~]# ansible 10.212.52.252 -B 3600 -P 0 -a 'watch ls'
background launch...
.212.52.252 | success >> {
    "ansible_job_id": "411650646689.13501",
    "results_file": "/root/.ansible_async/411650646689.13501",
    "started": 1
}
[root@linuxbaodian ~]# ansible 10.212.52.252 -m async_status -a 'jid=411650646689.13501'
.212.52.252 | success >> {
    "ansible_job_id": "411650646689.13501",
    "changed": false,
    "finished": 0,
    "results_file": "/root/.ansible_async/411650646689.13501",
    "started": 1
}

不指定-P或-P参数为非0时,该任务就会按-P直接的参数一直刷新下去,直到超出-B参数指定的时间或命令执行完成:


[root@linuxbaodian ~]# ansible 10.212.52.252 -B 3600  -a 'watch ls'
background launch...
.212.52.252 | success >> {
    "ansible_job_id": "397200656414.15008",
    "results_file": "/root/.ansible_async/397200656414.15008",
    "started": 1
}
.212.52.252 | success >> {
    "ansible_job_id": "397200656414.15008",
    "changed": false,
    "finished": 0,
    "results_file": "/root/.ansible_async/397200656414.15008",
    "started": 1
}
<job 397200656414.15008> polling on 10.212.52.252, 3585s remaining
…………………………………………略

二、commands模块

上面已经提到,ansbile自身已经自带了很多模块,可以通过ansible-doc -l 进行查看。这里就结合command、shell、raw、script模块了解下其用法。


上面四个模块都属于commands 类。


command模块,该模块通过-a跟上要执行的命令可以直接执行,不过命令里如果有带有如下字符部分则执行不成功 “ so variables like $HOME and operations like “<“, “>”, “|”, and “&” will not work (use the shell module if you need these features).”;

shell 模块,用法其本和command一样,不过的是其是通过/bin/sh进行执行,所以shell 模块可以执行任何命令,就像在本机执行一样,“ It is almost exactly like the command module but runs the command through a shell (/bin/sh) on the remote node.”;

raw模块,用法和shell 模块一样 ,其也可以执行任意命令,就像在本机执行一样,“Executes a low-down and dirty SSH command, not going through the module subsystem. There is no change handler support for this module. This module does not require python on the remote system”

script模块,其是将管理端的shell 在被管理主机上执行,其原理是先将shell 复制到远程主机,再在远程主机上执行,原理类似于raw模块,“This module does not require python on the remote system, much like the raw module.” 。

注:raw模块和comand、shell 模块不同的是其没有chdir、creates、removes参数,chdir参数的作用就是先切到chdir指定的目录后,再执行后面的命令,这在后面很多模块里都会有该参数 。


command模块包含如下选项: 


creates:一个文件名,当该文件存在,则该命令不执行 

free_form:要执行的linux指令 

chdir:在执行指令之前,先切换到该指定的目录 

removes:一个文件名,当该文件不存在,则该选项不执行

executable:切换shell来执行指令,该执行路径必须是一个绝对路径

command模块、raw模块、shell模块示例:


[root@linuxbaodian ~]# ansible 10.212.52.252 -m command -a 'ps auxf|grep snmp'
.212.52.252 | FAILED | rc=1 >>
ERROR: Unsupported option (BSD syntax)
********* simple selection *********  ********* selection by list *********
-A all processes                      -C by command name
-N negate selection                   -G by real group ID (supports names)
-a all w/ tty except session leaders  -U by real user ID (supports names)
-d all except session leaders         -g by session OR by effective group name
-e all processes                      -p by process ID
T  all processes on this terminal     -s processes in the sessions given
a  all w/ tty, including other users  -t by tty
g  OBSOLETE -- DO NOT USE             -u by effective user ID (supports names)
r  only running processes             U  processes for specified users
x  processes w/o controlling ttys     t  by tty
*********** output format **********  *********** long options ***********
-o,o user-defined  -f full            --Group --User --pid --cols --ppid
-j,j job control   s  signal          --group --user --sid --rows --info
-O,O preloaded -o  v  virtual memory  --cumulative --format --deselect
-l,l long          u  user-oriented   --sort --tty --forest --version
-F   extra full    X  registers       --heading --no-heading --context
                    ********* misc options *********
-V,V  show version      L  list format codes  f  ASCII art forest
-m,m,-L,-T,H  threads   S  children in sum    -y change -l format
-M,Z  security data     c  true command name  -c scheduling class
-w,w  wide output       n  numeric WCHAN,UID  -H process hierarchy
[root@linuxbaodian ~]# ansible 10.212.52.252 -m raw -a 'ps auxf|grep snmp'
.212.52.252 | success | rc=0 >>
root      5580 25.0  0.0  12876  1792 pts/2    Ss+  12:36   0:00      \_ bash -c ps auxf|grep snmp
root      5607  0.0  0.0   5720   832 pts/2    S+   12:36   0:00          \_ grep snmp
root     24364  0.0  0.0  70416  6696 ?        SNl  May15   0:22 /usr/sbin/snmpd -r -A -LF i /var/log/net-snmpd.log -p /var/run/snmpd.pid
[root@linuxbaodian ~]# ansible 10.212.52.252 -m shell -a 'ps auxf|grep snmp'
.212.52.252 | success | rc=0 >>
root      5803  0.0  0.0  11308  1308 pts/2    S+   12:36   0:00              \_ /bin/sh -c ps auxf|grep snmp
root      5805  0.0  0.0   4260   572 pts/2    S+   12:36   0:00                  \_ grep snmp
root     24364  0.0  0.0  70416  6696 ?        SNl  May15   0:22 /usr/sbin/snmpd -r -A -LF i /var/log/net-snmpd.log -p /var/run/snmpd.pid

上面的执行结果可以看到,我这里加了管道,command模块执行时出错,而使用raw模块和shell 模块都正常。


使用chdir的示例:


[root@linuxbaodian ~]# ansible 10.212.52.252 -m command -a 'chdir=/tmp/linuxbaodian touch test.file'
.212.52.252 | success | rc=0 >>
[root@linuxbaodian ~]# ansible 10.212.52.252 -m shell -a 'chdir=/tmp/linuxbaodian touch test2.file'
.212.52.252 | success | rc=0 >>
[root@linuxbaodian ~]# ansible 10.212.52.252 -m raw -a 'chdir=/tmp/linuxbaodian touch test3.file'
.212.52.252 | success | rc=0 >>

从上面执行结果来看,三个命令都执行成功了。不过通过在远程主机上查看,前两个文件被成功创建:


linux-wdh1:/tmp/linuxbaodian # ls /tmp/linuxbaodian
test.file  test2.file

使用raw模块的执行的结果文件也被正常创建了,不过不是在chdir 指定的目录,而是在当前执行用户的家目录。


linux-wdh1:~ # ls ~/test3.file
/root/test3.file

creates与removes示例:


这里我在测试主机上创建/tmp/linuxbaodian/server.txt文件,执行结果如下:


[root@linuxbaodian ~]# ansible 10.212.52.252 -a 'creates=/tmp/linuxbaodian/server.txt uptime'
.212.52.252 | success | rc=0 >>
skipped, since /tmp/linuxbaodian/server.txt exists
[root@linuxbaodian ~]# ansible 10.212.52.252 -a 'removes=/tmp/linuxbaodian/server.txt uptime'
.212.52.252 | success | rc=0 >>
:11pm  up 28 days  0:34,  2 users,  load average: 0.75, 0.46, 0.39

script模块示例:


[root@linuxbaodian ~]# cat script.sh
#!/bin/bash
df -hl
ifconfig
ps auxf|grep snmp
[root@linuxbaodian ~]# ansible 10.212.52.252 -m script -a 'scrip.sh'
.212.52.252 | FAILED => file or module does not exist: /root/scrip.sh
[root@linuxbaodian ~]# ansible 10.212.52.252 -m script -a 'script.sh'
.212.52.252 | success >> {
    "changed": true,
    "rc": 0,
    "stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\nControl socket connect(/root/.ansible/cp/ansible-ssh-10.212.52.252-22-root): Connection refused\r\ndebug1: Connecting to 10.212.52.252 [10.212.52.252] port 22.\r\ndebug1: fd 3 clearing O_NONBLOCK\r\ndebug1: Connection established.\r\ndebug1: permanently_set_uid: 0/0\r\ndebug1: identity file /root/.ssh/identity type -1\r\ndebug1: identity file /root/.ssh/identity-cert type -1\r\ndebug1: identity file /root/.ssh/id_rsa type -1\r\ndebug1: identity file /root/.ssh/id_rsa-cert type -1\r\ndebug1: identity file /root/.ssh/id_dsa type -1\r\ndebug1: identity file /root/.ssh/id_dsa-cert type -1\r\ndebug1: identity file /root/.ssh/id_ecdsa type -1\r\ndebug1: identity file /root/.ssh/id_ecdsa-cert type -1\r\ndebug1: Remote protocol version 2.0, remote software version OpenSSH_6.2\r\ndebug1: match: OpenSSH_6.2 pat OpenSSH*\r\ndebug1: Enabling compatibility mode for protocol 2.0\r\ndebug1: Local version string SSH-2.0-OpenSSH_5.3\r\ndebug1: SSH2_MSG_KEXINIT sent\r\ndebug1: SSH2_MSG_KEXINIT received\r\ndebug1: kex: server->client aes128-ctr hmac-md5 zlib@openssh.com\r\ndebug1: kex: client->server aes128-ctr hmac-md5 zlib@openssh.com\r\ndebug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent\r\ndebug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP\r\ndebug1: SSH2_MSG_KEX_DH_GEX_INIT sent\r\ndebug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY\r\ndebug1: Host '10.212.52.252' is known and matches the RSA host key.\r\ndebug1: Found key in /root/.ssh/known_hosts:1\r\ndebug1: ssh_rsa_verify: signature correct\r\ndebug1: SSH2_MSG_NEWKEYS sent\r\ndebug1: expecting SSH2_MSG_NEWKEYS\r\ndebug1: SSH2_MSG_NEWKEYS received\r\ndebug1: SSH2_MSG_SERVICE_REQUEST sent\r\ndebug1: SSH2_MSG_SERVICE_ACCEPT received\r\ndebug1: Authentications that can continue: publickey,password,keyboard-interactive\r\ndebug1: Next authentication method: keyboard-interactive\r\ndebug1: Enabling compression at level 6.\r\ndebug1: Authentication succeeded (keyboard-interactive).\r\ndebug1: setting up multiplex master socket\r\nControlSocket /root/.ansible/cp/ansible-ssh-10.212.52.252-22-root already exists, disabling multiplexing\r\ndebug1: channel 0: new [client-session]\r\ndebug1: Requesting no-more-sessions@openssh.com\r\ndebug1: Entering interactive session.\r\ndebug1: Sending environment.\r\ndebug1: Sending env.UTF-8\r\ndebug1: Sending command: LC_CTYPE=C /root/.ansible/tmp/ansible-tmp-1431924855.88-242473611260231/script.sh \r\ndebug1: client_input_channel_req: channel 0 rtype exit-status reply 0\r\ndebug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0\r\ndebug1: channel 0: free: client-session, nchannels 1\r\ndebug1: fd 1 clearing O_NONBLOCK\r\ndebug1: fd 2 clearing O_NONBLOCK\r\nConnection to 10.212.52.252 closed.\r\nTransferred: sent 1928, received 3920 bytes, in 0.1 seconds\r\nBytes per second: sent 37017.0, received 75262.7\r\ndebug1: Exit status 0\r\ndebug1: compress outgoing: raw data 537, compressed 375, factor 0.70\r\ndebug1: compress incoming: raw data 1837, compressed 1019, factor 0.55\r\n",
    "stdout": "Filesystem      Size  Used Avail Use% Mounted on\r\n/dev/sda2       9.9G  872M  8.5G  10% /\r\nudev            3.9G  128K  3.9G   1% /dev\r\ntmpfs           3.9G   76K  3.9G   1% /dev/shm\r\n/dev/sda3       5.0G  219M  4.5G   5% /boot\r\n/dev/sda8        40G   15G   23G  40% /home\r\n/dev/sda9       9.9G  5.2G  4.3G  55% /opt\r\n/dev/sda6       5.0G  2.7G  2.1G  57% /tmp\r\n/dev/sda5       9.9G  3.4G  6.0G  36% /usr\r\n/dev/sda7       9.9G  823M  8.6G   9% /var\r\neth0      Link encap:Ethernet  HWaddr 00:50:56:A8:65:7E  \r\n          inet addr:10.212.52.252  Bcast:10.212.52.255  Mask:255.255.255.0\r\n          inet6 addr: fe80::250:56ff:fea8:657e/64 Scope:Link\r\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\r\n          RX packets:24112135 errors:0 dropped:792372 overruns:0 frame:0\r\n          TX packets:10697339 errors:0 dropped:0 overruns:0 carrier:0\r\n          collisions:0 txqueuelen:1000 \r\n          RX bytes:17137233328 (16343.3 Mb)  TX bytes:13390377826 (12770.0 Mb)\r\n\r\nlo        Link encap:Local Loopback  \r\n          inet addr:127.0.0.1  Mask:255.0.0.0\r\n          inet6 addr: ::1/128 Scope:Host\r\n          UP LOOPBACK RUNNING  MTU:16436  Metric:1\r\n          RX packets:3407332 errors:0 dropped:0 overruns:0 frame:0\r\n          TX packets:3407332 errors:0 dropped:0 overruns:0 carrier:0\r\n          collisions:0 txqueuelen:0 \r\n          RX bytes:262675450 (250.5 Mb)  TX bytes:262675450 (250.5 Mb)\r\n\r\nroot     25332  0.0  0.0   4260   568 pts/2    S+   12:54   0:00          \\_ grep snmp\r\nroot     24364  0.0  0.0  70416  6696 ?        SNl  May15   0:22 /usr/sbin/snmpd -r -A -LF i /var/log/net-snmpd.log -p /var/run/snmpd.pid\r\n"
}

输出结果很多,看起来也很乱,不过查下stdout部分,这个部分是实际上执行后的结果。这里可以配合管道一起使用,可以如下使用:

[root@linuxbaodian ~]# ansible 10.212.52.252 -m script -a 'script.sh' |egrep '>>|stdout'

篇幅所限,本来想把常用模块都放在该篇来写,感觉太冗长,后面再单独分开相应的篇幅做模块的介绍。


评论区

共0条评论
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

【随机新闻】

返回顶部