ansible Ad-Hoc Commands

所谓 ad-hoc 命令是什么呢?

(这其实是一个概念性的名字,是相对于写 Ansible playbook 来说的.类似于在命令行敲入shell命令和 写shell scripts两者之间的关系)…

如果我们敲入一些命令去比较快的完成一些事情,而不需要将这些执行的命令特别保存下来, 这样的命令就叫做 ad-hoc 命令.

Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook.前者可以解决一些简单的任务, 后者解决较复杂的任务.

那我们会在什么情境下去使用ad-hoc 命令呢?

比如说因为圣诞节要来了,想要把所有实验室的电源关闭,我们只需要执行一行命令 就可以达成这个任务,而不需要写 playbook 来做这个任务.

至于说做配置管理或部署这种事,还是要借助 playbook 来完成,即使用 ‘/usr/bin/ansible-playbook’ 这个命令.

Parallelism and Shell Commands

1
ansible atlanta -a "/sbin/reboot" -f 10

这个命令中,atlanta是一个组,这个组里面有很多服务器,”/sbin/reboot”命令会在atlanta组下 的所有机器上执行.这里ssh-agent会fork出10个子进程(bash),以并行的方式执行reboot命令.如前所说“每次重启10个” 即是以这种方式实现:

1
$ ansible raleigh -m shell -a 'echo $TERM'

ansible有许多模块,默认是 ‘command’,也就是命令模块,我们可以通过 -m 选项来指定不同的模块.在前面所示的例子中, 因为我们是要在 Atlanta 组下的服务器中执行 reboot 命令,所以就不需要显示的用这个选项指定 ‘command’ 模块,使用 默认设定就OK了.一会在其他例子中,我们会使用 -m 运行其

使用 Ansible ad hoc 命令行接口时(与使用 Playbooks 的情况相反),尤其注意 shell 引号的规则. 比如在上面的例子中,如果使用双引号”echo $TERM”,会求出TERM变量在当前系统的值,而我们实际希望的是把这个命令传递 到其它机器执行.

File Transfer

这是 /usr/bin/ansible 的另一种用法.Ansible 能够以并行的方式同时 SCP 大量的文件到多台机器. 命令如下:

1
ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"

使用 file 模块可以做到修改文件的属主和权限,(在这里可替换为 copy 模块,是等效的):

1
2
$ ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
$ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"

使用 file 模块也可以创建目录,与执行 mkdir -p 效果类似:

1
$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"

删除目录(递归的删除)和删除文件:

1
$ ansible webservers -m file -a "dest=/path/to/c state=absent"

Managing Packages

Ansible 提供对 yum 和 apt 的支持.这里是关于 yum 的示例.

确认一个软件包已经安装,但不去升级它:

1
$ ansible webservers -m yum -a "name=acme state=present"

确认一个软件包的安装版本:

1
$ ansible webservers -m yum -a "name=acme-1.5 state=present"

确认一个软件包还没有安装:

1
$ ansible webservers -m yum -a "name=acme state=absent"

Users and Groups

使用 ‘user’ 模块可以方便的创建账户,删除账户,或是管理现有的账户:

1
2
3
$ ansible all -m user -a "name=foo password=<crypted password here>"

$ ansible all -m user -a "name=foo state=absent"

Deploying From Source Control

直接使用 git 部署 webapp:

1
2
$ ansible webservers -m git -a "repo=git://foo.example.org/repo.git dest=/srv/myapp version=HEAD"

因为Ansible 模块可通知到 change handlers ,所以当源码被更新时,我们可以告知 Ansible 这个信息,并执行指定的任务, 比如直接通过 git 部署 Perl/Python/PHP/Ruby, 部署完成后重启 apache.

Managing Services

确认某个服务在所有的webservers上都已经启动:

1
$ ansible webservers -m service -a "name=httpd state=started"

或是在所有的webservers上重启某个服务(译者注:可能是确认已重启的状态?):

1
$ ansible webservers -m service -a "name=httpd state=restarted"

确认某个服务已经停止:

1
$ ansible webservers -m service -a "name=httpd state=stopped"

Time Limited Background Operations

需要长时间运行的命令可以放到后台去,在命令开始运行后我们也可以检查运行的状态.如果运行命令后,不想获取返回的信息, 可执行如下命令:

1
$ ansible all -B 3600 -P 0 -a "/usr/bin/long_running_operation --do-stuff"

如果你确定要在命令运行后检查运行的状态,可以使用 async_status 模块.前面执行后台命令后会返回一个 job id, 将这个 id 传给 async_status 模块:

1
$ ansible web1.example.com -m async_status -a "jid=488359678239.2844"

获取状态的命令如下:

1
$ ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"

其中 -B 1800 表示最多运行30分钟, -P 60 表示每隔60秒获取一次状态信息.

Polling 获取状态信息的操作会在后台工作任务启动之后开始.若你希望所有的工作任务快速启动, –forks 这个选项的值 要设置得足够大,这是前面讲过的并发进程的个数.在运行指定的时间(由-B选项所指定)后,远程节点上的任务进程便会被终止.

一般你只能在把需要长时间运行的命令或是软件升级这样的任务放到后台去执行.对于 copy 模块来说,即使按照前面的示例想放到 后台执行文件传输,实际上并不会如你所愿.

Gathering Facts

在 playbooks 中有对于 Facts 做描述,它代表的是一个系统中已发现的变量.
These can be used to implement conditional execution of tasks but also just to get ad-hoc information about your system.
可通过如下方式查看所有的 facts:

1
$ ansible all -m setup

我们也可以对这个命令的输出做过滤,只输出特定的一些 facts,详情请参考 “setup” 模块的文档.

参考文章

评论