说明:这篇文章依赖上一篇的环境html
http://ximenfeibing.blog.51cto.com/8809812/1669162node
Playbook是使用yaml语言定制的,YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其余多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy dt Net与Oren Ben-Kiki也是这语言的共同设计者。mysql
- host: websrvs #定义执行的主机 remote_user: root #定义执行的用户 tasks: #定义任务 - task1 #定义第一个任务名称 module_name: module_args #定义使用的模块,和模块参数 - task 2 #定义第二个任务名称
定义一个yml:对webserver组中的主机,调用group和user模块建立组和用户;对dbserver组中的主机调用copy模块复制文件。linux
执行ymlnginx
执行第二遍,返回的全部结果为ok不是表示执行ok而是全部条件都知足web
搭建一个apache环境sql
准备须要复制到被管理主机的httpd.conf配置文件,修改监听端口为8080
shell
[root@node1 ~]# mkdir conf [root@node1 ~]# cp /etc/httpd/conf /httpd.conf conf/ [root@node1 ~]# vim conf/httpd.conf Listen 8080
应用以前先中止webserver组中的httpd服务,并卸载数据库
[root@node1 ~]# ansible webserver -a 'service httpd stop' [root@node1 ~]# ansible websrvs -m yum -a 'name=httpd state=absent'
执行:apache
验证:httpd软件包已经安装,服务开机自动启动,并且也监听8080端口
[root@node2 ~]# rpm -qa httpd httpd-2.2.15-39.el6.centos.x86_64 [root@node2 ~]# chkconfig --list httpd httpd 0:off1:off2:on3:on4:on5:on6:off [root@node2 ~]# netstat -lntp | grep 8080 tcp 0 0 :::8080 :::* LISTEN 40826/httpd
收集被管理主机的信息时,会返回不少变量,这里就是调用了返回的ipv4地址变量
示例:将客户端返回的ip地址,建立webserver组中主机的/tmp/test.ans文件。
执行结果以下:
验证:使用的变量名同样,可是生成的内容倒是被管理主机的ip地址
[root@node2 ~]# cat /tmp/test.ans [u'172.16.4.101'] [root@node3 ~]# cat /tmp/test.ans [u'172.16.4.102']
示例:对webserver组中的主机,定义testvar变量,值为ip地址后两位
[root@node1 ~]# vim /etc/ansible/hosts [webserver] 172.16.4.101 testvar="4.101" 172.16.4.102 testvar="4.102" [dbserver] 172.16.4.103
设置yml文件,和使用其余变量同样的方法调用变量:
执行yml
验证:相同变量,不一样主机获得了不一样的值
[root@node2 ~]# cat /tmp/test.ans [u'172.16.4.101'],4.101 [root@node3 ~]# cat /tmp/test.ans [u'172.16.4.102'],4.102
示例:使用变量指定httpd.conf配置文件中一些参数的值
定义配置文件中使用的变量
[root@node1 ~]# vim temolastes/httpd.conf.j2 <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients {{ maxClients }} MaxRequestsPerChild 4000 </IfModule> Listen {{ http_port }} ServerName {{ ansible_fqdn }}
修改Ansible的hosts文件定义主机变量
[root@node1 ~]# vim /etc/ansible/hosts [webserver] 172.16.4.101 http_port=80 maxClients=100 172.16.4.102 http_port=8080 maxClients=200 [dbserver] 172.16.4.103
定义yml:定义的过程当中使用变量,根据不一样主机定义的值不一样,生成的配置文件参数也不一样
执行过程
验证:相同的playbook因为对hosts指定的变量不一样,因此生成不一样的配置文件
node2: <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 100 MaxRequestsPerChild 4000 </IfModule> Listen 80 ServerName node2 node3: <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 200 MaxRequestsPerChild 4000 </IfModule> Listen 8080 ServerName node3
示例:添加用户,可是只对主机名为node2的主机添加。
执行结果以下:
当有须要重复性执行的任务时,可使用迭代机制。其使用格式为将须要迭代的内容定义为item变量引用,并经过with_items语句来指明迭代的元素列表便可。例如:
上面语句的功能等同于下面的语句:
- name: create user user: name=testuser1 - name: create user user: name=testuser2
事实上,with_items中可使用元素还可为hashes,例如:
ansible的循环机制还有更多的高级功能,具体请参见官方文档(http://docs.ansible.com/playbooks_loops.html)。
playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先经过ansible中的task定义好的角色。从根本上来说,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,便可以让它们联同起来按事先编排的机制同唱一台大戏。
playbook基础组件
playbook中的每个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,其能够是一个或多个由冒号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的
-hosts: webnodes remote_user:root
不过,remote_user也可用于各task中。也能够经过指定其经过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至能够在sudo时使用sudo_user指定sudo时切换的用户。
- hosts: webnodes remote_user: mageedu tasks: - name: test connection ping: remote_user: mageedu sudo: yes
play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的全部主机上执行,即在全部主机上完成第一个任务后再开始第二个。在运行自下而下某playbook时,若是中途发生错误,全部已执行任务都将回滚,所以,在更正playbook后从新执行一次便可。
task的目的是使用指定的参数执行模块,而在模块参数中可使用变量。模块执行是幂等的,这意味着屡次执行是安全的,由于其结果均一致。
每一个task都应该有其name,用于playbook的执行结果输出,建议其内容尽量清晰地描述任务执行步骤。若是未提供name,则action的结果将用于输出。
定义task的可使用“action:module options”或“module: options”的格式,推荐使用后者以实现向后兼容。若是action一行的内容过多,也中使用在行首使用几个空白字符进行换行。
tasks:
- name: make sure apache is running service:name=httpd state=running
在众多模块中,只有command和shell模块仅须要给定一个列表而无需使用“key=value”格式,例如:
tasks: -name: disable selinux command: /sbin/setenforce 0
若是命令或脚本的退出码不为零,可使用以下方式替代:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
ansible的主要功用在于批量主机操做,为了便捷地使用其中的部分主机,能够在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。
inventory文件遵循INI文件风格,中括号中的字符为组名。能够将同一个主机同时归并到多个不一样的组中;此外,当如若目标主机使用了非默认的SSH端口,还能够在主机名称以后使用冒号加端口号来标明。
ntp.xmfb.com [webservers] www1.xmfb.com:2222 www2.xmfb.com [dbservers] db1.xmfb.com db2.xmfb.com db3.xmfb.com
若是主机名称遵循类似的命名模式,还可使用列表的方式标识各主机,例如:
[webservers] www[01:50].example.com [databases] db-[a:f].example.com
inventory中,组还能够包含其它的组,而且也能够向组中的主机指定变量。不过,这些变量只能在ansible-playbook中使用,而ansible不支持。例如:
[apache] httpd1.xmfb.com httpd2.xmfb.com [nginx] ngx1.xmfb.com ngx2.xmfb.com [webservers:children] apache nginx [webservers:vars] ntp_server=ntp.xmfb.com
示例:定义配置文件发生修改以后,在执行yml文件,会重启httpd服务。
定义的内容:
修改配置文件的监听端口为80
[root@node1 ~]# vim conf/httpd.conf Listen 80
执行结果
验证:webserver组中的主机httpd端口更改与否
[root@node2 ~]# netstat -lntp | grep httpd tcp 0 0 :::80 :::* LISTEN 41848/httpd
tags用于让用户选择运行或路过playbook中的部分代码。ansible具备幂等性,所以会自动跳过没有变化的部分,即使如此,有些代码为测试其确实没有发生变化的时间依然会很是地长。此时,若是确信其没有变化,就能够经过tags跳过此些代码片段。
示例:将修改配置文件部分定义为tags,一旦配置文件发生改变,能够跳过安装和启动服务,只执行复制配置文件和handlers
验证:使用tags执行conf,只是出现了conf这个任务的执行
ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles可以根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只须要在playbook中使用include指令便可。简单来说,roles就是经过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并能够便捷地include它们的一种机制。角色通常用于基于主机构建服务的场景中,但也能够是用于构建守护进程等场景中。
建立role的步骤
(1)建立以roles命名的目录;
(2)在roles目录中分别建立以各角色名称命名的目录,如webservers等;
(3)在每一个角色命名的目录中分别建立files、handlers、meta、tasks、templates和vars目录;用不到的目录能够建立为空目录,也能够不建立;
(4)在playbook文件中,调用各角色;
role内各目录中可用的文件
tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可使用include包含其它的位于此目录中的task文件;
files目录:存放由copy或script等模块调用的文件;
templates目录:template模块会自动在此目录中寻找Jinja2模板文件;
handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中;
vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其之后的版本才支持;
default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;
建立相关目录
[root@node1 ~]# mkdir -pvansible_playbooks/roles/{webserver,dbserver}/{tasks,files,templates,meta,handlers,vars} [root@node1 ~]# tree ansible_playbooks/ ansible_playbooks/ └── roles ├── dbserver │ ├── files │ ├── handlers │ ├── meta │ ├── tasks │ ├── templates │ └── vars └── webserver ├── files ├── handlers ├── meta ├── tasks ├── templates └── vars 15 directories, 0 files
Webserver建立配置文件
[root@node1 ~]# cp /etc/httpd/conf/httpd.confansible_playbooks/roles/webserver/files/
在tasks目录下,定义yml,此处只须要定义执行的任务
在handlers目录下,定义handlers
在目录名同级目录,定义roles,只须要指明运行的主机和用户身份已经调用的角色便可
执行结果
示例:在4.101配置web服务,在4.102配置数据库,在4.103及配置web又配置数据库;
复制mysql配置文件
[root@node1 ~]# cp /etc/my.cnfansible_playbooks/roles/dbserver/files/
定义tasks
定义handlers
定义site.yml,在4.101配置web服务,在4.102配置数据库,在4.103及配置web又配置数据库。
执行结果: