一、Ad-Hoc 执行格式
一个ad-hoc命令的执行,需要按以下格式进行执行:
ansible 主机或组-m 模块名-a '模块参数' ansible参数
主机和组:是在/etc/ansible/hosts 里进行指定的部分,当然动态Inventory使用的是脚本从外部应用里获取的主机。
模块名:可以通过ansible-doc -l 查看目前安装的模块,默认不指定时,使用的是command模块,具体可以查看/etc/ansible/ansible.cfg的"#module_name= command " 部分,默认模块可以在该配置文件中进行修改;
模块参数:可以通过"ansible-doc 模块名"查看具体的用法及后面的参数;
ansible参数:可以通过ansible命令的帮忙信息里查看到,这里有很多参数可以供选择,如是否需要输入密码、是否sudo等。
二、playbook
1、playbook简介
playbook字面意思,即剧本,现实中由演员按照剧本表演,在Ansible中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。
那么为什么要使用playbook呢?
执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行的ad-hoc命令是不适合的,这时最好使用playbook,就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
2、playbook文件的格式
playbook文件由YAML语言编写。YAML是一个类似XML、JSON的标记性语言,YAML强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称"一种人性化的数据格式语言"。首先学习了解一下YAML的格式,对后面书写playbook很有帮助。以下为playbook常用到的YAML格式。
大小写敏感
使用空格作为嵌套缩进工具,缩进时不允许使用Tab键
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
使用"-"(横线)+ 单个空格:表示单个列表项
使用":"(冒号)+ 空格:表示单个键值对
使用"{}"表示一个键值表
playbook文件是通过ansible-playbook命令进行解析的,ansbile-playbook命令会根据自上而下的顺序依次执行playbook文件中的内容。同时,playbook开创了很多特性,它可以允许传输某个命令的状态到后面的指令,它也可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得playbook可以实现一些复杂的部署机制,这是ansible命令无法实现的。
3、playbook的构成
playbook是由一个或多个"play"组成的列表。play的主要功能在于,将事先合并为一组的主机装扮成事先通过ansible定义好的角色。将多个play组织在一个playbook中就可以让它们联同起来按事先编排的机制完成一系列复杂的任务。
其主要有以下四部分构成:
target部分:定义将要执行playbook 的远程主机组
variable部分:定义playbook运行时需要使用的变量
task部分:定义将要在远程主机上执行的任务列表
handler部分:定义task 执行完成以后需要调用的任务
而其对应的目录层为五个(视情况可变化),分别为:
vars变量层
tasks 任务层
handlers 触发条件
files 文件
template 模板
4、playbook的语法详解
(1)、Hosts和Users
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
hosts:用于指定要执行指定任务的主机,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,可指定自定义主机清单的位置。在运行清单文件的时候,--list-hosts选项会显示那些主机将会参与执行任务的过程中。
remote_user:用于指定在远程主机上执行任务的用户。可以指定任意用户,也可以使用sudo,但是用户必须要有执行相应任务的权限。
(2)、任务列表(tasks list)
play的主体部分是task list。
task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自上而下某playbook时,如果中途发生错误,则所有已执行任务都将回滚,因此在更正playbook后需要重新执行一次。
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的(幂等性;即一个命令,即使执行一次或多次, 其结果也一样),这意味着多次执行是安全的,因为其结果均一致。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,建议加上去,模块是必须的,同时也要给予模块相应的参数。
定义tasks推荐使用module: options"的格式,例如:
service: name=httpdstate=running
(3)、handlers
用于当关注的资源发生变化时采取一定的操作。handlers是和"notify"配合使用的。
"notify"这个动作可用于在每个play的最后被触发,这样可以避免多次有改变发生时,每次都执行指定的操作,通过"notify",仅在所有的变化发生完成后一次性地执行指定操作。
在notify中列出的操作称为handler,也就是说notify用来调用handler中定义的操作。
注意:在notify中定义的内容一定要和handlers中定义的"-name"内容一样,这样才能达到触发的效果,否则会不生效。
(4)、tags
tags用于让用户选择运行或略过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分;但是当一个playbook任务比较多时,一个一个的判断每个部分是否发生了变化,也需要很长时间。因此,如果确定某些部分没有发生变化,就可以通过tags跳过这些代码片断。
5、Playbook执行结果解析
使用ansible-playbook运行playbook文件,输出的内容为JSON格式。并且由不同颜色组成,便于识别。一般而言,输出内容中:
绿色代表执行成功,但系统保持原样
黄色代表系统状态发生改变,也就是执行的操作生效
红色代表执行失败,会显示错误信息。
示例:
- name: create user
hosts: 172.16.213.233
user: root
gather_facts: false
vars:
- user1: "testuser"
tasks:
- name: start createuser
user: name="{{ user1 }}"
解析:
上面的playbook 实现的功能是新增一个用户:
name参数对该playbook实现的功能做一个概述,后面执行过程中,会输出name的值;
hosts参数指定了对哪些主机进行操作。
user参数指定了使用什么用户登录到远程主机进行操作。
gather_facts参数指定了在下面任务执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时需要用到。
vars参数,指定了变量,这里指字一个user1变量,其值为testuser,需要注意的是,变量值一定要用引号括起来。
tasks指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来。user是一个模块,user后面的name是user模块里的一个参数,而增加的用户名字调用了上面user1变量的值。
6、收集facts信息
facts组件是Ansible用于采集被管理机器设备信息的一个功能。可以使用setup模块查机器的所有facts信息,facts信息包括远端主机发行版,IP地址,CPU核数,系统架构,主机名等等,可以使用filter来查看指定信息。整个facts信息被包装在一个json格式的数据结构中。
[root@ansibleplaybook]# ansible 172.16.213.233 -m setup
所有数据格式都是JSON格式,facts还支持查看指定信息,如下所示:
[root@ansibleplaybook]# ansible 172.16.213.233 -m setup -a 'filter=ansible_all_ipv4_addresses'
playbook在执行的时候,默认的第一个tasks就是收集远端被管主机的facts信息,如果后面的task不会使用到setup获取的信息时,可以禁止ansible收集facts,在playbook中的hosts指令下面设置"gather_facts: false"即可。默认gather_facts的值为true。
facts经常被用在条件语句和模板当中,也可以用于根据指定的标准创建动态主机组。