索引目录
首先简单说明一下playbook,playbook是什么呢?根本上说playbook和shell脚本没有任何的区别,playbook就像shell一样,也是把一堆的命令组合起来,然后加入对应条件判断等等,在shell脚本中是一条一条的命令,而在playbook中是一个一个的task任务构成,每个task任务可以看做shell中的一条命令;shell脚本一般只是在当前服务器上执行,而playbook则是在不止一个服务器上执行,因此playbook需要在其中指定运行该playbook的服务器名。
playbook的语法结构
playbook使用yml标记语言,这是一种标记语言,这种标记语言在文件的最开始需要使用三个“-”来说明文件开始,然后使用缩进来说明代码块的范围。下面通过一个简易的实例,来说明playbook的语法。【实例来自官方文档】
--- #标记文件的开始 - hosts: webservers #指定该playbook在哪个服务器上执行 vars: #表示下面是定义的变量, http_port: 80 #变量的形式,key: value,这里http_port是变量名,80是值 max_clients: 200 remote_user: root #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。 tasks: #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。 - name: ensure apache is at the latest version #指定该任务的名称。 yum: pkg=httpd state=latest #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。 - name: write the apache config file #每个task之间可以使用空行来做区分。 template: src=/srv/httpd.j2 dest=/etc/httpd.conf #需要说明的是缩进的意义和python中缩进的意义是一样,是来区分代码块的。
一个简单的实例: 检查MySQL的运行状态
[root@test2 playbook]# cat test.yml --- - hosts: all remote_user: root gather_facts: no #不收集对应主机的信息,这样运行会快点。 tasks: - name: check the mysql stauts service: name=mysqld state=running
运行结果如下:
[root@test2 playbook]# ansible-playbook test.yml PLAY [all] ******************************************************************** TASK: [check the mysql stauts] ************************************************ ok: [10.0.102.200] ok: [10.0.102.162] ok: [10.0.102.212] PLAY RECAP ******************************************************************** 10.0.102.162 : ok=1 changed=0 unreachable=0 failed=0 10.0.102.200 : ok=1 changed=0 unreachable=0 failed=0 10.0.102.212 : ok=1 changed=0 unreachable=0 failed=0
ansible-playbook的使用小技巧
限定主机范围执行
虽然playbook中定义了执行的主机,但是有时候我们可能仅想在定义的主机中的部分机器上执行,这时候怎么办?修改playbook中的hosts的范围,但是每次改变主机就修改一次,比较麻烦,我们可以使用--limit参数,指定该playbook在指定的主机上执行。有以下inventory文件,我们想在dbservers上执行上面测试用的playbook内容。
[all] 10.0.102.212 10.0.102.200 10.0.102.162 [dbservers] 10.0.102.162
上面测试的playbook中hosts定义all,我们想仅在dbservers上执行。
[root@test2 playbook]# ansible-playbook test.yml --limit dbservers PLAY [all] ******************************************************************** TASK: [check the mysql stauts] ************************************************ ok: [10.0.102.162] PLAY RECAP ******************************************************************** 10.0.102.162 : ok=1 changed=0 unreachable=0 failed=0 [root@test2 playbook]#
查看当前playbook在哪些主机上执行
[root@test2 playbook]# ansible-playbook test.yml --list-hosts playbook: test.yml play #1 (all): host count=3 10.0.102.162 10.0.102.212 10.0.102.200
ansible-playbook的一些其他技巧
- --inventory=path,指定inventory文件,默认是在/etc/ansible/hosts下面。
- --verbose,显示详细的输出,使用-vvvv显示精确到每分钟的输出。
- --extra-vars=vars:定义在playbook使用的变量。
- --forks:指定并发的线程数,默认是5.
- --connection=type:指定远程连接主机的方式,默认是ssh,设置为local时,则只在本地执行playbook、
- --check:检测模式,playbook中定义的所有任务将在每台主机上检测,但是并不执行。
ansibleplaybook中的handlers
在系统中,我们修改了服务器的配置文件,这时候就需要重启操作服务,就可以使用到handlers。
handlers: #下面定义了两个handlers - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted - name: template configuration file template: src=template.j2 dest=/etc/foo.conf #修改了配置文件然后依次启动memcached和apache服务。 notify: #使用notify来声明引用handlers。 - restart memcached - restart apache
在使用handlers时需要注意以下几点:
- Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。
- Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers.
- 如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。
变量
这个变量我们来说明ansible中变量(不包含role中的变量)用法。
playbook中的变量
在运行playbook的时候使用--extra-vars来指定变量
有如下playbook脚本:
--- - hosts: all remote_user: root gather_facts: no tasks: - name: test playbook variables command: echo { { test_var }} #打印出变量test_var的值。