十三、Ansible Role 详解

发布时间:2024年01月09日

目录

Roles 介绍

一、Roles目录?

1、roles目录结构

?2、roles目录含义

二、roles编写步骤

1、编写roles 的步骤为:

2、roles的调用

3、roles中使用变量

4、多次调用同一个roles

5、roles管理模板文件

6、roles管理handlers文件

7、roles 的依赖关系

8、roles 的相互调用

三、项目示例

1、创建httpd服务的roles(角色)

2、创建nginx服务的roles

3、如果想触发 notify和handlers 这个角色,可以修改配置文件

4、实现条件判断

5、使用标签实现playbook角色的调用

四、总结


Roles 介绍

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

一、Roles目录?

1、roles目录结构

?2、roles目录含义

[root@k8s-master-1 ansible]# tree


├── playbook.yaml        <==执行剧本
├── roles                <==角色必须与执行剧本在同一级目录中
│   ├── mysql            <==项目名称
│   │   ├── default
│   │   │   └── main.yaml
│   │   ├── files
│   │   ├── handlers
│   │   │   └── main.yaml
│   │   ├── meta
│   │   │   └── main.yaml
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   ├── templates
│   │   └── vars
│   └── nginx            <==另一个项目
roles:<--所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在/etc/ansible/roles
  project:<---具体的角色项目名称。比如 nginx、tomcat、mysql
    default: <--角色使用到的变量在此目录中的main.yml文件中,defaults/main.yml文件中的变量都用于设置默认值,以便在没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
      main.yaml
    files:<--角色可能会用到的一些其他文件可以放置在此目录中。或者 用来存放由copy模块或script模块调用的文件。
    handlers:<--此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
      main.yaml
    meta:<--如果想要赋予这个角色一些元数据,则可以将元数据写到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定。
      main.yaml
    tasks: <--此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
      main.yaml
    templates:<--用来存放jinjia2模板,如果没有指定目录,template模块会自动在此目录中寻找jinjia2模板文件。
    vars:<--此目录应当包含一个main.yml文件,用于定义此角色用到的变量。看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
      

二、roles编写步骤

1、编写roles 的步骤为:

  1. 创建roles的项目目录。
  2. 编写roles的功能,也就是tasks;
  3. 最后playbook引用roles编写好的tasks;

示例:

1、先创建roles_test 项目目录结构,并创建下面的子目录,最基本的子目录需要有tasks目录。
[root@k8s-master-1 ansible]# cd roles/
[root@k8s-master-1 roles]# mkdir roles_test
[root@k8s-master-1 roles]# cd roles_test/
[root@k8s-master-1 roles_test]# mkdir tasks
[root@k8s-master-1 roles_test]# cd tasks/
[root@k8s-master-1 tasks]# pwd
/etc/ansible/roles/roles_test/tasks

2、然后在tasks中编写相关的任务,在tasks中必须有一个 main.yaml 文件。可以把编写的任务直接写到 main.yaml 文件中,也可以写到其他文件中,然后在main.yaml中通过 include 的方式引用这些文件。在 tasks 中 不需要写 play 部分,只写tasks部分就行。
[root@k8s-master-1 tasks]# vim main.yaml
- name: test roles
  debug:
    msg: "this is test roles"
------或者----
[root@k8s-master-1 tasks]# vim test.yaml
- name: test roles
  debug:
    msg: "this is test roles"
[root@k8s-master-1 tasks]# vim main.yaml
- include: test.yaml

3、写好之后 编写playbook调用roles,playbook剧本必须要与roles角色在同一目录
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
  remote_user: root

  roles:
  - role: roles_test

4、测试
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml 
ok: [192.168.134.138] => {
    "msg": "this is test roles"
}

2、roles的调用

在playbook调用roles时,如何找到roles所在的目录呢?有以下几种方式:

? ? ? ? 1、playbook文件会在同级目录中寻找与调用的角色同名的roles,例如在上例中,roletest.yaml这个playbook文件调用了roles_test这个角色,会自动在同级目录中寻找roles_test这个目录,并执行其中的tasks。

[root@k8s-master-1 roles]# ll
总用量 2

drwxr-xr-x 3 root root  19 8月   9 09:25 roles_test
-rw-r--r-- 1 root root  68 8月   9 10:08 roletest.yaml

????????2、playbook文件也会寻找同级目录中的roles 目录,执行roles目录中同名的角色项目

[root@k8s-master-1 ansible]# tree 
.

├── roles


│   └── roles_test
│       └── tasks
│           ├── main.yaml
│           └── test.yaml
├── roletest.yaml

????????3、也可以修改ansible配置文件中定义的roles的路径,多个路径之间使用冒号 :隔开

roles_path    = /etc/ansible/roles:/data/ansible/roles:/opt 

????????4、在playbook文件中,直接写roles的绝对路径也可以调用

[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
  remote_user: root

  roles:
  - role: /etc/ansible/roles/roles_test

3、roles中使用变量

? ? ? ? 修改roles文件,引入变量

1、[root@k8s-master-1 ansible]# vim roles/roles_test/tasks/test.yaml
- name: test roles
  debug:
    msg: "{{ var }}"

2、在调用这个角色时,则需要传入对应的变量,否则就会报错,调用上例角色的示例如下:
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
  remote_user: root

  roles:
  - role: roles_test

  vars:
  - var: test vars
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml 
ok: [192.168.134.138] => {
    "msg": "test vars"
}

-----或者----  变量定义在vars文件中
3、也可以为变量设置默认值,这样即使在调用角色时没有传入任何参数,也有默认的值可以使用,同时也不会在调用时因为没有传入对应变量而报错,需要在roles_test目录中创建一个defaults目录/vars 目录,并且创建defaults/main.yml文件/vars/main.yaml文件,文件内容如下:
[root@k8s-master-1 roles_test]# mkdir vars
[root@k8s-master-1 roles_test]# cd vars/
[root@k8s-master-1 vars]# vim main.yaml
var: test abc

4、然后在运行playbook,结果一样
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
ok: [192.168.134.138] => {
    "msg": "test abc"
}
结论:变量的优先级
ansible-playbook > vars/main.yaml > 其他变量定义的方式

4、多次调用同一个roles

默认情况下,我们无法多次调用同一个角色,也就是说,如下playbook只会调用一测role角色:

[root@k8s-master-1 ansible]# cat roletest.yaml 
---
- hosts: web
  remote_user: root

  roles:
  - role: roles_test
  - role: roles_test
执行上边的playbook,会发现roles_test 的debug 模块只输出了一次,如果想多次调用同一个角色,有两种方法:

1、设置角色的 allow_duplicates 属性,让其支持重复使用
[root@k8s-master-1 roles_test]# mkdir meta
[root@k8s-master-1 ansible]# cat roles/roles_test/meta/main.yaml 
allow_duplicates: true

2、调用角色时,传入不同的参数
先把vars 文件中的main.yaml 定义的变量注释掉
然后在playbook中添加变量

  roles:
  - role: roles_test
    vars:
      var: 123
  - role: roles_test
    vars:
      var: test vars
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml 
TASK [roles_test : test roles] *******************************************************************
ok: [192.168.134.138] => {
    "msg": 123
}

TASK [roles_test : test roles] **********************************************************************
ok: [192.168.134.138] => {
    "msg": "test vars"
}

5、roles管理模板文件

前文中提到,roles中把所有的模板文件放置到templates 目录中,我么来测试下:

1、新增template 目录,建立模板文件
[root@k8s-master-1 roles_test]# mkdir templates
[root@k8s-master-1 templates]# vim temp.j2
something in template;
{{ template_var }}

2、tasks/main.yaml 如下:
- name: test roles
  debug:
    msg: "{{ var }}"

- name: copy template
  template:
    src: temp.j2
    dest: /tmp/temp

3、变量文件如下:
var: test abc 
template_var: tempvar

4、playbook文件如下:
---
- hosts: web
  remote_user: root

  roles:
  - role: roles_test
[root@k8s-master-1 ansible]# ansible-playbook  roletest.yaml
TASK [roles_test : test roles] **************************************************************************
ok: [192.168.134.138] => {
    "msg": "test abc"
}

TASK [roles_test : copy template] ***********************************************************************
changed: [192.168.134.138]

6、roles管理handlers文件

如果想要在角色中使用一些handlers 以便进行触发,则可以直接将对应的handlers 任务写到 handlers/main.yaml文件中

1、创建handlers 目录
[root@k8s-master-1 roles_test]# mkdir handlers
[root@k8s-master-1 handlers]# vim main.yaml
- name: test_handlers
  debug:
    msg: "this is a test handler"

2、编辑tasks任务
[root@k8s-master-1 tasks]# vim main.yaml
- name: test roles
  debug:
    msg: "{{ var }}"
  changed_when: true
  notify: test_handlers

3、把之前测试template 的变量注释掉

4、运行playbook文件
[root@k8s-master-1 ansible]# ansible-playbook -C roletest.yaml 
TASK [roles_test : test roles] *******************************************************************************
changed: [192.168.134.138] => {
    "msg": "test abc"
}

RUNNING HANDLER [roles_test : test_handlers] ********************************************************************************
ok: [192.168.134.138] => {
    "msg": "this is a test handler"
}

7、roles 的依赖关系

????????roles 允许在使用时自动引入其他roles,role 依赖关系存储在meta/main.yaml文件中

示例:

安装WordPress 项目时:
1、需要先确保 nginx 与 php-fpm的role 都能正常运行;

2、然后在WordPress的role中定义,依赖关系;

3、依赖的role 有nginx 以及 php-fpm;

4、 在WordPress的role中新街meta 目录,编写main.yaml文件
[root@k8s-master-1 meta]# vim main.yaml
dependencies:
  - { role: nginx }
  - { role: php-fpm }

5、在WordPress的playbook中就不需要在安装 nginx 和php-fpm了,只写一个 WordPress就可以了,安装WordPress之前会自动先部署 nginx和php-fpm
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
  remote_user: root

  roles:
  - role: WordPress

8、roles 的相互调用

????????roles 中的各项目之间的文件是可以跨项目相互调用的。跨项目调用时,需要指明要调用的role的名称。

示例:

要同时部署nginx 和apache 两个项目,这俩项目使用了相同的index.hetm主页文件,这个主页文件已经在nginx项目中定义过了,若此时需要在Apache项目中引用,使用如下方式
[root@localhost  /data/roles]$vim apache/tasks/html.yml      <==页面配置
- name: Copy Index File 
  copy: 
    src:roles/nginx/files/index.html    #跨项目调用路径要写roles的名称
    dest: /var/www/nginx/html/   

三、项目示例

1、创建httpd服务的roles(角色)

1、创建项目目录,httpd
[root@k8s-master-1 roles]# mkdir httpd

2、创建roles相关目录
[root@k8s-master-1 httpd]# mkdir tasks files vars
[root@k8s-master-1 httpd]# cd tasks/

3、创建用户组
[root@k8s-master-1 tasks]# vim group.yaml
- name: create group
  group:
    name: apache
    state: present
    system: yes
    gid: 80

4、创建用户
[root@k8s-master-1 tasks]# vim user.yaml
- name: create user
  user:
    name: apache
    group: apache
    state: present
    uid: 80
    system: yes
    shell: /sbin/nologin
    home: /usr/share/httpd

5、安装httpd包
[root@k8s-master-1 tasks]# vim install.yaml
- name: yum httpd
  yum:
    name: httpd
    state: installed

6、在files目录下,创建配置文件 httpd.conf文件。将httpd.conf配置文件的端口修改为9527:
[root@k8s-master-1 files]# vim httpd.conf
Listen 9527

7、创建一个网页文件,用于验证当前信息
[root@k8s-master-1 files]# vim index.html
<h1> welcome to beijing! </h1>

8、将创建的配置文件复制到被管理端主机上
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
  copy:
    src: httpd.conf
    dest: /etc/httpd/conf
    backup: yes

9、将创建的index.html数据复制到/var/www/html目录下,相当于是给页面准备一个文件:
[root@k8s-master-1 tasks]# vim data.yaml
- name: copy data file
  copy:
    src: index.html
    dest: /var/www/html/

10、创建服务文件
[root@k8s-master-1 tasks]# vim service.yaml
- name: started service
  service:
    name: httpd
    state: started
    enabled: yes

11、将任务按顺序编排到main.yaml 文件中
[root@k8s-master-1 tasks]# vim main.yaml 
- include: group.yaml
- include: user.yaml
- include: install.yaml
- include: copy.yaml
- include: service.yaml
- include: data.yaml

12、编写playbook,用来调用httpd整个目录下的内容。注意:需要与roles 是同级目录
[root@k8s-master-1 ansible]# vim httpd_roles.yaml
---
- hosts: web
  remote_user: root

  roles:
  - role: httpd

13、当前项目目录结构
[root@k8s-master-1 ansible]# tree roles/httpd/
roles/httpd/
├── files
│   ├── httpd.conf    // 配置文件
│   └── index.html    // html 文件
├── tasks    
│   ├── copy.yaml    
│   ├── data.yaml
│   ├── group.yaml
│   ├── install.yaml
│   ├── main.yaml
│   ├── service.yaml
│   └── user.yaml
└── vars

14、执行playbook
[root@k8s-master-1 ansible]# ansible-playbook -C httpd_roles.yaml 
PLAY [web] ****************************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [192.168.134.138]

TASK [httpd : create group] ***********************************************************
changed: [192.168.134.138]

TASK [httpd : create user] **************************************************************
changed: [192.168.134.138]

TASK [yum httpd] *****************************************************************
changed: [192.168.134.138]

TASK [httpd : copy file] *******************************************************************
changed: [192.168.134.138]

TASK [httpd : started service] ****************************************************************
changed: [192.168.134.138]

TASK [httpd : copy data file] ********************************************************************
changed: [192.168.134.138]

PLAY RECAP *********************************************************************************
192.168.134.138     : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@k8s-master-1 ansible]# 
ok 没有问题

