美文网首页
06 Ansible Roles

06 Ansible Roles

作者: 运维开发_西瓜甜 | 来源:发表于2020-08-17 13:54 被阅读0次

    本文链接: https://www.jianshu.com/p/905cf0e51968
    作者:闫立行

    一、 Ansible Roles 介绍

    一个数据中心有可能存在好多类型的服务器。比如WEB类型、DB类型、开发人员使用的开发类型、QA使用的测试类型等等。

    实际生产中,基本每个类型的服务器的初始化行为都不一致。

    那要在一个PlayBook中将这些动作完成,这个PlayBook将变得臃肿、庞大,且难以后续维护和更新。

    如果能够针对每个类型的服务器单独编写PlayBook,最后通过某种方式整合这PlayBook, 在管理方式上就又会变得简单。

    Ansible中提供了类似的概念,也就是Role。它允许管理员将他们复杂的PlayBook分解成一个个小的逻辑单元, 以便于维护和管理。

    二、 Roles 结构

    1. ROLE 是什么呢

    先看一个示例:

    webservers/
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    └── vars
        └── main.yml
    

    从表面上看,它就是一个目录。目录的名字也就是role的名字,示例中,role 的名字叫做 webservers
    进到这个role名字的目录里,会发现好多子目录。

    使用时,每个目录必须包含一个main.yml文件,这个文件应该包含如下目录名称对应的内容:

    • tasks -包含角色要执行的任务的主要列表。
    • handlers -包含处理程序,此角色甚至该角色之外的任何地方都可以使用这些处理程序。
    • defaults-角色的默认变量。
    • vars-角色的其他变量。
    • files -包含可以通过此角色部署的文件。
    • templates -包含可以通过此角色部署的模板。
    • meta-为此角色定义一些元数据。

    角色必须至少包含这些目录之一,但是最好排除任何未使用的目录。

    三、 制作一个Role

    我们将上文经过最终优化的PlayBook,分解成一个Role。 那么应该如何操作呢?

    最终优化的PlayBook

    - name: template playbook example
      hosts: webservers
      vars:
        createuser:
          - tomcat
          - www
          - mysql
      tasks:
        - name: create user
          user: name={{ item }} state=present
          with_items: "{{ createuser }}"
    
        - name: yum nginx webserver
          yum: name=nginx state=present
    
          # use ansible template
        - name: update nginx main config
          template: 
            src: nginx.conf.j2
            dest: /etc/nginx/nginx.conf
          tags: updateconfig
          notify: reload nginx server
          
        - name: add virtualhost config
          copy:
            src: www.qfedu.com.conf
            dest: /etc/nginx/conf.d/
          tags: updateconfig
          notify: reload nginx server
          
        - name: check nginx syntax
          shell: /usr/sbin/nginx -t
          register: nginxsyntax
          tags: updateconfig
          
        - name: check nginx running
          stat: path=/var/run/nginx.pid
          register: nginxrunning
          tags: updateconfig
            
        - name: print nginx syntax
          debug: var=nginxsyntax
          
        - name: start nginx server
          service: name=nginx state=started
          when:
            - nginxsyntax.rc == 0
            - nginxrunning.stat.exists == false
      handlers:
        - name: reload nginx server
          service: name=nginx state=started
          when:
            - nginxsyntax.rc == 0
            - nginxrunning.stat.exists == true
    

    分解这个PlayBook,命名role 的名字为 nginx

    nginx/
    │
    ├── files
    ├── handlers
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    └── vars
        └── main.yml
    

    files 文件夹存放文件

    存放 www.qfedu.com.conf 配置文件
    

    handlers 文件夹中的main.yml 文件

    ---
    - name: reload nginx server
      service: name=nginx state=started
      when: nginxsyntax.rc == 0 and nginxrunning.stat.exists == true
    

    tasks 文件夹中的 main.yml 文件

    ---
    - name: create user
      user: name={{ item }} state=present
      with_items: "{{ createuser }}"
    
    - name: yum nginx webserver
      yum: name=nginx state=present
    
      # use ansible template
    - name: update nginx main config
      template: 
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      tags: updateconfig
      notify: reload nginx server
      
    - name: add virtualhost config
      copy:
        src: www.qfedu.com.conf
        dest: /etc/nginx/conf.d/
      tags: updateconfig
      notify: reload nginx server
      
    - name: check nginx syntax
      shell: /usr/sbin/nginx -t
      register: nginxsyntax
      tags: updateconfig
      
    - name: check nginx running
      stat: path=/var/run/nginx.pid
      register: nginxrunning
      tags: updateconfig
        
    - name: print nginx syntax
      debug: var=nginxsyntax
      
    - name: start nginx server
      service: name=nginx state=started
      when:
        - nginxsyntax.rc == 0
        - nginxrunning.stat.exists == false
    ...
    

    templates 文件夹存放模板

    存放 nginx.conf.j2 模板
    

    vars 文件夹中的 main.yml 文件

    ---
    createuser:
      - tomcat
      - www
      - mysql
    

    经过以上对PlayBook 的拆分,就形成了一个nginx 的 ROLE。
    回到本章开始的问题,当一个数据中心存在多种类型的服务器时,我们可以针对每个类型去单独写一个ROLE,这些ROLE 有可能分给不同的人去开发,这样不但使开发的逻辑变得简单,且开发效率也随着人员的增加而提升。

    四、如何在PlayBook中使用 Role

    Role 本身不能被直接执行,还是需要借助PlayBook进行间接的调用。
    
    - name: a playbook used role
      hosts: all
      roles:
        - nginx
    

    五、使用角色

    1. 经典(原始)方式

    在 playbook 中给定 roes:属性

    - name: use  role
      hosts: webservers
      roles:
        - webservers
    

    2. 新方式

    在 playbook 中给定 import_role 属性
    这种方式适用于 Ansible 2.4及以上

    - name: use rose
      hosts: webservers
      tasks:
        - debug:
          msg: "before we run our role"
        - import_role:
            name: webservers
        - debug:
            msg: "after we ran our role"
    

    六、如何使用 Galaxy

    Ansible的galaxy 工具,类似程序员使用的github。运维人员可以将自己编写的Role通过galaxy这个平台进行分享。同样,我们也可以通过galaxy 这个平台去获取一些我们想要的role。官网为:https://galaxy.ansible.com
    而ansible-galaxy 则是一个使用 galaxy 命令行的工具。它使我们不用访问galaxy 的网站而获取到需要的内容。
    接下来我们将通过 ansible-galaxy 这个命令行去学习galaxy的使用。

    获取帮助

    # ansible-galaxy  --help
    Usage: ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
    
    Options:
      -h, --help     show this help message and exit
      -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                     debugging)
      --version      show program's version number and exit
    

    获取具体某个子指令的帮助

    在 ansible-galaxy  --help 中可以看到子指令
    子指令包含: delete|import|info|init|install|list|login|remove|search|setup
    ansible-galaxy delete|import|info|init|install|list|login|remove|search|setup --help
    
    # ansible-galaxy install --help
    Usage: ansible-galaxy install [options] [-r FILE | role_name(s)[,version] | scm+role_repo_url[,version] | tar_file(s)]
    
    Options:
      -f, --force           Force overwriting an existing role
      -h, --help            show this help message and exit
      -c, --ignore-certs    Ignore SSL certificate validation errors.
      -i, --ignore-errors   Ignore errors and continue with the next specified
                            role.
      -n, --no-deps         Don't download roles listed as dependencies
      -r ROLE_FILE, --role-file=ROLE_FILE
                            A file containing a list of roles to be imported
      -p ROLES_PATH, --roles-path=ROLES_PATH
                            The path to the directory containing your roles. The
                            default is the roles_path configured in your
                            ansible.cfg file (/etc/ansible/roles if not
                            configured)
      -s API_SERVER, --server=API_SERVER
                            The API server destination
      -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                            connection debugging)
      --version             show program's version number and exit
    

    常用指令

    // 在galaxy 上搜索共享的ROLE
    # ansible-galaxy search
    // 安装 galaxy 上共享的 ROLE
    # ansible-galaxy install
    // 列举已经通过 ansible-galaxy 工具安装的ROLE
    # ansible-galaxy list
    // 创建一个ROLE 的空目录架构, 这样我们在开发一个ROLE的时候,就不需要手动创建目录了。
    # ansible-galaxy init --offline
    

    Example

    // 创建了名字为testrole的空ROLE目录结构,默认在执行命令的目录生产。
    # ansible-galaxy init  testrole
    # tree testrole/
    testrole/
    ├── defaults
    │   └── main.yml
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── tests
    │   ├── hosts
    │   └── test.yml
    └── vars
        └── main.yml
    
    1.2 动态资产

    动态资产, -i 参数后面接的是一个可运行的脚本。脚本的结果为一个 Ansible 可理解的 JSON 格式字符串。

    为什么要存在动态资产呢? 往往我们在使用 Ansible 管理服务器前,公司中有可能已经将服务器信息存储在了特定位置,比如 CMDB, 数据库等系统。
    此时若我们再使用静态资产去管理服务器,势必会造成资产管理入口不统一的问题。
    
    因此我们只能抛弃原先的静态资产,通过脚本从已存在的系统中获取要管理的节点,并按照特定的形式传给 Ansible。这样既解决了公司资产统一入口, 也解决了Ansible 的服务器管理来源。
    

    动态资产实例

    {
      "_meta": {
        "hostvars": {
          "192.168.100.10": {
            "host_var": "hoge"
          },
          "192.168.100.20": {
            "host_var": "fuga"
          }
        }
      },
      "sampledb_servers": {
        "hosts": [
          "192.168.100.10",
          "192.168.100.20"
        ],
        "vars": {
          "group_var": "hogefuga"
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:06 Ansible Roles

          本文链接:https://www.haomeiwen.com/subject/dzwtvhtx.html