角色
一、利用角色构造ansible playbook
随着开发更多的playbook,会发现有很多机会重复利用以前编写的playbook中的代码。或许,一个用于为某一应用配置MySQL数据库的play可以改变用途。通过利用不同的主机名、密码和用户来为另一个应用配置MySQL数据库。
但在现实中,这个play可能比较冗长且复杂,有许多包含或导入的文件,以及用于管理各种情况的任务和处理程序。将所有这些代码复制到另一playbook种可能并不简单。
ansible提供了一种方法,能以通用的方式更加轻松地重复利用ansible代码。可以在标准化目录结构中打包所有的任务、变量、文件、模板,以及调整基础架构或部署应用所需的其他资源。只需通过复制相关的目录,将角色从一个项目复制到另外一个项目。然后,只需从一个play调用该角色就能执行。
借助编写好的角色,可以从playbook中向角色传递调整其行为的变量,设置所有站点相关的主机名、IP地址、用户名,或其他在本地需要的具体详细信息。例如,部署数据库服务器的角色可能已编写为支持多个变量,这些变量用于设置主机名、数据库管理员用户和密码,以及需要为安装进行自定义的其他参数。角色的作者也可以确保在选择不在play中设置变量值时,为这些变量设定合理的默认值。
ansible角色具有下列优点:
\1. 角色可以分组内容,从而与他人轻松共享代码
\2. 可以编写角色来定义系统类型的基本要素:Web服务器、数据库服务器、Git存储库,或满足其他用途
\3. 角色使得较大型项目更容易管理
\4. 角色可以由不同的管理员并行开发
除了自行编写、使用、重用和共享角色以外,还可以从其他来源获取角色。一些角色以及包含在rhel-system-rolses软件包中,作为红帽企业Linux的一部分。可以从ansible Galaxy网站获取由社区提供支持的许多角色。
检查ANSIBLE角色结构
ansible角色由字幕了和文件的标准化结构定义。顶级目录定义角色本身的名称。文件整理到子目录中,子目录按照各个文件在角色中的用途进行命名,如tasks和handlers。files和templates子目录中包含其他YAML文件中的任务引用的文件。
Defaults:此目录中的main.yml文件包含角色变量的默认值,使用角色时可以覆盖这些默认值。这些变量的优先级较低,应该在play中更改和自定义。
Files:此目录包含由角色任务引用的静态文件
Handlers:此目录中的main.yml文件包含角色的处理程序定义,也就是触发器的内容。
Meta:此目录中的main.yml文件包含与角色相关的信息,如作者、许可证、平台和可选的角色的依赖项。
Tasks: 此目录中的mian.yml文件包含角色的任务定义。
Template: 此目录包含由角色任务引用的jinja2模板(j2模板)
Tests:此目录可以包含清单和test.yml剧本,可用于测试角色
Vars:此目录的文件定义角色的变量值,这些变量通常用于角色内部用途,这些变量的优先级较高,在中使用时不应更改
在playbook中使用ansible角色
在playbook中使用角色非常简单。
- name: test
hosts: node1
roles:
-
role1
-
role2
对于每个指定的角色,角色任务、角色处理程序、角色变量和角色依赖项将按照顺序导入到playbook中。角色中的任何copy、script、template或include_tasks/import_tasks任务都可引用角色中相关的文件、模板或任务文件,且无需相对或绝对路径名称。ansible将分别在角色的files、templates或tasks子目录中寻找他们。
如果使用roles部分将角色导入到play中,这些角色会为该play定义的任何任务之前运行。
以下示例设置ws的角色变量a1和a2的值,使用ws角色时,任何defaults和vars变量都会被覆盖。
1、创建角色
[student@master roles]$ ansible-galaxy init ws
- Role ws was created successfully
2、在vars里给角色定义变量
---
# vars file for ws
a1: 11
a2: 22
~
3、在tasks目录中的main.yml中写角色的任务
---
# tasks file for ws
- name: test1
debug:
msg: "{{ a1 }}"
4、在/home/student/ansible/目录下创建一个test.yml的playbook来使用ws角色
---
- name: test11
hosts: node1
roles:
- ws
此时会发现,我们能够调用角色vars目录下main.yml定义的变量可以被调用
[student@master ansible]$ ansible-playbook test.yml
PLAY [test11] ******************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [node1]
TASK [ws : test1] **************************************************************************************
ok: [node1] => {
"msg": 11
}
PLAY RECAP *********************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5、在test.yml的playbook中来定义变量
---
- name: test111
hosts: node1
roles:
- role: ws
a1: 333
6、执行test.yml,就会发现test.yml中定义的a1变量覆盖了角色中vars目录中定义的变量。
[student@master ansible]$ ansible-playbook test.yml
PLAY [test111] *****************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [node1]
TASK [ws : test1] **************************************************************************************
ok: [node1] => {
"msg": 333
}
PLAY RECAP *********************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
控制执行顺序
对于playbook中的每个play,任务按照任务列表中的顺序来执行,执行完所有任务后,将执行任何通知的处理程序。
在角色添加到play后,角色任务将添加到任务列表的开头。如果play中包含第二个角色,其任务列表添加到第一个角色之后。
角色处理程序添加到play中的方式与角色任务添加到play中相同。每个play定义一个处理程序列表。角色处理程序先添加到处理程序列表,后跟play的handlers部分中定义的任何处理程序。
在某些情形中,可能需要在角色之前执行一些play任务。可以为play配置pre_tasks部分。列在此部分中的所有任务将在执行任何角色之前执行。如果这些任务中有任何一个通知了处理程序,则这些处理程序任务也在角色或普通任务之前执行。
此外,play也支持post_tasks关键字。这些任务在play的普通任务和他们通知的任何处理程序之后执行。
如:
---
- name: test111
hosts: node1
roles:
- role: ws
a1: 333
pre_tasks:
- name: test2
debug:
msg: 00000
[student@master ansible]$ ansible-playbook test.yml
PLAY [test111] *****************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [node1]
TASK [test2] *******************************************************************************************
ok: [node1] => {
"msg": 0
}
TASK [ws : test1] **************************************************************************************
ok: [node1] => {
"msg": 333
}
PLAY RECAP *********************************************************************************************
node1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
执行该playbook,我们发现pre_tasks任务在角色之前执行的
示例:
示例:创建和使用角色
根据下列要求,在/home/student/ansible/roles中创建名为http的角色
1、部署yum仓库
2、安装httpd软件包
3、模板文件index.html.j2已存在,用户创建具有以下输出的文件/var/www/html/index.html:
Welcome to HOSTNAME on IPADDRESS
当index.html内容发生改变时,重启httpd服务
其中HOSTNAME是受控节点的完全合格域名,IPADDRESS则是受控节点的IP地址
按照上方所述,创建一个使用此角色的playbook /home/student/ansible/newrole.yml,该playbook在node1主机上运行。
步骤
1、创建http角色
[student@master roles]$ ansible-galaxy init httpd
- Role httpd was created successfully
2、根据要求新建index.html.j2模板
Welcome to {{ ansible_default_ipv4.address }} on {{ ansible_hostname }}
3、在/etc/ansible/roles/http/tasks/main.yml书写角色任务内容
---
# tasks file for httpd
- name: baseos
yum_repository:
name: aa
description: aa1
baseurl: http://ansible.example.com/rhel9/BaseOS
enabled: yes
gpgcheck: no
- name: appstream
yum_repository:
name: bb
description: bb1
baseurl: http://ansible.example.com/rhel9/AppStream
enabled: yes
gpgcheck: no
- name: install httpd firewalld
yum:
name:
- httpd
- firewalld
state: present
- name: cp html
template:
src: index.html.j2
dest: /var/www/html/index.html
- name: restart httpd firewalld
service:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
- httpd
- firewalld
- name: set firewalld
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
4、书写/home/student/ansible/newrole.yml
playbook,运行http角色
---
- name: test
hosts: node1
roles:
- httpd
5、执行该playbook
[student@master ansible]$ ansible-playbook newrole.yml
PLAY [test] ********************************************************************************************
TASK [Gathering Facts] *********************************************************************************
ok: [node1]
TASK [httpd : baseos] **********************************************************************************
ok: [node1]
TASK [httpd : appstream] *******************************************************************************
ok: [node1]
TASK [httpd : install httpd firewalld] *****************************************************************
ok: [node1]
TASK [httpd : cp html] *********************************************************************************
changed: [node1]
TASK [httpd : restart httpd firewalld] *****************************************************************
changed: [node1] => (item=httpd)
changed: [node1] => (item=firewalld)
TASK [httpd : set firewalld] ***************************************************************************
changed: [node1]
PLAY RECAP *********************************************************************************************
node1 : ok=7 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
6、验证:
[student@master ansible]$ curl http://node1
Welcome to 192.168.122.10 on node1
二、系统角色
1、安装系统角色
[student@master ansible]$ sudo yum -y install rhel-system-roles
2、rhel系统角色
Rhel-system-roles.kdump 配置kdump崩溃恢复服务
Rhel-system-roles.network 配置网络接口
Rhel-system-roles.selinux 配置和管理selinux(selinux模式 文件和端口上下文、布尔值 )
Rhel-system-roles.timesync 配置时钟同步
Rhel-system-roles.postfix 使用postfix服务将每个主机配置为邮件传输代理
Rhel-system-roles.firewall 配置主机的防火墙
Rhel-system-roles.tuned 配置tuned服务,以调优系统性能
3、RHEL系统角色位于/usr/share/ansible/roles/目录下
示例:
安装 RHEL 系统角色软件包,并创建符合以下条件的playbook /home/student/ansible/timesync.yml:
在所有受管节点上运行
使用 timesync 角色
配置该角色,以使用当前有效的 NTP 提供商
配置该角色,以使用时间服务器 [ansible.example.com]
配置该角色,以启用iburst 参数
1、安装系统角色
sudo yum -y install rhel-system-roles
2、将时钟同步的系统角色复制到/etc/ansible/roles目录下,并重名了角色名为timesync
[student@master ansible]$ cp -r rhel-system-roles.timesync -p /home/student/ansible/roles/timesync
3、书写playbook。
---
- name: test
hosts: all
vars:
timesync_ntp_servers:
- hostname: ansible
iburst: yes
roles:
- timesync
4.改ansible主机chrony配置文件
allow 192.168.122.0/24
# Serve time even if not synchronized to a time source.
local stratum 10
5.执行
[student@master ansible]$ ansible-playbook timesync.yml
[student@master ansible]$ ansible node2 -m shell -a 'chronyc sources'
node2 | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* ansible.example.com 3 6 17 1 -171us[ -488us] +/- 54ms
三、从ansible-galaxy安装角色
ansible-galaxy install子命令从Ansible Galaxy下载角色,并将它站桩到控制节点本地。
默认情况下,角色安装到用户的roles_path下的第一个可写目录中。根据ansible设置的默认roles_path,角色通常安装到用户的~/.ansible/roles目录。默认的roles_path可能会被当前的ansible配置文件或环境变量ANSIBLE_ROLES_PATH覆盖,这将影响ansible-galaxy的行为。
可以使用-p DIRECTORY选项,指定具体的目录来安装角色。
安装角色
1、首先在roles目录下书写一个playbook,把需要安装角色的路径定义到playbook中
---
- name: haproxy
src: http://ansible.example.com/roles/haproxy.tar
- name: myphp
src: http://ansible.example.com/roles/myphp.tar
2、使用ansible-galaxy命令安装角色
[student@master ansible]$ ansible-galaxy install -r roles/test.yml -p roles/
Starting galaxy role install process
- downloading role from http://ansible.example.com/roles/haproxy.tar
- extracting haproxy to /home/student/ansible/roles/haproxy
- haproxy was installed successfully
- downloading role from http://ansible.example.com/roles/myphp.tar
- extracting myphp to /home/student/ansible/roles/myphp
- myphp was installed successfully
管理下载的角色
ansible-galaxy命令也可管理本地的角色,如位于playbook项目的roles目录中的角色。ansible-galaxy list子命令列出本地找到的角色。
[student@master ansible]$ ansible-galaxy list
# /home/student/ansible/roles
- ws, (unknown version)
- httpd, (unknown version)
- timesync, (unknown version)
- haproxy, (unknown version)
- myphp, (unknown version)
可以使用ansible-galaxy
remove子命令本地删除角色
[student@master ansible]$ ansible-galaxy remove myphp
- successfully removed myphp
[student@master ansible]$ ansible-galaxy list
# /home/student/ansible/roles
- ws, (unknown version)
- httpd, (unknown version)
- timesync, (unknown version)
- haproxy, (unknown version)