ansible高级应用

上一篇博客介绍了ansible的基础应用Modules,博客地址 http://www.178linux.com/14860 。这次介绍下Ansible的另一个核心模块Playbooks。

 

Ansible的核心模块:

    Ansible core:            核心;

    core Modules:          包括 Ansible 自带的核心模块及自定义模块;

    connect Plugins:       完成模块功能的补充,包括连接插件、邮件插件等;

    Playbooks:       网上很多翻译为剧本,个人觉得理解为编排更为合理;定义 Ansible 多任务配置文件,由 Ansible 自动执行;

    host Inventory:         定义 Ansible 管理主机的清单、主机池、主机列表;

 

        Playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。
从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。

        ansinbl使用 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。

 

YAML介绍:

        YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。

YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。其特性:

 YAML的可读性好
 YAML和脚本语言的交互性好
 YAML使用实现语言的数据类型
 YAML有一个一致的信息模型
 YAML易于实现
 YAML可以基于流来处理
 YAML表达能力强,扩展性好

更多的内容及规范参见http://www.yaml.org

 

1、YAML语法:

        YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。

Playbook组成结构:
 Inventory
 Modules
 Ad Hoc Commands
 Playbooks
  Tasks:任务,即调用模块完成的操作
  Variables:变量
  Templates:模板
  Handlers:处理器,由某个条件触发执行的操作
  Roles:角色
基本结构:
 – host:webservices
  remote_user:
  – tasks:
   – task1
    module_name

YAML文件扩展名通常为.yml,如test.yml。

2、使用yaml模板文件安装httpd、提供其配置文件、配置开机启动并启动服务:

[root@master ansible]# vim apache.yml
– hosts: webserver
  remote_user: root
  tasks:
  – name: install httpd package
    yum: name=httpd state=latest
  – name: install configuration file for httpd
    copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
  – name: start httpd service
    service: enabled=true name=httpd state=started

    apache-yml.jpg

    apache-yml-client.jpg

 

3、YAML语言变量:

 变量命名:变量名仅能由字母、数字和下划线组成,且只能以字母开头。

 facts变量:

    facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts,可使用如下命令进行:

            ansible hostname -m setup

             register

把任务的输出定义为变量,然后用于其他任务,示例如下:

  tasks:
     – shell: /usr/bin/foo
       register: foo_result
       ignore_errors: True

通过命令行传递变量:

    在运行playbook的时候也可以传递一些变量供playbook使用,示例如下:

     ansible-playbook test.yml –extra-vars "hosts=webserver user=node1"

通过roles传递变量:

    当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量,示例如下:

     – hosts: webservers
       roles:
     – common
     – { role: foo_app_instance, dir: '/web/htdocs/a.com',  port: 8080 }

Inventory:

    ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。

    inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成。

     inventory文件格式:

        inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明。

 test.ansible.com

 [webservers]
 www1.mageedu.com:2222
 www2.mageedu.com

 [dbservers]
 db1.mageedu.com
 db2.mageedu.com
 db3.mageedu.com

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,例如:

[webservers]
www[01:50].example.com

[databases]
db-[a:f].example.com

主机变量:可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用。例如:

[webservers]
www1.mageedu.com http_port=80 maxRequestsPerChild=808
www2.mageeducom http_port=8080 maxRequestsPerChild=909

组变量:组变量是指赋予给指定组内所有主机上的在playboo中可用的变量。例如:

[webservers]
www1.mageedu.com
www2.mageedu.com

[webservers:vars]
ntp_server=ntp.mageedu.com
nfs_server=nfs.mageedu.com

 

4、使用变量、模板文件安装配置apache:

    apache-template.jpg

    var-apache.jpg

 5、条件测试:

    如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试。

    when语句

在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。例如:

tasks:
  – name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -h now
    when: ansible_os_family == "Debian"

when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:

tasks:
  – command: /bin/false
    register: result
    ignore_errors: True
  – command: /bin/something
    when: result|failed
  – command: /bin/something_else
    when: result|success
  – command: /bin/still/something_else
    when: result|skipped

此外,when语句中还可以使用facts或playbook中定义的变量。

6、迭代:

        当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。例如:

调用:item
定义循环列表:whit_item
 – apache
 – php
 – mysql-server
注意:whit_items中的列表值也可以是字典,但引用是要使用item_KEY
 – {name: apache,conf: confffiles/httpd.conf}
 – {name: php,conf:conffiles/php.ini}
 – {name: mysql-servce,conf/conffiles/my.cnf}
 
– name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     – testuser1
     – testuser2

上面语句的功能等同于下面的语句:

– name: add user testuser1
  user: name=testuser1 state=present groups=wheel
– name: add user testuser2
  user: name=testuser2 state=present groups=wheel

事实上,with_items中可以使用元素还可为hashes,例如:

– name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    – { name: 'testuser1', groups: 'wheel' }
    – { name: 'testuser2', groups: 'root' }

ansible的循环机制还有更多的高级功能,具体请参见官方文档(http://docs.ansible.com/playbooks_loops.html)。

 

7、tags:

        tags用于让用户选择运行或路过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断。

在playbook可以为某个或默写任务定义一个“标签”,在执行此playbook时,通过为ansible-playbook命令,使用–tags选项能实现仅运行指定的tasks而非所有:
 [root@master ansible]# vim targ.yml
– hosts: webserver
  remote_user: root
  vars:
  – package: httpd
  – service: httpd
  tasks:
  – name: install httpd package
    yum: name={{ package }} state=latest
  – name: install configuration file for httpd
    template: src=/etc/ansible/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    tags:
    – conf
    notify:
        – restart httpd
  – name: start httpd service
    service: enabled=true name={{ service }} state=started
  handlers:
  – name: restart httpd
    service: name=httpd state=restarted
~                                       
ansible-playbook targ.yml –tags="conf"

特殊tags:always 无论无可都运行

8、roles:

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文件中,调用各角色;

8.2 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文件;

 

9、使用roles角色分离task、files、handlers文件

    a、创建roles目录:

                            mkdir -pv /etc/ansible/ansible_playbooks/roles/websrvs{tasks,files,templates,meta,handlers,vars}

    b、提供配置文件:(也可以使用模板文件)

                           cp /etc/httpd/conf/httpd.conf  /etc/ansible/ansible_playbooks/roles/websrvs/files

            8080.jpg

    c、编辑task任务文件格式为main.yml

            roles-task.jpg

    d、编辑handlers通知文件格式为main.yml

           handler.jpg

   e、编辑站点site.yml文件调用roles角色的websrvs

           roles-site.png

    f、基于roles角色运行site.yml

          roles-site1.png

  g、测试客户端:

        start-httpd-roles.png

 

 

                                                                                                                                                    感谢马哥,每天进步一点点! 

原创文章,作者:n18-jude,如若转载,请注明出处:http://www.178linux.com/14869

评论列表(1条)

  • 517766237
    517766237 2016-04-21 11:18

    写的很详细,学习