ansible(二):playbook和roles介绍

playbook和roles介绍

  • 一、前言
  • 二、playbook详解
    • 1、playbook的基本组成
    • 2、playbook各基础组件说明
    • 3、条件测试
    • 4、迭代和迭代嵌套
    • 5、tags(标签)
    • 6、运行playbook
    • 7、案例:使用ansible对websrvs组的两台主机做httpd的高可用
  • 三、roles

一、前言

在介绍playbook之前,我们先了解一下YAML语言,因为playbook是用YAML语言编写的

一、YAML

1、YAML是一种可读性高的用来表达资料序列的语言,其语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。所有的yaml文件都以---开头表示开始一个document,所有的列表元素以"-“开头,键值对用”:",后面的空格是必须的。下面是一个示例:

---   #打头符可省略

- name: John Smith

  age: 41

  gender: Male

  spouse:

    name: Jane Smith

    age: 37

    gender: Female

  children:

    - name: Jimmy Smith

     age: 17

     gender: Male

    - name: Jenny Smith

     age 13

     gender: Female

YAML文件扩展名通常为.yaml或.yml,如example.yaml

2、list

列表的所有元素均使用“-”打头,例如:

  # A list of tasty fruits

  - Apple

  - Orange

  - Strawberry

3、dictionary

字典通过key与valuef进行标识,例如:

  # An employee record

  name: Example Developer

  job: Developer

  skill: Elite

也可以将key:value放置于{}中进行表示,例如:

  # An employee record

  {name: Example Developer, job: Developer, skill: Elite}

二、playbook详解

playbook(剧本)是ansible管理配置、部署应用和编排的文件,可用来描述你想在被控主机上执行的策略或者一组任务等。

一个playbook文件由一个或多个play组成,每个play定义了在一个或多个远程主机上执行的一系列的task,其中每个task一般就是调用一个ansible的模块。

playbook使用YAML语言编写,文件名以.yaml或.yml结尾。此外playbook和模板文件(template)还可使用jinja2语法语法实现高级功能。

1、playbook的基本组成

  targets:指定要执行playbook的远程主机组

  variables:定义playbook运行时需要使用的变量

  tasks:要执行的任务

  handlers:处理器,在某些条件下被触发的操作



一个简单的示例:

  vim httpd.yml

  - hosts: websrvs

   remote_user: root

   vars:

     remote_conffile_path: /etc/httpd/conf/httpd.conf

   tasks:

   - name: install httpd

    yum: name=httpd state=latest

    when: ansible_pkg_mgr == "yum"

   - name: configration file

    tags: conf

    copy: src=/root/httpd.conf dest=` remote_conffile_path `  

    notify: restart httpd

   - name: start httpd

    service: name=httpd enabled=yes state=started

   handlers:

   - name: restart httpd

    service: name=httpd state=restarted

2、playbook各基础组件说明

⑴hosts和users

  hosts用于指定要执行指定任务的主机,其可以是一个或多个由逗号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的

    - hosts: websrvs

      remote_user: magedu   #在远程主机上以哪个用户身份执行

      become: yes   #是否允许身份切换

      become_method: sudo   #切换用户身份的方式,有sudo、su、pbrun等方式,默认为sudo

      become_user: root   #切换成什么用户身份,默认为root

     tasks:

     - name: test connection

       ping:

   以上remote_user、become、become_method、become_use选项不仅可用于全局,也可用于各task中。在absible 2.0以前的版本中,用 sudo 和 sudo_user 两个选项分别表示是否允许sudo和sudo切换到的用户身份

  remote_user、become、become_method、become_user分别对应inventory文件中的ansible_user、ansible_become、ansible_become_method、ansible_become_user

  如果需要指定切换用户身份时的密码,可在执行ansible-playbook时使用选项 --ask-become-pass指定(旧版ansible使用 --ask-sudo-pass指定sudo切换时的密码)

  



⑵任务列表和action

   play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。

   task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。

   每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。

   定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容例如:

      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



⑶handlers:用于当关注的资源发生变化时触发一定的操作。

   “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

      - name: template configuration file

       template: src=/root/template.j2 dest=/etc/foo.conf

       notify:

       - restart memcached

       - restart apache

   handler是task列表,这些task与前述的task并没有本质上的不同。

      handlers:

      - name: restart memcached

       service: name=memcached state=restarted

      - name: restart apache

       service: name=apache state=restarted

