目录
ansible角色是它的精华所在,进行中大型部署的时候需要用上,简单的playbooks已经不能满足要求。
roles角色对功能进了步细化,把playbooks进行拆分,重用一些功能。好比一个小快餐店和一个酒楼的区别。当规模小的时候两三个人就搞定了,当规模大了,那么就要团队了。roles就相当于团队式的配置管理了。
相关知识可以看一下ansible官网的Roles和ansible权威指南的playbook角色
一、角色roles的介绍
1.1 关于include
当我们刚开始学习运用 playbook 时,可能会把 playbook 写成一个很大的文件,到后来可能你会希望这些文件是可以方便去重用的,所以需要重新去组织这些文件。
基本上,使用 include 语句引用 task 文件的方法,可允许你将一个配置策略分解到更小的文件中。使用 include 语句引用 tasks 是将 tasks 从其他文件拉取过来。因为 handlers 也是 tasks,所以你也可以使用 include 语句去引用 handlers 文件。handlers 文件来自 ‘handlers:’ section。
Playbook 同样可以使用 include 引用其他 playbook 文件中的 play。这时被引用的 play 会被插入到当前的 playbook 中,当前的 playbook 中就有了一个更长的的 play 列表。
1.2 角色概念
当你开始思考这些概念: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”角色也是一样
这样角色化的好处就是可以重要使用,需要什么就弄进什么角色即可,还可以传参实现个性化。
1.3 角色与include区别
相对Includes功能,Roles更适合于大项目Playbook的编排架构。简而言之,Ad-Hoc适合用临时命令的执行,Playbook合适中小项目,而大项目一定使用Roles.
1.4 案例
一个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
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对些没有强制要求。但建议将代码存放在代码机预先规划的目录,以便管理。
2.1 创建roles的步骤
(1) 创建以roles命名的目录;
(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;
(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;
(4) 在playbook文件中,调用各角色;
2.2 角色roles内各目录中可用的文件
目录 | 作用 |
---|---|
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文件; |
2.3 Roles目录结构
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
3.1 建立必要的角色roles目录
#按照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的时候再用会更好。
3.2 配置nginx角色前准备
因为要用到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<<EOF
<h2>Welcome to hualinux</h2>
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 ~]#
3.3 相关yaml配置文件分析
如何编写nginx角色相关的配置文件呢,一般是安装流程来,这里使用的是nginx安装流程,按我们传统的手工安装流程一般如下:
3.3.1 创建安装nginx
安装nginx我选择是复制对应的rpm文件,并以yum方式安装,这样速度会快很多,安装完之后启动nginx并设置开机启动。
软件的安装目录统一放在/disk1/tools中,对应的配置文件为 roles/nginx/tasks/install.yml
3.3.2 创建网站目录及上传文件
目录我统一放在/disk1/www/hualinux.com中,我这里只有一个index.html文件,对应的yaml文件为roles/nginx/tasks/siteFiles.yml
3.3.3 修改nginx配置并重启的yaml配置文件
nginx安装完之后一般会修改一下配置文件重启重启nginx,这里也是对应的配置文件为 roles/nginx/tasks/conf.yml
3.3.4 最终目录结构
最终的目录结构如下:
#查看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 #变量相关,为了提交效率,实现重用
3.4 相关的yaml配置代码
3.4.1 任务相关yaml配置
任务主配置文件: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
3.4.2 变量配置
为了实现重用,提高工作效率我我把重复出现的部分提出来,使用变量的方式。配置如下:
[root@vm82 ~]# cat /etc/ansible/roles/nginx/vars/main.yml
install_dir: /disk1/tools
3.4.3 handlers配置
我这时的 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
3.4.4 配置playbooks运行文件
# 在配置文件中以角色的方式配置,我使用了cneotos8和centos7两个主机组
# YAML配置文件我统一放在/etc/ansible/yaml-conf 目录中
[root@vm82 ~]# cat /etc/ansible/yaml-conf/nginx_roles.yml
---
- hosts:
- hua
- h1
roles:
- nginx
3. 5 执行效果
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网站看一下效果,发现都没有问题。