2、创建nginx服务的roles

1、将之前httpd的子目录都复制一份到nginx目录下
[root@k8s-master-1 roles]# cp -r httpd ./nginx

2、修改main.yaml 文件
[root@k8s-master-1 tasks]# vim main.yaml 
- include: install.yaml
- include: copy.yaml
- include: service.yaml
- include: data.yaml

3、删除不需要的文件
[root@k8s-master-1 tasks]# rm -rf group.yaml user.yaml

4、将安装的文件和启动的文件 name修改成nginx

5、修改copy.yaml文件改成使用template 模板的方式修改
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

6、在本地下载一个nginx ,并将配置文件拷贝到 templates目录下
[root@k8s-master-1 nginx]# mkdir tamplates
[root@k8s-master-1 nginx]# yum -y install nginx
[root@k8s-master-1 templates]# cp /etc/nginx/nginx.conf ./nginx.conf.j2

7、修改nginx.conf.j2配置文件的CPU内核
user nginx;
worker_processes {{ ansible_processor_count*3 }};

8、跨角色调用httpd服务的文件内容
[root@k8s-master-1 tasks]# vim data.yaml 
- name: copy data file
  copy:
    src: roles/httpd/files/index.html
    dest: /usr/share/nginx/html/

9、编写playbook文件
[root@k8s-master-1 ansible]# vim nginx_roles.yaml 
---
- hosts: web
  remote_user: root

  roles:
  - role: nginx

10、执行playbook
[root@k8s-master-1 ansible]# ansible-playbook  nginx_roles.yaml
PLAY [web] ***********************************************

TASK [Gathering Facts] ***********************************
ok: [192.168.134.138]

TASK [nginx : yum nginx] *********************************
changed: [192.168.134.138]

TASK [nginx : copy file] ********************************
changed: [192.168.134.138]

TASK [nginx : started service] *************************
changed: [192.168.134.138]

TASK [nginx : copy data file] **************************
changed: [192.168.134.138]

PLAY RECAP *********************************************
192.168.134.138        : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

11、查看进程
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ps -ef |grep nginx'
192.168.134.138 | CHANGED | rc=0 >>
root      13623      1  0 14:41 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx     13624  13623  0 14:41 ?        00:00:00 nginx: worker process
nginx     13625  13623  0 14:41 ?        00:00:00 nginx: worker process
nginx     13626  13623  0 14:41 ?        00:00:00 nginx: worker process

12、查看端口
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ss -nlt'

13、浏览器访问
http://192.168.134.138:80

3、如果想触发 notify和handlers 这个角色,可以修改配置文件

1、修改copy任务的配置文件,添加notify,如果文件有更改就触发
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart_nginx

2、创建handlers文件,并添加main.yaml文件
[root@k8s-master-1 nginx]# mkdir handlers
[root@k8s-master-1 nginx]# vim main.yaml
- name: restart_nginx
  service:
    name: nginx
    state: restarted

