知识文档


使用Ad-Hoc命令执行任务

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

如果我们敲入一些命令去比较快的完成一些事情,而不需要将这些执行的命令特别保存下来, 这样的命令就叫做 ad-hoc 命令.
Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook.前者可以解决一些简单的任务, 后者解决较复杂的任务.

Ad-Hoc的执行依赖于模块,ansible官方提供了大量的模块。 如:command、raw、shell、file、cron等,具体可以通过ansible-doc -l 进行查看 。可以使用ansible-doc -s module来查看某个模块的参数,也可以使用ansible-doc help module来查看该模块更详细的信息。

ad-hoc 命令的常用参数

$ ansible –help

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Usage: ansible <host-pattern> [options]
-a MODULE_ARGS, --args=MODULE_ARGS:指定模块参数;
-b, --become:run operations with become (nopasswd implied)
--become-user=BECOME_USER:变成BECOME_USER用户身份,不提示密码
-c CONNECTION, --connection=CONNECTION:连接类型(default=smart)
-C:只是测试一下会改变什么内容,不会真正去执行
-f FORKS, --forks=FORKS:并发线程数,默认为5个线程;
-i:指定inventory信息(default=/etc/ansible/hosts)
-k, --ask-pass:提示输入ssh登录密码,当使用密码验证的时候用
-K, --ask-become-pass:提示输入sudo密码,当不是NOPASSWD模式时使用
-l SUBSET, --limit=SUBSET:限制运行主机;
-list-host:只打印有哪些主机会执行这个命令,不会实际执行
-M MODULE_PATH, --module-path=MODULE_PATH:指定模块存放路径,默认为/usr/share/ansible;
-m MODULE_NAME, --module-name=MODULE_NAME:要执行的模块,默认为command
-o:压缩输出,摘要输出
--private-key=PRIVATE_KEY_FILE:指定密钥文件;
-u REMOTE_USER, --user=REMOTE_USER:指定远程执行的用户
-s:sudo运行
--syntax-check:对剧本进行语法检查,但不执行
-T:ssh连接超时时间,默认是10秒
-t:日志输出到该目录,日志文件名以主机命名
-v, --verbose:verbose mode (-vvv for more, -vvvv to enable:输出详细的执行过程信息,可以得到执行过程所有信息;

ansible命令执行结果色彩说明

1
2
3
绿色:表示没有发生任何改变
红色:执行命令操作出现异常
黄色:执行命令后,对受控主机产生影响,发生了配置改变

命令执行模块

命令执行模块有四个:command、raw、shell、script

command、raw

command为系统默认模块,使用时可以直接省略指定 -m command

1
2
3
[root@sltkp3cbpch ansible]# ansible all -a "pwd"
10.122.60.68 | CHANGED | rc=0 >>
/root

转换到别的目录中,执行程序,chdir为command模块自带的参数:

1
2
3
[root@sltkp3cbpch ansible]# ansible all -a "pwd chdir=/tmp"
10.122.60.68 | CHANGED | rc=0 >>
/tmp

command 不支持管道命令:$HOME和”<”, “>”, “|”, “;” and “&”
raw和command类似,两个模块都是在远程节点上面执行命令,但是raw支持管道命令

1
2
3
4
[root@sltkp3cbpch ansible]# ansible all -m raw -a "cd /tmp;pwd"
10.122.60.68 | CHANGED | rc=0 >>
/tmp
Shared connection to 10.122.60.68 closed.

shell、script

shell模块调用远程主机的指令,支持shell特性,包括执行脚本、管道命令等:

1
2
3
[root@sltkp3cbpch ansible]# ansible all -m shell -a "cd /tmp;pwd"
10.122.60.68 | CHANGED | rc=0 >>
/tmp

shell直接执行脚本,执行的脚本需要放在远程主机上

script只能执行脚本,不能调用其他指令,该模块的执行是将管理机上的脚本传送到远程节点上运行,并且script不支持管道命令。

1
[root@sltkp3cbpch ansible]# ansible all -m script -a '/etc/ansible/test.sh

几个模块中,command是默认模块,建议使用shell,功能较方便,script和shell的区别是一个执行控制端的脚本,一个执行远程端的脚本。

命令行执行的常用示例

下面简单介绍通过命令行可以对被控制端做什么,后面再深入语法学习:

Ping

检查所有的server,是否以bruce用户创建了ansible主机可以访问的环境。

1
$ansible all -m ping -u bruce

sudo

If you would like to access sudo mode, there are also flags to do that:

1
2
3
4
5
6
7
8
9
10
11
12
# as bruce
$ ansible all -m ping -u bruce
# as bruce, sudoing to root
$ ansible all -m ping -u bruce --sudo
# as bruce, sudoing to batman
$ ansible all -m ping -u bruce --sudo --sudo-user batman

# With latest version of ansible `sudo` is deprecated so use become
# as bruce, sudoing to root
$ ansible all -m ping -u bruce -b
# as bruce, sudoing to batman
$ ansible all -m ping -u bruce -b --become-user batman

执行命令

在所有的server上,以当前bash的同名用户,在远程主机执行“echo bash”

1
$ ansible all -a "/bin/echo hello"

文件传输

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

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

若你使用 playbooks, 则可以利用 template 模块来做到更进一步的事情.(请参见 module 和 playbook 的文档)
使用 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"

软件包管理

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"

对于不同平台的软件包管理工具,Ansible都有对应的模块.如果没有,你也可以使用 command 模块去安装软件. 或者最好是来为那个软件包管理工具贡献一个相应的模块.请在 mailing list 中查看相关的信息和详情.

用户和用户组

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

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

更多可用的选项请参考 模块相关 ,包括对组和组成员关系的操作.

使用git部署应用

直接使用 git 部署 webapp:

1
$ 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.

服务管理

确认某个服务在所有的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"

任务的并行执行

启动10个并行进行执行重起

1
$ ansible lb -a "/sbin/reboot" -f 10

系统信息收集

在 playbooks 中有对于 Facts 做描述,它代表的是一个系统中已发现的变量.

1
$ ansible all -m setup

我们也可以对这个命令的输出做过滤,只输出特定的一些 facts