Loading... <p>上一篇博客介绍了ansible的基础应用Modules,博客地址 http://www.178linux.com/14860 。这次介绍下Ansible的另一个核心模块Playbooks。</p> <p> </p> <p>Ansible的核心模块:</p> <p style="background: white;line-height: 28px"> Ansible core: 核心;</p> <p style="background: white;line-height: 28px"> core Modules: 包括 Ansible 自带的核心模块及自定义模块;</p> <p style="background: white;line-height: 28px"> connect Plugins: 完成模块功能的补充,包括连接插件、邮件插件等;</p> <p style="background: white;line-height: 28px"> Playbooks: 网上很多翻译为剧本,个人觉得理解为编排更为合理;定义 Ansible 多任务配置文件,由 Ansible 自动执行;</p> <p style="background: white;line-height: 28px"> host Inventory: 定义 Ansible 管理主机的清单、主机池、主机列表;</p> <p> </p> <p> Playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。<br />从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。</p> <p> ansinbl使用 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。</p> <p> </p> <p><strong><span style="font-size: 20px">YAML介绍:</span></strong></p> <p> YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。</p> <p>YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。其特性:</p> <p> YAML的可读性好<br /> YAML和脚本语言的交互性好<br /> YAML使用实现语言的数据类型<br /> YAML有一个一致的信息模型<br /> YAML易于实现<br /> YAML可以基于流来处理<br /> YAML表达能力强,扩展性好</p> <p>更多的内容及规范参见http://www.yaml.org。</p> <p> </p> <p><strong>1、YAML语法:</strong></p> <p> YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。</p> <p>Playbook组成结构:<br /> Inventory<br /> Modules<br /> Ad Hoc Commands<br /> Playbooks<br /> Tasks:任务,即调用模块完成的操作<br /> Variables:变量<br /> Templates:模板<br /> Handlers:处理器,由某个条件触发执行的操作<br /> Roles:角色<br />基本结构:<br /> – host:webservices<br /> remote_user:<br /> – tasks:<br /> – task1<br /> module_name</p> <p>YAML文件扩展名通常为.yml,如test.yml。</p> <p><strong>2、使用yaml模板文件安装httpd、提供其配置文件、配置开机启动并启动服务:</strong></p> <p>[root@master ansible]# vim apache.yml <br />– hosts: webserver<br /> remote_user: root<br /> tasks:<br /> – name: install httpd package<br /> yum: name=httpd state=latest<br /> – name: install configuration file for httpd<br /> copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf<br /> – name: start httpd service<br /> service: enabled=true name=httpd state=started</p> <p> <img title="1460689215197972.jpg" alt="apache-yml.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170046-27.jpg" /></p> <p> <img width="1033" height="264" title="1460689431775793.jpg" style="width: 1019px;height: 265px" alt="apache-yml-client.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170046-84.jpg" /></p> <p> </p> <p><strong>3、YAML语言变量:</strong></p> <p> 变量命名:变量名仅能由字母、数字和下划线组成,且只能以字母开头。</p> <p> facts变量:</p> <p> facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts,可使用如下命令进行:</p> <p> ansible hostname -m setup</p> <p> register</p> <p>把任务的输出定义为变量,然后用于其他任务,示例如下:</p> <p> tasks:<br /> – shell: /usr/bin/foo<br /> register: foo_result<br /> ignore_errors: True</p> <p>通过命令行传递变量:</p> <p> 在运行playbook的时候也可以传递一些变量供playbook使用,示例如下:</p> <p> ansible-playbook test.yml –extra-vars "hosts=webserver user=node1"</p> <p>通过roles传递变量:</p> <p> 当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量,示例如下:</p> <p> – hosts: webservers<br /> roles:<br /> – common<br /> – { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 }</p> <p>Inventory:</p> <p> ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。</p> <p> inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成。</p> <p> inventory文件格式:</p> <p> inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明。</p> <p> test.ansible.com</p> <p> [webservers]<br /> www1.mageedu.com:2222<br /> www2.mageedu.com</p> <p> [dbservers]<br /> db1.mageedu.com<br /> db2.mageedu.com<br /> db3.mageedu.com</p> <p>如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,例如:</p> <p>[webservers]<br />www[01:50].example.com</p> <p>[databases]<br />db-[a:f].example.com</p> <p>主机变量:可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用。例如:</p> <p>[webservers]<br />www1.mageedu.com http_port=80 maxRequestsPerChild=808<br />www2.mageeducom http_port=8080 maxRequestsPerChild=909</p> <p>组变量:组变量是指赋予给指定组内所有主机上的在playboo中可用的变量。例如:</p> <p>[webservers]<br />www1.mageedu.com<br />www2.mageedu.com</p> <p>[webservers:vars]<br />ntp_server=ntp.mageedu.com<br />nfs_server=nfs.mageedu.com</p> <p> </p> <p><strong>4、使用变量、模板文件安装配置apache:</strong></p> <p> <img title="1460690277729271.jpg" alt="apache-template.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170046-97.jpg" /></p> <p> <img title="1460690928476110.jpg" alt="var-apache.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170046-75.jpg" /></p> <p><strong> 5、条件测试:</strong></p> <p> 如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试。</p> <p> when语句</p> <p>在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。例如:</p> <p>tasks:<br /> – name: "shutdown Debian flavored systems"<br /> command: /sbin/shutdown -h now<br /> when: ansible_os_family == "Debian"</p> <p>when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:</p> <p>tasks:<br /> – command: /bin/false<br /> register: result<br /> ignore_errors: True<br /> – command: /bin/something<br /> when: result|failed<br /> – command: /bin/something_else<br /> when: result|success<br /> – command: /bin/still/something_else<br /> when: result|skipped</p> <p>此外,when语句中还可以使用facts或playbook中定义的变量。</p> <p><strong>6、迭代:</strong></p> <p> 当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。例如:</p> <p>调用:item<br />定义循环列表:whit_item<br /> – apache<br /> – php<br /> – mysql-server<br />注意:whit_items中的列表值也可以是字典,但引用是要使用item_KEY<br /> – {name: apache,conf: confffiles/httpd.conf}<br /> – {name: php,conf:conffiles/php.ini}<br /> – {name: mysql-servce,conf/conffiles/my.cnf}<br /> <br />– name: add several users<br /> user: name={{ item }} state=present groups=wheel<br /> with_items:<br /> – testuser1<br /> – testuser2</p> <p>上面语句的功能等同于下面的语句:</p> <p>– name: add user testuser1<br /> user: name=testuser1 state=present groups=wheel<br />– name: add user testuser2<br /> user: name=testuser2 state=present groups=wheel</p> <p>事实上,with_items中可以使用元素还可为hashes,例如:</p> <p>– name: add several users<br /> user: name={{ item.name }} state=present groups={{ item.groups }}<br /> with_items:<br /> – { name: 'testuser1', groups: 'wheel' }<br /> – { name: 'testuser2', groups: 'root' }</p> <p>ansible的循环机制还有更多的高级功能,具体请参见官方文档(http://docs.ansible.com/playbooks_loops.html)。</p> <p> </p> <p><strong>7、tags:</strong></p> <p> tags用于让用户选择运行或路过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断。</p> <p>在playbook可以为某个或默写任务定义一个“标签”,在执行此playbook时,通过为ansible-playbook命令,使用–tags选项能实现仅运行指定的tasks而非所有:<br /> [root@master ansible]# vim targ.yml <br />– hosts: webserver<br /> remote_user: root<br /> vars:<br /> – package: httpd<br /> – service: httpd<br /> tasks:<br /> – name: install httpd package<br /> yum: name={{ package }} state=latest<br /> – name: install configuration file for httpd<br /> template: src=/etc/ansible/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf<br /> tags:<br /> – conf<br /> notify:<br /> – restart httpd<br /> – name: start httpd service<br /> service: enabled=true name={{ service }} state=started<br /> handlers:<br /> – name: restart httpd<br /> service: name=httpd state=restarted<br />~ <br />ansible-playbook targ.yml –tags="conf"</p> <p>特殊tags:always 无论无可都运行</p> <p><strong>8、roles:</strong></p> <p>ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。<br />要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,<br />并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。</p> <p> </p> <p> 创建role的步骤:</p> <p> (1) 创建以roles命名的目录;<br /> (2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;<br /> (3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;<br /> (4) 在playbook文件中,调用各角色;</p> <p>8.2 role内各目录中可用的文件</p> <p> tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件;<br /> files目录:存放由copy或script等模块调用的文件;<br /> templates目录:template模块会自动在此目录中寻找Jinja2模板文件;<br /> handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中;<br /> vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;<br /> meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;<br /> default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;</p> <p> </p> <p><strong>9、使用roles角色分离task、files、handlers文件</strong></p> <p> a、创建roles目录:</p> <p> mkdir -pv /etc/ansible/ansible_playbooks/roles/websrvs{tasks,files,templates,meta,handlers,vars}</p> <p> b、提供配置文件:(也可以使用模板文件)</p> <p> cp /etc/httpd/conf/httpd.conf /etc/ansible/ansible_playbooks/roles/websrvs/files</p> <p> <img title="1460968863568902.jpg" alt="8080.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170047-4.jpg" /></p> <p> c、编辑task任务文件格式为main.yml</p> <p> <img title="1460966837544084.jpg" alt="roles-task.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170047-86.jpg" /></p> <p> d、编辑handlers通知文件格式为main.yml</p> <p> <img title="1460966939292143.jpg" alt="handler.jpg" src="//cto.wang/usr/uploads/2016/07/20160703170047-20.jpg" /></p> <p> e、编辑站点site.yml文件调用roles角色的websrvs</p> <p> <img title="1460967201353688.png" alt="roles-site.png" src="//cto.wang/usr/uploads/2016/07/20160703170047-19.png" /></p> <p> f、基于roles角色运行site.yml</p> <p> <img title="1460969020532616.png" alt="roles-site1.png" src="//cto.wang/usr/uploads/2016/07/20160703170047-86.png" /></p> <p> g、测试客户端:</p> <p> <img title="1460969215695705.png" alt="start-httpd-roles.png" src="//cto.wang/usr/uploads/2016/07/20160703170047-22.png" /></p> <p> </p> <p> </p> <p> 感谢马哥,每天进步一点点! </p> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信