ansile(3)playbook 使用

发布时间:2019-07-10 13:37:25编辑:auto阅读(1507)


    一、playbook介绍

    二、palybook使用说明

    三、roles说明及配置


    一、playbook介绍

    1.playbook介绍

    顾名思义,playbook就是类似演戏的剧本一样,将所有的戏码全部放在一起,官方说明如下:

    Playbooks是Ansible的配置,部署和编排语言。它们可以描述您希望远程系统执行的策略,或一般IT流程中的一组步骤。

    如果Ansible模块是车间中的工具,Playbooks是您的使用手册,您的主机库存是您的原材料。

    在基本层面,剧本可用于管理远程机器的配置和部署。在更高级的层面上,他们可以对涉及滚动更新的多层次发布进行排序,并且可以将动作委派给其他主机,同时与监视服务器和负载平衡器进行交互。

    虽然这里有很多信息,但没有必要一次学习一切。你可以开始小,并随着时间的推移更多的功能,当你需要它们。

    Playbooks被设计为人类可读的,并且用基本的文本语言开发。有多种方式来组织剧本和它们包括的文件,我们将提供一些建议,并充分利用Ansible。


    二、palybook使用说明

    2.playbook的使用及说明

    2.1.基本变量及组件

    2.1.1.基本组件

    主机和用户说明:

    hosts  为主机的IP,或者主机组名,或者关键字all

    remote_user 在远程以哪个用户身份执行。

    become 切换成其它用户身份执行,值为yes或者no

    become_method 与became一起用,指可以为‘sudo’/’su’/’pbrun’/’pfexec’/’doas’

    become_user 与bacome_user一起用,可以是root或者其它用户名 


    2.1.2.基本变量

    自定义变量需要用` `引用以来即可

    例如:

    - host: cklserver
      vars: 
          ser_name: nginx
      tasks:
         - name: install {{ ser_name }}
         - yum: 
              name: {{ ser_name }}
              state: present

    2.1.3.注意问题!

    但是这样写YML会报错:

    - hosts: app_servers
      vars:
          app_path: {{ base_path }}/22

    解决办法:要在{ 开始的值加上引号:

    - hosts: app_servers
      vars:
           app_path: "{{ base_path }}/22"

    2.2.task说明

    2.2.1.task的基本写法

    tasks:
      - name: make sure apache is running
        service: name=httpd state=running

    参数太长可以分隔到多行

     tasks:
      - name: Copy ansible inventory file to client
        copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
                owner=root group=root mode=0644

    或者用yml的字典作为参数

     tasks:
      - name: Copy ansible inventory file to client
        copy: 
          src: /etc/ansible/hosts 
          dest: /etc/ansible/hosts
          owner: root
          group: root 
          mode: 0644

    2.2.2.task的执行状态

    task中每个action会调用一个module,在module中会去检查当前系统状态是否需要重新执行. 具体的判断规则由各个module自己实现.

        .如果执行那么action会得到返回值changed;

        .如果不需要执行,那么action得到返回值ok


    2.3.示例说明

    2.3.1.不废话看一个简单的例子:

    # cat apache.yml 
    - hosts: webserver
      user: root
      tasks:
          - name: restart httpd
            service: name=httpd state=restarted

    执行结果:

    wKiom1hlSz7zFRqAAAAjgh1e6MY321.png

    YML文件简单说明:

    - hosts: webserver  //服务器组
      user: root //运行用户
      tasks:  //任务
          - name: restart httpd  //任务名称
            service: name=httpd state=restarted //操作服务

    2.3.2.看一个稍微长一点的示例

    # cat apache.yml 
    - hosts: webserver
      remote_user: root
      vars:
          ser_name: httpd
      tasks:
          - name: add run user
            user: name='niao' uid=1008 state=present
          - name: install package {{ ser_name }} 
            yum: name={{ ser_name }} state=present
          - name: copy {{ ser_name }} config file
            copy: src=/etc/ansible/conf_dir/{{ ser_name }}.conf dest=/etc/{{ ser_name }}/conf/ owner=niao group=niao
          - name: start {{ ser_name }} server
            service: name={{ ser_name }} state=started

    以上内容说明:

    1.添加一个uid为1008的niao用户

    2.安装httpd服务

    3.拷贝配置文件,并修改属主属组为niao

    4.启动httpd服务

    运行结果:

    wKiom1hlTF2AvrnsAAA8nm727_A559.png

    查看目标文件:

    # cd /etc/httpd/conf
    # ll
    total 52
    -rw-r--r-- 1 niao niao 11750 Dec 29 21:43 httpd.conf

    wKioL1hlTYqyY4X2AAAYk8ybEE8722.png

    2.4.handler说明

    Handlers里面的每一个handler,也是对module的一次调用。而handler与tasks不同的是,handlers不会默认的按顺序执行。

    Tasks中的任务都是有状态的,changed或者ok。 Ansible提供了一种机制,只在task的执行状态为changed的时候,才会触发执行,这就是handler。


    使用情景:

    如果你在tasks中修改了apache的配置文件。需要重起apache。此外还安装了apache的插件。那么还需要重起apache。像这样的应该场景中,重起apache就可以设计成一个handler.


    2.4.1.一个handler最多只执行一次

    在所有的任务里表执行之后执行,如果有多个task notify同一个handler,那么只执行一次。

    在下面的例子里apache只执行一次

    拷贝两个apache的配置文件,重启一次:

    # vim httpd.yml              
    - hosts: webserver
      remote_user: root
      vars:
          ser_name: httpd
      tasks:
          - name: copy {{ ser_name }} config file ckl
            copy: src=/etc/ansible/conf_dir/ckl.conf dest=/etc/{{ ser_name }}/conf.d/ owner=niao group=niao
            notify:
                 - call in copy action
          - name: copy {{ ser_name }} config file zld
            copy: src=/etc/ansible/conf_dir/zld.conf dest=/etc/{{ ser_name }}/conf.d/ owner=niao group=niao
            notify:
                 - call in copy action
      handlers:
          - name: call in copy action
            service: name={{ ser_name }} state=started

    运行结果:

    wKiom1hlTZnzM4kUAAA28qw77jU962.png

    action是Changed ,才会执行handler

    只有当TASKS种的action的执行状态是changed时,才会触发notify handler的执行。

    下面的脚本执行两次,执行结果是不同的:


    上面的次执行是,tasks的状态都是changed,会触发两个handler


    2.4.2.下面的执行是:

    第一个task的状态是changed,触发了handlers"call in copy action"

    第二个task的状态是OK,那么不会触发handlers"call in add user action"

    # vim call_by.yml 
    - hosts: webserver
      remote_user: root
      vars:
          ser_name: httpd
      tasks:
          - name: copy {{ ser_name }} config file ckl
            copy: src=/etc/ansible/conf_dir/ckl.conf dest=/etc/{{ ser_name }}/conf.d/ owner=niao group=niao
            notify:
                 - call in copy action
          - name: add user niao
            user: name='niao' uid=1008
            notify:
                 - call in add user action
    
      handlers:
          - name: call in copy action
            service: name={{ ser_name }} state=started
          - name: call in add user action
            service: name={{ ser_name }} state=started

    运行结果:

    wKioL1hlTc3hoV5gAAA1xSYM0WM476.png

    2.5.主机的系统变量(facts)

    2.5.1.收集变量

    ansible会通过module setup来收集主机的系统信息,这些收集到的系统信息叫做facts,这些facts信息可以直接以变量的形式使用。

    ansible dbserver -m setup -u root
    ...
     "ipv4": {
                    "address": "172.16.110.49", 
                    "broadcast": "172.16.110.255", 
                    "netmask": "255.255.255.0", 
                    "network": "172.16.110.0"
                }, 
                "ipv6": [
                    {
                        "address": "fe80::4986:a223:c2d8:0", 
                        "prefix": "64", 
                        "scope": "link"
                    }, 
    ....
      "ansible_hostname": "localhost", 
            "ansible_interfaces": [
                "lo", 
                "ens33"
            ], 
    ....
       "ansible_nodename": "localhost.localdomain", 
            "ansible_os_family": "RedHat", 
            "ansible_pkg_mgr": "yum", 
            "ansible_processor": [
                "GenuineIntel", 
                "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz"
            ], 
    ...

    2.5.2.使用facts变量示例:

    - hosts: dbserver
      user: root
      tasks:
      - name: echo system
        shell: echo {{ ansible_os_family }}
      - name install ntp on RedHat linux
        yum: name=ntp state=installed
        when: ansible_os_family == "RedHat"

    2.5.3.变量子属性访问

    那么可以通过下面的两种方式访问复杂的变量中的子属性:

    中括号:

    {{ ansible_ens3["ipv4"]["address"] }}

    点号:

    {{ ansible_ens3.ipv4.address }}

    关闭facts

    - hosts: whatever
      gather_facts: no

    2.6.使用命令行变量

    在命令行里面传值得的方法:

    ansible-playbook ckl.yml --extra-vars "hosts=web user=root"

    还可以用json格式传递参数:

    ansible-playbook ckl.yml --extra-vars "{'hosts':'ckl1.com', 'user':'root'}"

    还可以将参数放在文件里面:

    ansible-playbook ckl.yml --extra-vars "@vars.json"

    2.7.include调用

    很简单,看例子就行

    Include语句的功能,基本的代码重用机制。主要重用tasks。

    主配置yml:

    # cat main.yml 
    - hosts: webserver
      remote_user: root
      vars:
          ser_name: httpd
      tasks:
          - include: taks/call_by.yml

    需要include的yml文件:

    # cat taks/call_by.yml 
    - name: copy {{ ser_name }} config file ckl
      copy: src=/etc/ansible/conf_dir/ckl.conf dest=/etc/{{ ser_name }}/conf.d/ owner=niao group=niao
      notify:
           - call in copy action
    - name: add user niao 
      user: name='niao' uid=1008 
      notify:
           - call in add user action

    主配置的变量可以在include文件中使用

    运行结果:

    wKioL1hlTmSDqSLKAAAnY5pYfzo385.png

    三、roles说明及配置

    比include更强大的代码重用机制。一个role可以包含vars_files, tasks, and handlers等等. 通常一个role定义了如何完成一个特定的功能,比如安装Webservers可以写成一个role, 安装Database可以写成一个role.

    role的目录结构

    site.yml
    roles/
       dbserver/  
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/
       webserver/
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/

    每个角色都会遵循以下原则:

    - 如果'roles/x/tasks/main.yml'存在,里面的任务列表会被添加到`play`中。

    - 如果'roles/x/handlers/main.yml'存在,里面的`handlers`会被添加到`play`中。

    - 如果'roles/x/vars/main.yml'存在,里面的变量会被添加到`play`中。

    - 如果'roles/x/meta/main.yml'存在,里面的角色依赖会被添加到角色列表中。

    - 在'roles/x/files'任务所需要被复制的文件,无需绝对路径或者相对路径都可以引用该文件。

    - 在'roles/x/files'中的任务脚本都可以直接使用该文件,无需指定绝对路径或者是相对路径。

    - 在'roles/x/templates'中的模板,无需指定绝对路径或者相对路径,都可以直接使用文件名引用该文件。

    - 需要包含在`roles/x/tasks'中的任务文件时,无需指定绝对路径或者相对路径,可以直接使用文件名包含。


    测试示例:

    目标:apache服务器组安装httpd并拷贝配置文件,启动程序

          dbserver服务器组安装maridb并拷贝配置文件,启动程序


    1.配置webserver

    # cd roles
    # mkdir -p webserver/{files,templates,tasks,handlers,vars,defaults,meta}

    1.1.拷贝配置文件:

    cp httpd.conf webserver/files

    1.2.配置tasks:

    # cat roles/webserver/tasks/main.yml 
    - name: add run user
      user: name='niao' uid=1008 state=present
    - name: install package httpd
      yum: name=httpd state=present
    - name: copy httpd config file
      copy: src=httpd.conf dest=/etc/httpd/conf/ owner=niao group=niao

    1.3.配置handlers

    # cat roles/webserver/handlers/main.yml 
    - name: start httpd server
      service: name=httpd state=started

    2.配置dbserver

    # mkdir -p dbserver/{files,templates,tasks,handlers,vars,defaults,meta}

    2.1.拷贝配置文件

    cp my.cnf dbserver/files

    2.2.配置tasks:

    # cat roles/dbserver/tasks/main.yml                   
    - name: install mariadb package
      yum: name=mariadb-server state=present
    - name: copy config file
      copy: src=my.cnf dest=/etc/

    2.3.配置handlers

    # cat roles/dbserver/handlers/main.yml      
    - name: start mariadb server
      service: name=mariadb state=started

    3.整体结构

    # tree
    ├── roles
    │   ├── dbserver
    │   │   ├── defaults
    │   │   ├── files
    │   │   │   └── my.cnf
    │   │   ├── handlers
    │   │   │   └── main.yml
    │   │   ├── meta
    │   │   ├── tasks
    │   │   │   └── main.yml
    │   │   ├── templates
    │   │   └── vars
    │   └── webserver
    │       ├── defaults
    │       ├── files
    │       │   └── httpd.conf
    │       ├── handlers
    │       │   └── main.yml
    │       ├── meta
    │       ├── tasks
    │       │   └── main.yml
    │       ├── templates
    │       └── vars
    ├── site.retry
    ├── site.yml

    4.site配置

    # cat site.yml 
    - hosts: webserver
      remote_user: root
      roles:
         - webserver
    - hosts: dbserver
      remote_user: root
      roles:
         - dbserver

    5.运行结果:

    wKioL1hlTxyh7RYwAABXxJadL80906.png

关键字