zoukankan      html  css  js  c++  java
  • Ansible之roles角色

      一、roles简介

      ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需在playbook中使用include指定即可。简单来讲,roles就是通过分别将变量、文件、任务、模板以及处理器放置于单独目录中,并可以便捷的使用include指令将他们组织在一块的一种机制。角色一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。复杂场景建议使用角色,代码复用度高。

      二、roles目录结构

      roles目录结构如上所示,每个角色以特定的层次目录结构进行组织。其中roles/目录下是每个角色的目录,比如上图有git和user两个角色,每个角色下分别有tasks、files、vars等等目录,files/目录主要存放copy或scripts模块等调用的文件;templates/目录主要存放template模块查找所需要的模板文件;tasks/定义task,role的基本元素,至少应该包含一个名为main.yml的文件(这个文件就是tasks目录的入口文件),其他的文件需要在此文件中通过include进行包含;handlers/目录主要存放触发器任务的yml文件,同样它里面至少需要有一个main.yml的入口文件,其文件内容通过include指令引用其下文件;vars/目录主要存放定义的变量文件,同样也需要有main.yml文件;meta/目录定义当前角色的特殊设定以及依赖关系,同样这个目录也需要有一个main.yml的入口文件;default/设定默认变量时使用此目录中的main.yml文件;

      通过上面的介绍,不难发现roles是依赖目录的命名和摆放,默认tasks/main.yml是所有任务的入口,所以使用roles的过程可以理解为目录规范化命名的过程。每个目录下均由main.yml定义该功能的任务集,tasks/main.yml默认执行所有指定的任务。roles的调用文件playbook_roles.yml的内容如下

    ---
    - hosts: websers
      remote_user: root
      
      roles:
        - roles_name  
    

      说明:定义好角色我们还需要写一个调用角色的playbook.yml 用于调用角色,其中我们要写明这个角色用于那些主机(在那些主机上执行),在远程主机上以那个用户来执行角色以及执行那些角色。

      角色的执行方法同执行playbook一样,我们只需要执行定义调用角色的playbook即可;roles目录可以摆放在/etc/ansible/ansible.cfg中"roles_path"定义路径,也可以和入口playbook文件存放在同级目录,ansible没有强制的要求,但还是建议将代码存放在代码集预先规划的目录,以便管理。

      三、创建角色

      通常创建role的步骤有如下4步

      1)创建以roles命名的目录

      2)在roles目录中分别创建以各自角色名称命名的目录,如nginx等

      3)在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates、和vars目录;若角色用不到的目录可以是空目录,也可以不创建

      4)在playbook文件中,调用各角色

    示例:将我们之前写的playbook修改成角色

    playbook代码以及目录结构如下:

    [root@test ~]#tree
    .
    ├── install_nginx.yml
    └── templates
        ├── centos6_nginx.conf.j2
        └── centos7_nginx.conf.j2
    
    1 directory, 3 files
    [root@test ~]#cat install_nginx.yml 
    ---
    - hosts: websers
      remote_user: root
    
      tasks:
        - name: install nginx
          yum: name=nginx
        - name: templates config file centos6
          template: src=centos6_nginx.conf.j2 dest=/etc/nginx/nginx.conf
          notify: restart nginx
          when: ansible_distribution_major_version == "6"
        - name: templates config file centos 7
          template: src=centos7_nginx.conf.j2 dest=/etc/nginx/nginx.conf
          notify: restart nginx
          when: ansible_distribution_major_version == "7"
        - name: start service
          service: name=nginx state=started 
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted
    
    [root@test ~]#

    改编成角色目录结构以及各目录文件内容如下

    [root@test ~]#tree
    .
    ├── install_nginx.yml
    ├── nginx_role.yml
    ├── roles
    │   └── nginx
    │       ├── handlers
    │       │   ├── main.yml
    │       │   └── restart_nginx.yml
    │       ├── tasks
    │       │   ├── install_nginx.yml
    │       │   ├── main.yml
    │       │   ├── nginx_service.yml
    │       │   └── template_config_file.yml
    │       └── templates
    │           ├── centos6_nginx.conf.j2
    │           └── centos7_nginx.conf.j2
    └── templates
        ├── centos6_nginx.conf.j2
        └── centos7_nginx.conf.j2
    
    6 directories, 12 files
    [root@test ~]#cat roles/nginx/tasks/install_nginx.yml 
    - name: install nginx
      yum: name=nginx
    [root@test ~]#cat roles/nginx/tasks/template_config_file.yml 
    - name: templates config file centos6
      template: src=centos6_nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
      when: ansible_distribution_major_version == "6"
    - name: tmeplates config file centos7
      template: src=centos7_nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
      when: ansible_distribution_major_version == "7"
    
    [root@test ~]#cat roles/nginx/tasks/nginx_service.yml 
    - name: start service
      service: name=nginx state=started 
    [root@test ~]#cat roles/nginx/tasks/main.yml 
    - include: install_nginx.yml
    - include: template_config_file.yml
    - include: nginx_service.yml
    [root@test ~]#cat roles/nginx/handlers/restart_nginx.yml 
    - name: restart nginx
      service: name=nginx state=restarted
    [root@test ~]#cat roles/nginx/handlers/main.yml 
    - include: restart_nginx.yml
    [root@test ~]#

      说明:以上目录编排就实现了一个简单角色,我们把playbook内容分别用一个文件存放,然后按照每个目录的main.yml文件定义的顺序依次执行,这里只是定义好了一个角色,我们还需要写一个playbook来调用该角色即可。

    [root@test ~]#cat nginx_role.yml 
    ---
    - hosts: websers
      remote_user: root
    
      roles:
        - nginx
    [root@test ~]#
    

      说明:以上就是一个调用我们刚才编排好的nginx角色的playbook。用ansilble-playbook 命令去执行以上调用角色的playbook,就相当于我们之前写的playbook功能完全一样。

    [root@test ~]#ansible-playbook nginx_role.yml 
    
    PLAY [websers] ******************************************************************************************************
    
    TASK [Gathering Facts] **********************************************************************************************
    ok: [192.168.0.128]
    ok: [192.168.0.218]
    
    TASK [nginx : install nginx] ****************************************************************************************
    changed: [192.168.0.128]
    changed: [192.168.0.218]
    
    TASK [nginx : templates config file centos6] ************************************************************************
    changed: [192.168.0.128]
    changed: [192.168.0.218]
    
    TASK [nginx : tmeplates config file centos7] ************************************************************************
    skipping: [192.168.0.128]
    skipping: [192.168.0.218]
    
    TASK [nginx : start service] ****************************************************************************************
    changed: [192.168.0.128]
    changed: [192.168.0.218]
    
    RUNNING HANDLER [nginx : restart nginx] *****************************************************************************
    changed: [192.168.0.128]
    changed: [192.168.0.218]
    
    PLAY RECAP **********************************************************************************************************
    192.168.0.128              : ok=5    changed=4    unreachable=0    failed=0   
    192.168.0.218              : ok=5    changed=4    unreachable=0    failed=0   
    
    [root@test ~]#ansible websers -m shell -a 'ss -ntl'     
    192.168.0.128 | SUCCESS | rc=0 >>
    State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port 
    LISTEN     0      128                      :::80                      :::*     
    LISTEN     0      128                       *:80                       *:*     
    LISTEN     0      128                      :::22                      :::*     
    LISTEN     0      128                       *:22                       *:*     
    
    192.168.0.218 | SUCCESS | rc=0 >>
    State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port 
    LISTEN     0      128                       *:35725                    *:*     
    LISTEN     0      128                      :::111                     :::*     
    LISTEN     0      128                       *:111                      *:*     
    LISTEN     0      128                      :::80                      :::*     
    LISTEN     0      128                       *:80                       *:*     
    LISTEN     0      128                      :::22                      :::*     
    LISTEN     0      128                       *:22                       *:*     
    LISTEN     0      128               127.0.0.1:631                      *:*     
    LISTEN     0      128                     ::1:631                     :::*     
    LISTEN     0      100                     ::1:25                      :::*     
    LISTEN     0      100               127.0.0.1:25                       *:*     
    LISTEN     0      128                      :::47546                   :::*     
    
    [root@test ~]#
    

      说明:可看到我们把playbook改编成角色同我们写的playbook执行后的结果是一样的,都实现了同样的功能。

       四、角色调用

      方法一:写好要调用的角色列表

    ---
    - hosts: websers
      remote_user: root
     
      roles:
        - mysql
        - nginx
        - memcached        
    

      说明:此方法同上面示例一样,我们需要调用那些角色,只需要把角色名写在角色列表里即可

      方法二:调用角色的同时给角色传递变量

    ---
    - hosts: websers
      remote_user: root
     
      roles:
        - mysql
        - {role: nginx,username: nginx}                                                                                  
        - memcached
    

      说明:此方法在调用nginx角色的同时,还给nginx角色传递了一个变量和值,role键用于指定角色名,后续可以多个k/v,用于给角色传递变量。

      方法三:基于条件测试实现角色调用

    ---
    - hosts: websers
      remote_user: root
     
      roles:
        - mysql
        - {role: nginx,username: nginx}
        - {role: memcached,when: ansible_distribution_major_version == "7",username: memcached}     
    

      说明:此方法实现了当系统版本为7 的时候才调用memcached角色,换句话说只有在目标系统版本为7 的系统才能调用memchched角色,同时它也可以向脚本传递变量。

      五、roles playbook tags 的使用

    上面角色调用的时候我们介绍了三种方式,事实上我们不仅能给角色传递变量,我们还可以给角色打标签,通过执行playbook 指定标签 就可以实现只执行具有指定标签的角色,如下所示

    ---
    - hosts: websers
      remote_user: root
     
      roles:
        - {role: mysql,tags: ["mysql","db"]}
        - {role: marridb,tags: ["mysql","db"]}
        - {role: nginx,tags: ["nginx","web"],username: nginx}
        - {role: memcached,when: ansible_distribution_major_version == "7",username: memcached}
        - {role: httpd,tags: ["httpd","web"]}
        - {role: php,tags: php}                                                                 
    

      说明:我们在调用角色的时候,我们可以给角色打上多个标签,其作用在于,这样把同类角色打上相同的标签,我们在执行其playbook的时候就可以选择性的执行某些指定标签的角色,比如以上我们执行标签为“web”的角色,我们可以在执行playbook的时候用-t选项指定“web”,这样我们就可以实现只在目标主机上执行httpd和nginx这两个角色的目的。如果我们给一个角色打上多个标签需要写成列表的形式,用中括号把多个标签名给括起来,每个标签之间用逗号隔开,同时需要注意的是,标签上一个字符串,需要用引号将其引起来。

  • 相关阅读:
    南邮OJA题
    Executors工厂类创建线程池的底层实现
    Linux kernel 中的per_cpu宏
    [置顶] 高并发服务器的设计内存池的设计
    数据列表DataList模板之实例
    软件开发无敌心得篇
    嵌入式学习笔记之UART通信协议
    正则表达式 进阶(二)
    11687 Digits
    DELPHI接口转化为COM接口
  • 原文地址:https://www.cnblogs.com/qiuhom-1874/p/11902172.html
Copyright © 2011-2022 走看看