目录
一、角色roles的介绍
1.1 关于include
1.2 角色概念
1.3 角色与include区别
1.4 案例
二、使用角色roles
2.1 创建roles的步骤
2.2 角色roles内各目录中可用的文件
2.3 Roles目录结构
三、例子
3.1 建立必要的角色roles目录
3.2 配置nginx角色前准备
3.3 相关yaml配置文件分析
3.3.1 创建安装nginx
3.3.2 创建网站目录及上传文件
3.3.3 修改nginx配置并重启的yaml配置文件
3.3.4 最终目录结构
3.4 相关的yaml配置代码
3.4.1 任务相关yaml配置
3.4.2 变量配置
3.4.3 handlers配置
3.4.4 配置playbooks运行文件
3. 5 执行效果
ansible角色是它的精华所在,进行中大型部署的时候需要用上,简单的playbooks已经不能满足要求。
roles角色对功能进了步细化,把playbooks进行拆分,重用一些功能。好比一个小快餐店和一个酒楼的区别。当规模小的时候两三个人就搞定了,当规模大了,那么就要团队了。roles就相当于团队式的配置管理了。
相关知识可以看一下ansible官网的Roles和ansible权威指南的playbook角色
当我们刚开始学习运用 playbook 时,可能会把 playbook 写成一个很大的文件,到后来可能你会希望这些文件是可以方便去重用的,所以需要重新去组织这些文件。
基本上,使用 include 语句引用 task 文件的方法,可允许你将一个配置策略分解到更小的文件中。使用 include 语句引用 tasks 是将 tasks 从其他文件拉取过来。因为 handlers 也是 tasks,所以你也可以使用 include 语句去引用 handlers 文件。handlers 文件来自 ‘handlers:’ section。
Playbook 同样可以使用 include 引用其他 playbook 文件中的 play。这时被引用的 play 会被插入到当前的 playbook 中,当前的 playbook 中就有了一个更长的的 play 列表。
当你开始思考这些概念:tasks, handlers, variables 等等,是否可以将它们抽象为一个更大的概念呢。我们考虑的不再是”将这些 tasks,handlers,variables 等等应用到这些 hosts 中”,而是有了更抽象的概念,比如:”这些 hosts 是 dbservers” 或者 “那些 hosts 是 webservers”(译者注:dbserver,webservers 即是”角色”)。这种思考方式在编程中被称为”封装”,将其中具体的功能封装了起来。举个例子,你会开车但并不需要知道引擎的工作原理(译者注:同样的道理,我们只需要知道”这些 hosts 是 dbservers”,而不需要知道其中有哪些 task,handlers 等)。
Roles 的概念来自于这样的想法:通过 include 包含文件并将它们组合在一起,组织成一个简洁、可重用的抽象对象。这种方式可使你将注意力更多地放在大局上,只有在需要时才去深入了解细节。
我们将从理解如何使用 include 开始,这样你会更容易理解 roles 的概念。但我们的终极目标是让你理解 roles,roles 是一个很棒的东西,每次你写 playbook 的时候都应该使用它。
在 ansible-examples 中有很多实例,如果你希望深入学习可以在单独的页面打开它。
PS:
通俗理解:当playbook 写得很大的时候,发现有些东西可以重用,变成一部分功能,就像编程的模块化,这样用的是时候引用就行了。我们把“tasks, handlers, variables 等”独立出来,把它弄成一个“模块”把这个“模块”起一个名字叫roles(角色),当我们用到的时候可以用include 把这个roles引进来。
比如我们安装LNMP,并不是每一个机子会安装nginx、mysql、php吧,这样我们就可以LNMP分为3个角色,叫nginx、mysql、php并制定默认版本,这样当我们引入nginx角色的时候就会按nginx角色制定好的nginx yum源、nginx版本、配置文件等按照nginx角色的设置好。
同理include “mysql”和“php”角色也是一样
这样角色化的好处就是可以重要使用,需要什么就弄进什么角色即可,还可以传参实现个性化。
相对Includes功能,Roles更适合于大项目Playbook的编排架构。简而言之,Ad-Hoc适合用临时命令的执行,Playbook合适中小项目,而大项目一定使用Roles.
一个roles的案例如下所示:
site.yml
webservers.yml
dbservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
而在playbook中,可以这样使用roles:
---
- hosts: webservers
roles:
- common
- webservers
这个 playbook 为一个角色 ‘x’ 指定了如下的行为:
- 如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
- 如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
- 如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
- 如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
- 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
- 所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
- 所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
- 所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。
也可以向roles传递参数,例如:
---
- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/opt/a', port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', port: 5001 }
甚至也可以条件式地使用roles,例如:
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" }
Roles主要依赖于目录的命名和摆放,默认tasks/main.yml是所有任务的入口,所以使用Roles的过程可以理解为目录规范化命名的过程。
每个目录下均由main.yml定义该功能的任务集,asks/main.yml默认执行所有指定的任务。Roles的调用文件playbook_role.yml的内容如下:
---
- hosts: all
roles:
- role_name
Roles目录可以摆放在/etc/ansible/ansible.cfg中“roles_path”中(yum安装默认为/etc/ansible/roles)也可以和入口Playbook文件放在同级目录,Ansible对些没有强制要求。但建议将代码存放在代码机预先规划的目录,以便管理。
(1) 创建以roles命名的目录;
(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;
(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;
(4) 在playbook文件中,调用各角色;
目录 |
作用 |
---|---|
tasks |
至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件; |
files |
存放由copy或script等模块调用的文件; |
templates |
template模块会自动在此目录中寻找Jinja2模板文件; |
handlers |
此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中; |
vars |
应当包含一个main.yml文件,用于定义此角色用到的变量; |
meta |
应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系; ansible 1.3及其以后的版本才支持; |
default |
为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件; |
roles: <--所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在/etc/ansible/roles
project: <---具体的角色项目名称,比如nginx、tomcat、php
files: <--用来存放由copy模块或script模块调用的文件。
templates: <--用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。
tasks: <--此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
main.yml
handlers: <--此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
main.yml
vars: <--此目录应当包含一个main.yml文件,用于定义此角色用到的变量。
main.yml
defaults: <--此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。
main.yml
meta: <--此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。
main.yml
现在我建立一个nginx角色,主要功能用nginx官网rpm包,用yum方式安装nginx并简单配置一个目录。
#因前几章我使用了vm821安装了nginx ,所以要卸载一下之前在vm821安装安过的nginx。
#卸载之前的nginx
yum remove nginx* -y
#删除之前的配置文件及网站的index.html文件
rm -rf /etc/nginx
rm -f /disk1/www/hualinux.com/index.html
hosts配置如下:
[root@vm82 ~]# egrep -v '^$|^#' /etc/ansible/hosts
[hua]
192.168.3.21
[h1]
192.168.3.76
#按照roles角色的规则创建相关目录
cd /etc/ansible/
mkdir -pv roles/nginx/{tasks,files,templates,handlers,vars,meta,default}
tree roles
#查看目录结构
[root@master ansible]# tree roles
roles
└── nginx
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
PS:在这里我没有用到模板,到后面学到Jinja2的时候再用会更好。
因为要用到centos8和centos7的,rpm包不一样,nginx配置文件是一样的,index.html文件也设置一样吧
#1 下载rpm文件
#进行nginx角色专业放文件的地方
cd /etc/ansible/roles/nginx/files/
#下载centos7的nginx rpm包
wget http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.18.0-1.el7.ngx.x86_64.rpm
#下载centos8的nginx rpm包
wget http://nginx.org/packages/rhel/8/x86_64/RPMS/nginx-1.18.0-1.el8.ngx.x86_64.rpm
#2 nginx配置文件
nginx配置文件我《ansible 剧本Playbooks(一) 介绍、组件及使用》的时候,已经复制一了个默认配置文件default.conf,只修改了root目录,关键修改部分如下:
#只修改了root目录
location / {
root /disk1/www/hualinux.com;
index index.html index.htm;
}
#3.创建index.html文件
#创建index.html文件
cat>index.html<Welcome to hualinux
EOF
#4.nginx角色所涉及的文件浏览
这样nginx所涉及的目录如下
#文件所以的目录,为nginx角色的files
[root@vm82 files]# pwd
/etc/ansible/roles/nginx/files
[root@vm82 files]# ll
总用量 1588
-rw-r--r-- 1 root root 1095 9月 11 21:16 default.conf
-rw-r--r-- 1 root root 29 9月 11 21:20 index.html
-rw-r--r-- 1 root root 790284 4月 21 23:19 nginx-1.18.0-1.el7.ngx.x86_64.rpm
-rw-r--r-- 1 root root 825436 9月 11 21:12 nginx-1.18.0-1.el8.ngx.x86_64.rpm
[root@vm82 files]# cd ~
[root@vm82 ~]#
如何编写nginx角色相关的配置文件呢,一般是安装流程来,这里使用的是nginx安装流程,按我们传统的手工安装流程一般如下:
安装nginx我选择是复制对应的rpm文件,并以yum方式安装,这样速度会快很多,安装完之后启动nginx并设置开机启动。
软件的安装目录统一放在/disk1/tools中,对应的配置文件为 roles/nginx/tasks/install.yml
目录我统一放在/disk1/www/hualinux.com中,我这里只有一个index.html文件,对应的yaml文件为roles/nginx/tasks/siteFiles.yml
nginx安装完之后一般会修改一下配置文件重启重启nginx,这里也是对应的配置文件为 roles/nginx/tasks/conf.yml
最终的目录结构如下:
#查看nginx角色目录结构
[root@vm82 ansible]# tree roles/nginx/
roles/nginx/
├── default
├── files #主要是nginx相关的文件,有rpm包、配置文件、网站文件
│ ├── default.conf
│ ├── index.html
│ ├── nginx-1.18.0-1.el7.ngx.x86_64.rpm
│ └── nginx-1.18.0-1.el8.ngx.x86_64.rpm
├── handlers #主要是执行启动和重启
│ └── main.yml
├── meta
├── tasks
│ ├── conf.yml #3.修改nginx配置文件
│ ├── install.yml #1. 以yum方式安装rpm包
│ ├── main.yml #主文件
│ └── siteFiles.yml #2.网站相关文件
├── templates
└── vars
└── main.yml #变量相关,为了提交效率,实现重用
任务主配置文件:roles/nginx/tasks/main.yml
#任务的主配置文件,是按nginx传统安装流程编写配置的
[root@vm82 ~]# cat /etc/ansible/roles/nginx/tasks/main.yml
# 复制文件文件,如果对应的目录不存在此ansible版本会自动创建
# 如果不自动创建的请手工创建一下/disk1/www/hualinux.com
#
# 1.复制对应的rpm并使用yum安装rpm
- include: install.yml
# 2.复制网站文件
- include: siteFiles.yml
# 3.复制配置文件并重启
- include: conf.yml
nginx安装处理:roles/nginx/tasks/install.yml
[root@vm82 ~]# cat /etc/ansible/roles/nginx/tasks/install.yml
# 创建放软件的目录
- name: create {
{ install_dir }}
file:
path: "{
{ install_dir }}"
state: directory
recurse: yes
owner: root
group: root
# when和模块是同级的,判断系统版本及主版本
# 判断是否来centos7
- copy:
src: /etc/ansible/roles/nginx/files/nginx-1.18.0-1.el7.ngx.x86_64.rpm
dest: "{
{ install_dir }}"
when: (ansible_distribution=="CentOS") and (ansible_distribution_major_version=="7")
# 判断是否为centos8
- copy:
src: /etc/ansible/roles/nginx/files/nginx-1.18.0-1.el8.ngx.x86_64.rpm
dest: "{
{ install_dir }}"
when: (ansible_distribution=="CentOS") and (ansible_distribution_major_version=="8")
# yum安装
- name: yum install nginx on centos7
yum:
name: /disk1/tools/nginx-1.18.0-1.el7.ngx.x86_64.rpm
state: present
notify: start nginx
when: (ansible_distribution=="CentOS") and (ansible_distribution_major_version=="7")
- name: yum install nginx on centos8
yum:
name: /disk1/tools/nginx-1.18.0-1.el8.ngx.x86_64.rpm
state: present
notify: start nginx
when: (ansible_distribution=="CentOS") and (ansible_distribution_major_version=="8")
网站文件类处理:roles/nginx/tasks/siteFiles.yml
#主要是创建网站目录、复制网站文件
[root@vm82 ~]# cat /etc/ansible/roles/nginx/tasks/siteFiles.yml
# 创建目录并把权限修改为nginx,yum安装默认用户是nginx
- name: create site dir
file:
path: /disk1/www/hualinux.com
state: directory
recurse: yes
owner: nginx
group: nginx
- copy:
src: /etc/ansible/roles/nginx/files/index.html
dest: /disk1/www/hualinux.com
修改nginx配置:roles/nginx/tasks/conf.yml
[root@vm82 ~]# cat /etc/ansible/roles/nginx/tasks/conf.yml
#复制配置文件
- copy:
src: /etc/ansible/roles/nginx/files/default.conf
dest: /etc/nginx/conf.d/default.conf
notify: restart nginx
为了实现重用,提高工作效率我我把重复出现的部分提出来,使用变量的方式。配置如下:
[root@vm82 ~]# cat /etc/ansible/roles/nginx/vars/main.yml
install_dir: /disk1/tools
我这时的 handlers主要是nginx启动和重启
#nginx启动及加入开机运行、重启
[root@vm82 ~]# cat /etc/ansible/roles/nginx/handlers/main.yml
- name: restart nginx
service:
name: nginx
state: restarted
- name: start nginx
service:
name: nginx
state: started
enabled: yes
# 在配置文件中以角色的方式配置,我使用了cneotos8和centos7两个主机组
# YAML配置文件我统一放在/etc/ansible/yaml-conf 目录中
[root@vm82 ~]# cat /etc/ansible/yaml-conf/nginx_roles.yml
---
- hosts:
- hua
- h1
roles:
- nginx
ansible-playbook /etc/ansible/yaml-conf/nginx_roles.yml
#执行效果如下:
[root@vm82 ~]# ansible-playbook /etc/ansible/yaml-conf/nginx_roles.yml
PLAY [hua,h1] ******************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [192.168.3.76]
ok: [192.168.3.21]
TASK [nginx : create /disk1/tools] *********************************************************************************
ok: [192.168.3.76]
ok: [192.168.3.21]
TASK [nginx : copy] ************************************************************************************************
skipping: [192.168.3.21]
changed: [192.168.3.76]
TASK [nginx : copy] ************************************************************************************************
skipping: [192.168.3.76]
changed: [192.168.3.21]
TASK [yum install nginx on centos7] ********************************************************************************
skipping: [192.168.3.21]
changed: [192.168.3.76]
TASK [yum install nginx on centos8] ********************************************************************************
skipping: [192.168.3.76]
changed: [192.168.3.21]
TASK [nginx : create site dir] *************************************************************************************
changed: [192.168.3.76]
changed: [192.168.3.21]
TASK [nginx : copy] ************************************************************************************************
changed: [192.168.3.76]
changed: [192.168.3.21]
TASK [nginx : copy] ************************************************************************************************
changed: [192.168.3.76]
changed: [192.168.3.21]
RUNNING HANDLER [restart nginx] ************************************************************************************
changed: [192.168.3.76]
changed: [192.168.3.21]
RUNNING HANDLER [start nginx] **************************************************************************************
changed: [192.168.3.76]
changed: [192.168.3.21]
PLAY RECAP *********************************************************************************************************
192.168.3.21 : ok=9 changed=7 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
192.168.3.76 : ok=9 changed=7 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
访问一下nginx网站看一下效果,发现都没有问题。