⑷变量

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

    在playbook中定义变量的格式:

      - host websrvs

       vars:

         variable:value

    如何调用变量:` variable `

    在inventory中定义的变量,可在playbook中直接调用

    每个被控节点在接收并运行管理命令之前,会将本主机相关信息(称为facts,这些信息保存于变量中)如操作系统版本,ip地址,cpu数量等报告给ansible主机。这些变量信息通过 ansible  -m setup 获取,我们可在playbook中调用这些变量。

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

      - hosts: webservers

        roles:

        - common

        - { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 }

    另外,在运行playbook的时候也可以传递一些变量,示例:

       ansible-playbook test.yml --extra-vars "hosts=www user=magedu"

3、条件测试

  如果需要根据变量、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中定义的变量。

4、迭代和迭代嵌套

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

    - 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' }

5、tags(标签)

  tags用于让用户选择运行playbook中的某个或某些任务。虽然ansible具有幂等性,会跳过没有变化的部分,但是,有些代码为测试其确实没有发生变化,也会耗费很长时间。我们将playbook中的指定任务打上标签,在运行playbook时指定标签名称,这样就不用运行全部代码了。

  playbook中可定义多个标签,且可重名。

  示例:

    - name: configration file

     copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf    

     notify: restart httpd

     tags: conf

  运行指定标签的任务:ansible-playbook httpd.yml -t conf

6、运行playbook

  ansible-playbook  ... [options]

  例:ansible-playbook httpd.yml

7、案例:使用ansible对websrvs组的两台主机做httpd的高可用

以下node1为ansible节点,node2和node3为被控节点,已被添加至主机组websrvs。这里假设两个被控节点上已安装好httpd服务程序,且已建立双机互信。

[root@node1 ~]# vim /etc/ansible/hosts

[websrvs]
192.168.30.20
192.168.30.13
[dbsrvs]
192.168.30.14
[root@node1 ~]# ls hb_conf   #准备好需要的文件
authkeys  ha.cf  haresources
[root@node1 ~]# vim heartbeat.yml   #创建playbook

- hosts: websrvs
  remote_user: root
  tasks:
  - name: ensure heartbeat latest version
    yum: name=heartbeat state=present
  - name: authkeys
    copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/ mode=600
    notify: restart heartbeat
  - name: ha.cf
    copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/
    notify: restart heartbeat
    tags: conf   #打标签
  - name: haresources
    copy: src=/root/hb_conf/haresources dest=/etc/ha.d/
    notify: restart heartbeat
  handlers:
  - name: restart heartbeat
    service: name=heartbeat state=restarted

[root@node1 ~]# ansible-playbook heartbeat.yml    #运行playbook

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.30.20]
ok: [192.168.30.13]

TASK [ensure heartbeat latest version] *****************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

TASK [authkeys] ****************************************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

TASK [ha.cf] *******************************************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

TASK [haresources] *************************************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

RUNNING HANDLER [restart heartbeat] ********************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

PLAY RECAP *********************************************************************
192.168.30.13              : ok=6    changed=5    unreachable=0    failed=0   
192.168.30.20              : ok=6    changed=5    unreachable=0    failed=0
#验证
[root@node2 ~]# ls /etc/ha.d
authkeys  ha.cf  harc  haresources  rc.d  README.config  resource.d  shellfuncs
[root@node2 ~]# ll /etc/ha.d/authkeys 
-rw------- 1 root root 680 May  3 20:07 /etc/ha.d/authkeys
[root@node2 ~]# service heartbeat status
heartbeat OK [pid 7595 et al] is running on node2 [node2]...
[root@node2 ~]# ip addr show
...
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:bd:68:23 brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.20/24 brd 192.168.30.255 scope global eth0
    inet 192.168.30.100/24 brd 192.168.30.255 scope global secondary eth0
    inet6 fe80::20c:29ff:febd:6823/64 scope link 
       valid_lft forever preferred_lft forever
[root@node2 ~]# service httpd status
httpd (pid  8049) is running...
[root@node1 ~]# vim hb_conf/ha.cf   #修改主配置文件
...
mcast eth0 225.1.1.5 694 1 0   #更改心跳信息的组播地址
[root@node1 ~]# ansible-playbook heartbeat.yml -t conf   #只执行指定标签的任务

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.30.13]
ok: [192.168.30.20]

TASK [ha.cf] *******************************************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

RUNNING HANDLER [restart heartbeat] ********************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

PLAY RECAP *********************************************************************
192.168.30.13              : ok=3    changed=2    unreachable=0    failed=0   
192.168.30.20              : ok=3    changed=2    unreachable=0    failed=0
[root@node2 ~]# netstat -unl
...                         
udp        0      0 225.1.1.5:694               0.0.0.0:*

三、roles

https://blog.51cto.com/9124573/1769887
未完待续。。。。。。。

你可能感兴趣的:(linux)