什么是角色:
- 角色可以提高ansible代码的重复利用率,是以通用方式重复的利用Ansible代码,将标准化目录结构中的所有任务、变量、文件、模板打包,将打包好的角色从一个项目复制到另一个项目,随后只需从一个play调用该角色就能执行它。
优点:
- 角色可以分组内容,从而与他人轻松共享代码。
- 可以编写角色来定义系统类型的基本要素:Web服务器、数据库服务器、Git存储库,或满足其他用途。
- 角色使得较大型项目更容易管理。
- 角色可以由不同的管理员并行开发。
1.方式一,从rhel-system-roles软件包获取,是红帽工程师写的系统相关角色。
yum -y install rhel-system-roles
- Ansible角色由子目录和文件的标准化结构定义。顶级目录定义角色本身的名称。文件整理到子目录中,子目录按照各个文件在角色中的用途进行命名,如tasks和handlers。files和templates子目录中包含由其他YAML文件中的任务引用的文件。
- ansible所有子目录如下列表,但并非每个角色都拥有所有这些目录。
子目录 | 功能 |
---|---|
defaults | 此目录中的main.yml文件包含角色变量的默认值,使用角色时可以覆盖这些默认值。这些变量的优先级较低,应该在play中更改和自定义。 |
files | 此目录包含由角色任务引用的静态文件。 |
handlers | 此目录中的main.yml文件包含角色的处理程序定义。 |
meta | 此目录中的main.yml文件包含与角色相关的信息,如作者、许可证、平台和可选的角色依赖项。 |
tasks | 此目录中的main.yml文件包含角色的任务定义。 |
templates | 此目录包含由角色任务引用的Jinja2模板。 |
tests | 此目录可以包含清单和名为test.yml的playbook,可用于测试角色。 |
vars | 此目录中的main.yml文件定义角色的变量值。这些变量通常用于角色内部用途。这些变量的优先级较高,在playbook中使用时不应更改。 |
- 角色示例。
add-service.sh ##新增服务脚本。
ansible.cfg ##ansible配置文件。
group_vars ##角色组。
install-service.yml ##安装服务playbook。
inventory.ini ##清单文件。
setup.sh ##执行脚本入口。
uninstall-service.yml ##卸载服务playbook。
update-service.yml ##升级服务playbook。
roles/ ##角色目录,根据各个微服务定义各个目录,每个目录下存放子目录。
httpd/ ##微服务一。
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
mariadb/ ##微服务二。
tasks/
defaults/
meta/
概念:
- 角色变量在vars/main.yml文件中定义,优先级较高,无法被清单变量覆盖。这些变量旨在供角色的内部功能使用。
- 默认变量在defaults/main.yml文件定义,给playbook中执行的任务提供默认值,优先级最低,会被其他任何变量覆盖。
注意事项:
- 在vars/main.yml或defaults/main.yml中定义具体的变量,但不要在两者中都定义。若有想要覆盖的变量,则将此变量设置为默认变量。
- 角色里不应包含任何机密,如密码或私钥。
- 角色里应该使用变量定义需要变化的值,而不是直接写死。
- 内嵌设置的角色变量(角色参数)优先级非常高,能覆盖大多数其他变量。所以不要重复使用内嵌设置在play中任何其他位置的任何角色变量的名称,因为角色变量的值将覆盖清单变量和任何play中的vars。
- 使用系统角色同步受控机时间。
1.确定要使用的角色,这里使用系统时间角色,将其目录下的所有目录及文件复制到自定义下的角色目录里。
[root@localhost time]# cp -R /usr/share/ansible/roles/rhel-system-roles.timesync .
[root@localhost time]# mv rhel-system-roles.timesync time
2.查看角色说明文档,主要看在playbook中如何使用,还有默认变量和vars目录下的变量。
3.编写playbook,引用角色。
4.执行playbook,查看受控机时间是否被同步。
- 在使用角色之前,playbook中的任务执行流程是先把play执行完,再执行handlers触发程序。使用角色之后,playbook会按照顺序执行所有任务,比如普通play ——> role角色任务 ——> 普通play ——> role角色中的handlers触发程序 ——> 普通play中的handlers触发程序。
- 当然还有两种play,分别为pre_tasks和post_tasks,与普通tasks同级别。
- pre_tasks ,列在此部分中的所有任务将在执行任何角色之前执行。如果这些任务中有任何一个通知了处理程序,则这些处理程序任务也在角色或普通任务之前执行。
- post_tasks ,这些任务在play的普通任务和它们通知的任何处理程序运行之后执行。
- 也可以使用include_role模块和imports_role模块在普通play中引用角色任务。include_role模块是在Ansible 2.3中新增的,而import_role模块则是在Ansible 2.4中新增的。
1.如下playbook种有role任务,普通角色,handlers触发程序。执行顺序为:pre_tasks任务 ——> role角色任务 ——> 普通tasks任务 ——> post_tasks任务 ——>pre_tasks中的handlers处理程序 ——> 普通tasks中的handlers ——> post_tasks中的handlers 。
---
- hosts: all
gather_facts: no
pre_tasks: 不论排序如何,都先执行pre_tasks任务;再执行tasks任务;后执行post_tasks任务
- name: pre_task
debug:
msg: "hehe"
changed_when: True 只有执行任务结果为chenged时,才会通知notify执行handlers
notify:
- insert data
roles:
- ../roles/time
tasks:
- name: task
command: "echo 'haha'"
notify:
- insert data
post_tasks:
- name: post_task
command: "echo 'post'"
notify:
- insert data
handlers:
- name: insert data
shell: "echo 123 >> /tmp/abc" 在abc里写入123,因执行了3遍handlers,所以受控机的abc里应该有3个123
2.如下playbook中,在第2个play任务中引用了角色任务,则整个playbook执行顺序是:普通tasks任务 ——> 引用的角色任务。
---
- hosts: all
tasks:
- name: 普通任务
debug:
msg: "呵呵"
- name: timesync
include_role:
name: roles/timesync
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
名称 | 状态 | 角色描述 |
---|---|---|
rhel-system-roles.kdump | 全面支持 | 配置kdump崩溃恢复服务 |
rhel-system-roles.network | 全面支持 | 配置网络接口 |
rhel-system-roles.selinux | 全面支持 | 配置和管理SELinux自定义,包括SELinux模式、文件和端口上下文、布尔值设置以及SELinux用户 |
rhel-system-roles.timesync | 全面支持 | 使用网络时间协议或精确时间协议配置时间同步 |
rhel-system-roles.postfix | 技术预览 | 使用Postfix服务将每个主机配置为邮件传输代理 |
rhel-system-roles.firewall | 开发中 | 配置主机的防火墙 |
rhel-system-roles.tuned | 开发中 | 配置tuned服务,以调优系统性能 |
1.安装软件包,并更改配置文件角色查找默认路径。
yum -y install rhel-system-roles
[root@localhost roles]# cp -R /usr/share/ansible/roles/rhel-system-roles.timesync time
3.编写playbook。
[root@localhost playbook]# cat time.yml
---
- hosts: all
vars:
timesync_ntp_servers: ##引用角色中定义的变量。
- hostname: time1.aliyun.com
iburst: yes
qingjun_timezone: Asia/Nicosia ##自定义变量。使用命令timedatectl list-timezones查看所有可以设置的时区。
roles:
- time ##因为在ansible配置文件里指定了默认角色路径,所以会直接寻找默认路劲目录下的角色。
tasks:
- name: 同步时间时区
timezone: ##使用模块来定义时间同步时区。
name: "{{ qingjun_timezone }}"
4.执行playbook,受控机查看同步时间。
5.也可以不把变量写在playbook中,根据主机或主机组定义变量,单独写在变量文件中。
##清单文件。
[root@localhost ansible]# cat inventory.ini
[mq]
192.168.130.161 ansible_port=22 ansible_user=root ansible_password="citms@123"
##主机组变量。
[root@localhost ansible]# cat group_vars/mq/time.yml
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
qingjun_timezone: Asia/Shanghai
##playbook。
[root@localhost ansible]# cat playbook/time.yml
---
- hosts: all
roles:
- time
tasks:
- name: 同步时间时区
timezone:
name: "{{ qingjun_timezone }}"
自定义创建角色步骤:
- 创建角色目录结构。
- 定义角色内容。
- 在playbook中使用角色。
查找角色目录优先级为:
1.每个角色具有自己的目录,采用标准化的目录结构。
[root@localhost ~]# tree roles/
roles/
└── motd
├── defaults
│ └── main.yml
├── files ##files子目录包含固定内容的文件。
├── handlers
├── meta
│ └── main.yml ##该文件指定有关模块的作者、许可证、兼容性和依赖项的信息。
├── tasks
│ └── main.yml
└── templates ##templates子目录则包含使用时可由角色部署的模板。
└── motd.j2
2.可以使用命令创建角色目录框架,而不需要手动挨个创建费事。
ansible-galaxy init httpd
- 以下是给受控机安装httpd服务,编写角色思路如下:
- 编写任务,需先确定安装服务过程中需要做什么操作,配置yum源安装服务,修改配置文件,启动服务,若是重启需要配置处理程序。
- 修改配置文件中需要定义变量,因为传到受控机是要改成受控机本机的参数,且在playbook中需要使用template模块,不能copy。
- 配置变量,可以是默认变量,可以根据主机或主机组配置变量,也可以在最后playbook中定义变量,需要整体规划。
- 配置模板文件,一般存放服务配置文件,服务依赖文件等等。
- 配置handlers。
- 编写playbook,指定角色,可以配置变量,最后执行查看结果。
- 当然也可以配置全其他文件,方便其他人学习,比如说明文件md结尾的文件,现在markdown语法软件写好到导进来。配置meta文件,说明编写信息,更新信息等等。
1.创建角色目录架构,对每个目子目录进行内容编写。
ansible-galaxy init httpd
2.编写任务tasks子目录内容,确定整体要做的事情,使用什么模块操作,需要更改配置文件时要使用notify触发handlers处理程序取重启服务。
[root@localhost httpd]# cat tasks/main.yml
---
# tasks file for httpd
- name: 安装httpd
yum:
name: httpd
state: present
- name: 更改配置文件
template:
src: ../templates/httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: 启动服务
service:
name: httpd
state: started
3.配置模板templates/httpd.j2 ,模板里有需要修改的参数就要使用变量。
4.配置默认变量。
[root@localhost httpd]# cat defaults/main.yml
---
# defaults file for httpd
service_name: www.qingjun.com
service_port: 88
5.配置handlers play。
[root@localhost httpd]# cat handlers/main.yml
---
# handlers file for httpd
- name: restart httpd
service:
name: httpd
state: restarted
6.编写playbook,指定任务,可以定义变量。
[root@localhost ansible]# cat playbook/httpd.yml
---
- name: 安装阿帕奇
hosts: all
vars:
service_port: 8080
roles:
- name: 安装阿帕奇
role: ../roles/httpd
编写角色的推荐做法:
- ansible脚本可以基于git存储库在存储,比如github等。
- 若涉及到密码等敏感信息时,可以使用变量存放,可以设置一个简单错误的密码定义成默认变量,当在执行playbook时,再输入正确的变量密码。
- 使用ansible-galaxy init启动角色,然后删除不需要的任何目录和文件。比如没有使用到file目录,可以将其删掉。
- 应该创建并维护README.md和meta/main.yml文件,以记录用户的角色的用途、作者和用法。
- 让角色侧重于特定的用途或功能。可以编写多个角色,而不是让一个角色承担许多任务。
- 把经常重用和重构的任务写成角色,不常重用的任务就单独写在playbook中执行即可。
变量优先级:
- 角色中的vars目录下定义的变量优先级最高,除了事实、通过include_vars加载的变量、注册的变量和角色参数可以覆盖,其他任何文件中定义的变量都无法覆盖这里面的变量。
- playbook中定义的变量优先级第二,会覆盖其他大多数变量文件中的变量。
- group_vars和host_vars变量会覆盖默认变量。
- 角色中的defaults目录下定义默认变量文件,优先级最低。
- 当然也可以使用社区提供的角色,社区连接。
- 除了直接再官网上直接搜索下载,也可以根据–author(用户)、–platforms(平台)、–galaxy-tags(标记)进行搜索角色。
- 搜索出来的角色越靠前,说明编写的质量越高。
1.根据用户搜索,列出他上传的所有角色。
2.根据平台搜索。
[root@localhost ~]# ansible-galaxy info geerlingguy.redis
1.下载单个角色,默认下载到~.ansible/roles目录下,–ignore-errors参数表示忽略错误下载。
ansible-galaxy install geerlingguy.redis --ignore-errors
2.使用-p参数指定下载路径。
ansible-galaxy install 1davidmichael.ansible-role-nginx -p /etc/ansible/roles
3.下载多个角色。可以编辑一个文件,里面列出要下载的角色,通过-r指定下载文件。
[root@localhost roles]# cat requirements.yml
- src: geerlingguy.redis
- src: geerlingguy.apache
[root@localhost roles]# ansible-galaxy install -r requirements.yml -p ./ --ignore-errors
1.列出本机所有角色,只会列出ansible配置文件里指定的角色路径下的所有角色。
2.移除角色,只能移除安装下载的角色,不能移除自己编写和或者复制粘贴进来的角色。
ansible-galaxy remove 1davidmichael.ansible-role-nginx