美文网首页学习
3. Ansible Role

3. Ansible Role

作者: 随便写写咯 | 来源:发表于2021-02-11 19:10 被阅读0次

    4 Roles

    角色可用于层次性, 结构化组织playbook. 角色能够根据层次型结构自动装载变量文件, tasks以及handlers等
    要想使用角色, 只需要在playbook中使用include指令即可.
    roles就是通过分别将变量, 文件, 任务, 模板及处理器放置于单独的目录中, 并可以便捷地include它们的一种机制
    角色一般用于基于主机构建服务的场景, 也可以用于构建守护进程等场景
    
    在复杂场景中, 可以使用roles来做编排, 代码复用性高
    

    roles: 可以作为多个服务的集合, 把多个服务, 分别放置到roles目录下的独立子目录

    roles/
      mysql/
      nginx/
      tomcat/
      redis/
    

    4.1 Ansible Roles 目录编排

    roles目录结构: 每个角色, 以特定得层级目录结构进行组织

    roles structure

    roles 目录架构

    playbook1.yml  # 在playbook中去调用角色中的项目
    playbook2.yml
    roles/
      project1/
          tasks/
          files/
          vars/
          templates/
          handlers/
          default/
          meta/
      project2/
          tasks/
          files/
          vars/ 
          templates/
          handlers/
    

    角色中每个目录的作用

    roles/project: 项目名称, 有以下子目录

    • files/: 存放由copy或script模块等调用的文件
    • templates/: template模块查找所需要模板文件的目录
    • tasks/: 定义task, role的基本元素, 至少应该包含一个名为main.yml的文件; 其他的文件需要此文件中通过include进行包含
    • handlers/: 至少应该包含一个名为main.yml的文件; 其他的文件需要在此文件中通过include进行包含
    • vars/: 定义变量, 至少应该包含一个名为main.yml的文件; 其他的文件需要在此文件中通过include进行包含
    • meta/: 定义当前角色的特殊设定, 及其依赖关系, 至少应该包含一个名为main.yml的文件, 其他文件需要在此文件中通过include包含
    • default/: 设定默认变量时使用此目录中的main.yml文件, 比vars的优先级低

    4.2 create role

    创建role的步骤

    1. 创建目录roles
    2. 在roles目录中分别创建以各自角色名称命名的目录, 如webservers等
    3. 在每个角色命令的目录中分别创建files, handlers, tasks, templates和vars等目录, 用不到的目录可以创建为空目录, 也可以不创建
    4. 在playbook文件中, 调用各角色
    

    针对大型目录使用Roles进行编排

    eg: roles的目录结构

    [02:29:51 root@ansible /data/files]#tree roles 
    roles
    └── nginx
        ├── files
        │   └── main.yml
        ├── tasks
        │   ├── groupadd.yml
        │   ├── install.yml
        │   ├── main.yml
        │   ├── restart.yml
        │   └── useradd.yml
        └── vars
            └── main.yml
    

    4.3 playbook中调用角色

    调用角色方法1:

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

    调用角色方法2:

    键role用于指定角色名称, 后续的k/v用于传递变量给角色
    
    ---
    - hosts: websrvs
      remote_user: root
      roles:
        - mysql
        - { role: nginx, username: nginx} 
    

    调用角色方法3:

    还可基于条件测试实现角色调用
    
    ---
    - hosts: websrvs
      remote_user: root
      roles:
        - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' } 
    

    4.4 roles中使用tags

    [02:32:26 root@ansible /data/files]#vim role.yml
    
    ---
    - hosts: websrvs
      remote_user: root
      roles:
        - { role: nginx, tags: [ 'nginx', 'web' ], when: ansible_distribution_major_version == '6'}
        - { role: httpd, tags: [ 'httpd', 'web' ] }
        - { role: httpd, tags: [ 'mysql', 'web'] }
        - { role: mariadb, tags: [ 'mariadb', 'db'] }   
    
    [02:40:16 root@ansible /data/files]#ansible-playbook   --tags="nginx,httpd,mysql" role.yml
    

    4.5 实战案例: 实现httpd角色

    1. 创建角色相关目录
    [15:48:11 root@Ansible ~]#mkdir -pv /data/ansible/roles/httpd/{tasks,files}
    mkdir: created directory '/data/ansible/roles/httpd'
    mkdir: created directory '/data/ansible/roles/httpd/tasks'
    mkdir: created directory '/data/ansible/roles/httpd/files'
    
    1. 创建角色相关文件
    [15:48:32 root@Ansible ~]#cd /data/ansible/roles/httpd
    

    main.yml是tasks的入口文件, 定义了多个tasks的执行顺序. 把每个task的yml文件单独创建在tasks目录下, 用main.yml去调用并且按照顺序执行

    [15:49:02 root@Ansible /data/ansible/roles/httpd]#vim tasks/main.yml
    
    - include: group.yml
    - include: user.yml
    - include: install.yml
    - include: config.yml
    - include: mkdir.yml
    - include: index.yml
    - include: service.yml   
    

    创建group.yml

    [15:59:31 root@Ansible /data/ansible/roles/httpd]#vim tasks/group.yml
    ---
    - name: "创建apache用户组"
      group: name=apache system=yes gid=80   
    

    创建user.yml

    [16:04:58 root@Ansible /data/ansible/roles/httpd]#vim tasks/user.yml
    ---
    - name: "创建apache用户"
      user: name=apache system=yes shell=/sbin/nologin home=/var/www uid=80 group=apache 
    

    创建install.yml

    [16:09:15 root@Ansible /data/ansible/roles/httpd]#vim tasks/install.yml
    ---
    - name: "安装httpd包"
      yum: name=httpd                                                                                                                                  
    

    创建config.yml

    准备一个apache配置文件模板放在httpd/files目录下

    DocumentRoot "/data/html"
    
    <Directory "/data/html"> 
    
    [03:03:14 root@Ansible /data/ansible/roles/httpd/files]#ls
    httpd.conf  index.html
    
    [16:28:41 root@Ansible /data/ansible/roles/httpd]#vim tasks/config.yml 
    
    ---
    - name: "拷贝配置文件"   # src不用写全路径, 直接写文件名即可, 可以自动找到
      copy: src=httpd.conf dest=/etc/httpd/conf backup=yes
    

    创建mkdir.yml, 用来创建必要的目录

    [16:20:32 root@Ansible /data/ansible/roles/httpd]#vim tasks/mkdir.yml
    
    ---
    - name: "创建目录"
      file: path=/data/html state=directory  
    

    创建index.yml

    准备index.html文件, 放在httpd/files目录下

    [16:13:54 root@Ansible ~]#echo "httpd website based on ansible" > /data/ansible/roles/httpd/files/index.html
    
    [16:20:56 root@Ansible /data/ansible/roles/httpd]#vim tasks/index.yml
    
    - name: index.html
      copy: src=index.html dest=/data/html 
    

    创建service.yml

    [16:21:59 root@Ansible /data/ansible/roles/httpd]#vim tasks/service.yml 
    ---
    - name: httpd service
      service: name=httpd state=started enabled=yes 
    

    创建调用roles的文件, 该文件和roles目录平级

    [02:54:54 root@Ansible /data/ansible/]#vim role_httpd.yml
    
    ---
    - hosts: 10.0.0.86
      gather_facts: no
      remote_user: root
    
      roles:
        - httpd 
    

    执行剧本

    ansible-playbook role_httpd.yml
    
    PLAY RECAP ***************************************************************************************************************************************************************
    10.0.0.86                  : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    1. 下面通过handler和notify实现配置文件修改后能重启服务
    [16:08:48 root@Ansible /data/ansible/roles/httpd]#mkdir handlers
    [16:08:53 root@Ansible /data/ansible/roles/httpd]#ls
    files  handlers  tasks
    
    [16:48:13 root@Ansible /data/ansible/roles]#vim httpd/handlers/main.yml
    - name: restart httpd
      service: name=httpd state=restarted  
    

    修改config.yml

    [16:57:16 root@Ansible /data/ansible/roles]#vim httpd/tasks/config.yml 
    
    - name: config
      copy: src=/data/ansible/roles/httpd/files/httpd.conf dest=/etc/httpd/conf
      notify: restart httpd    
    

    修改httpd/files目录下的配置文件,监听端口号

    Listen 8080
    

    重新执行role_httpd.yml

    RUNNING HANDLER [restart httpd] ******************************************************************************************************************************************
    changed: [10.0.0.86]
    
    PLAY RECAP ***************************************************************************************************************************************************************
    10.0.0.86                  : ok=8    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

    验证端口号修改即可

    [17:04:14 root@Ansible /data/ansible/roles]#curl 10.0.0.86:8080
    httpd website based on ansible
    
    1. 下面实现配置文件模板
    [17:05:46 root@Ansible /data/ansible/roles]#mkdir httpd/templates
    

    把配置文件从files目录移动到templates里, 并添加.j2后缀. 利用j2模板生成配置文件,而不用统一的配置文件了

    [17:05:50 root@Ansible /data/ansible/roles]#mv httpd/files/httpd.conf httpd/templates/httpd.conf.j2
    

    修改j2模本文件的监听端口

    Listen {{ listen_port }}
    

    在主机清单中定义主机变量, 实现利用j2模板, 不同的服务器能监听不同的端口

    [websrvs]
    10.0.0.85 listen_port=9090  # 把10.0.0.85也加入到部署列表, 实现根据不同变量, 生成配置文件
    10.0.0.86 listen_port=7070 
    

    修改config.yml文件

    - name: config
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf # 利用j2模本后, 这里要写全路径和文件名, 否则j2文件拷贝到被管理节点, 还是.j2结尾, 配置文件并不会被修改.                                                        
      notify: restart httpd
    

    修改role_httpd.yml文件, 添加10.0.0.85

    [16:25:31 root@Ansible /data/ansible/]#vim role_httpd.yml 
    
    ---
    - hosts: websrvs                                                                                                                                                          
      gather_facts: no
      remote_user: root
    
      roles:
        - httpd
    

    执行剧本, 验证

    [17:15:34 root@Ansible ~]#curl 10.0.0.86:7070
    httpd website based on ansible
    [17:15:37 root@Ansible ~]#curl 10.0.0.85:9090
    httpd website based on ansible
    

    注意: 角色中利用vars目录定义的变量是比主机变量优先级高的, 如果定义了主机变量, 又定义了vars变量, 那么vars的会优先生效

    命令行变量 > vars变量 > 主机变量

    案例: 验证统一vars变量的优先级高于主机变量

    1. 添加vars变量
    [17:17:45 root@Ansible /data/ansible/roles/httpd]#ls
    files  handlers  tasks  templates
    [17:17:45 root@Ansible /data/ansible/roles/httpd]#mkdir vars
    [17:17:47 root@Ansible /data/ansible/roles/httpd]#vim vars/main.yml
    
    listen_port: 8888   
    
    2. 执行剧本
    [17:17:41 root@Ansible ~]#curl 10.0.0.85:8888
    httpd website based on ansible
    [17:20:47 root@Ansible ~]#curl 10.0.0.86:8888
    httpd website based on ansible
    
    3. 由此可以看到, 统一的vars变量优先级高于主机变量, 不过这样就无法实现根据不同的服务器生成不同的配置文件了
    

    或者也可以在playbook中调用when条件判断, 实现不同主机监听不同端口号

    1. 在files目录下准备两个配置文件
    [17:26:24 root@Ansible /data/ansible/roles/httpd/files]#ls
    httpd_85.conf  httpd_86.conf  index.html
    
    1. 修改config.yml文件, 实现基于ip地址拷贝不同的配置文件
    [17:46:57 root@Ansible /data/ansible/roles]#vim httpd/tasks/config.yml 
    
    ---
    - name: "拷贝10.0.0.85配置文件"
      copy: src=httpd_85.conf dest=/etc/httpd/conf/httpd.conf backup=yes
      when: ansible_default_ipv4['address'] == "10.0.0.85"
      notify: restart httpd
    
    - name: "拷贝10.0.0.86配置文件"
      copy: src=httpd_86.conf dest=/etc/httpd/conf/httpd.conf backup=yes
      when: ansible_default_ipv4['address'] == "10.0.0.86"                                                                                                                              
      notify: restart httpd
    
    1. 验证
    [17:48:16 root@Ansible ~]#curl 10.0.0.85:85
    httpd website based on ansible
    [17:53:20 root@Ansible ~]#curl 10.0.0.86:86
    httpd website based on ansible
    

    补充: 如果希望复用文件, 比如在apache和nginx间复用默认页面, 只需要把文件拷到不同的roles文件夹里即可, 或者直接从roles目录开始找httpd的index.html文件, src=roles/httpd/files/index.html, 即可实现复用默认页面. 不过其他的配置文件还是要修改的

    1. 创建目录
    [17:56:53 root@Ansible /data/ansible/roles]#mkdir -pv nginx/{tasks,files}
    mkdir: created directory ‘nginx’
    mkdir: created directory ‘nginx/tasks’
    mkdir: created directory ‘nginx/files’
    
    1. 创建tasks/main.yml文件
    [17:58:49 root@Ansible /data/ansible/roles]#vim nginx/tasks/main.yml
    
    - include: install.yml
    - include: config.yml
    - include: index.yml                                                                                                                                                                
    - include: service.yml
    
    1. 准备以上4个文件
    [17:59:28 root@Ansible /data/ansible/roles]#cp httpd/tasks/install.yml nginx/tasks
    [17:59:58 root@Ansible /data/ansible/roles]#cp httpd/tasks/config.yml nginx/tasks
    [18:00:02 root@Ansible /data/ansible/roles]#cp httpd/files/index.yml nginx/files
    [18:00:06 root@Ansible /data/ansible/roles]#cp httpd/tasks/service.yml nginx/tasks
    
    1. 编辑install文件
    [18:01:01 root@Ansible /data/ansible/roles/nginx/tasks]#vim install.yml 
    
    ---
    - name: "安装nginx包"
      yum: name=nginx  
    
    1. 编辑config文件
    [18:26:25 root@Ansible /data/ansible/roles/nginx/tasks]#vim config.yml 
    ---
    - name: "拷贝10.0.0.85配置文件"
      copy: src=nginx_885.conf dest=/etc/nginx/nginx.conf backup=yes
      when: ansible_default_ipv4['address'] == "10.0.0.85"
    
    
    - name: "拷贝10.0.0.86配置文件"
      copy: src=nginx_886.conf dest=/etc/nginx/nginx.conf backup=yes
      when: ansible_default_ipv4['address'] == "10.0.0.86"                                                                                                                              
    
    
    
    1. 编辑service文件
    [18:28:45 root@Ansible /data/ansible/roles/nginx/tasks]#vim service.yml 
    
    ---
    - name: "start nginx"                                                                                                                                                               
      service: name=nginx state=started enabled=yes
    
    1. 准备两个nginx配置文件
    [18:21:35 root@Ansible ~]#vim /data/ansible/roles/nginx/files/nginx_885.conf
        server {
            listen       885 default_server;
            listen       [::]:885 default_server; 
    
    [18:22:27 root@Ansible ~]#vim /data/ansible/roles/nginx/files/nginx_886.conf
        server {
            listen       886 default_server;
            listen       [::]:886 default_server; 
    
    1. 编辑index.yml
    [18:49:34 root@Ansible /data/ansible/roles/nginx/tasks]#vim index.yml 
    
    ---
    - name: index.html
      copy: src=roles/httpd/files/index.html dest=/data/html 
    # 由于需要复用httpd的页面, 因此, 需要指定src路径, 从roles开始既可以找到index.html, 因为, 执行playbook就是在roles同级目录执行的
    
    1. 准备nginx的role文件
    [18:51:14 root@Ansible /data/ansible/roles]#cp role_httpd.yml role_nginx.yml
    [18:51:25 root@Ansible /data/ansible/roles]#vim role_nginx.yml 
    
    ---
    - hosts: websrvs
      remote_user: root
      
      roles:
        - nginx  
    

    相关文章

      网友评论

        本文标题:3. Ansible Role

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