3、为了验证效果 我们把配置文件端口改成8080,并且将nginx配置文件的名称,以变量的方式传递
[root@k8s-master-1 templates]# vim nginx.conf.j2 
user {{ username }};
    server {
        listen       8080;
        listen       [::]:8080;

4、创建变量目录和main.yaml文件
[root@k8s-master-1 vars]# vim main.yaml
username: daemon

4、执行playbook,并查看端口 已改为8080,查看用户一改为 daemon
[root@k8s-master-1 ansible]# ansible-playbook nginx_roles.yaml
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ss -lnt'
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ps -aux |grep nginx'

4、实现条件判断

5、使用标签实现playbook角色的调用

1、修改playbook文件
[root@k8s-master-1 ansible]# vim nginx_roles.yaml
---
- hosts: web
  remote_user: root

  roles:
  - {role: nginx,tags: ["nginx","test1"]}
  - {role: mysql,tags: db}
2、[root@k8s-master-1 ansible]# ansible-playbook  -t nginx nginx_roles.yaml 
3、最后  卸载nginx
[root@k8s-master-1 ansible]# ansible web -m yum -a 'name=nginx state=absent'

四、总结

1、编写任务(tasks)时候,里面不需要写需要执行的主机,单纯的写某个任务是干什么的即可,装软件就写装软件的,启动就写启动的,单独做某一件事即可,最后通过main.yaml将这些单独的任务按照执行顺序 include 进来即可。这样方便维护,且一目了然。

2、定义变量时,直接按照 K: V 的格式在vars/main.yaml文件写即可,然后tasks或者template直接调用就行,会自动去var/main.yaml文件里找。

3、定义handlers时,直接在handlers/main.yaml文件中写需要做的事情即可,多的话可以写在该文件里,也可向像tasks那样写多个文件,然后include 引入。在task调用notify时,两者名字必须一致

4、模板文件放在templates目录下,tasks调用直接写文件名就行,会自动去template 目录下找。注意:如果一个角色调用另一个角色的任务的时候,那么tasks中有些模板或者文件,就得些绝对路径了。

文章来源:https://blog.csdn.net/weixin_42171272/article/details/135334766
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。