Roles
概念
- 由来:ansible自动化运行,基础由AD-Hoc命令来完成,在命令变多时,产生了playbook进行管理任务,简单任务使用playbook可以轻松处理,但是有复杂任务时单个playbook不可以胜任了,这时需要把多个playbook进行组合,少量用include将剧本中任务互相关联即可完成,但是playbook还在增多的情况时就不方便管理了,这时引入roles对playbook进行有效组织就十分必要了
- Roles:角色,是ansible自1.2版本开始引入的新特性
- 目的:用于层次性,结构化地组织playbook,roles能够根据层次型结构自动装载变量、文件、任务、模块及触发器
- 方法:roles通过分别将放置于变量、文件、任务、模块及触发器单独的目录中,并可以便捷地include它们的一种机制
- 应用:角色一般用于基于主机构建服务的场景中、但也可以是用于构建守护进程等场景中
注意区分include与import模块(虽然都是task关联使用,但是差距很大)
- import_tasks(Static):静态方法会在playbooks解析阶段将父task变量和子task变量全部读取并加载,这时候如果父与子task都定义了相同变量,子task变量为最终值,再继续执行父task时,会影响变量相关判断条件
- include_tasks(Dynamic):动态方法则是在执行play之前才会加载自己变量,即一个父与子task执行时都是只使用自己的变量,不会互相进行干扰
官方roles网站及使用工具
- Ansible Galaxy(https://galaxy.ansible.com)是一个官网提供的免费共享和下载 Ansible 角色的网站,可以帮助我们更好的定义和学习roles
ansible-galaxy命令:默认与https://galaxy.ansible.com网站API通信,可以查找、下载各种社区开发的 Ansible 角色
目录结构
#ansible安装后默认创建目录
/usr/share/ansible/roles #主要用于存放一些系统角色
/etc/ansible/roles #默认角色路径
#可以自定义roles文件,但是要在配置文件中指定文件路径
vim ansible.cfg
[defaults] #此模块内添加参数
roles_path=~/myroles #添加路径目录参数
#自定义目录myroles,创建apache项目
[ans@node1 myroles]$ ansible-galaxy init apache
- Role apache was created successfully
#初始化项目的目录层级
[ans@node1 myroles]$ tree -C apache/
apache/ <---具体的角色项目名称,比如nginx、tomcat、php(自由设置)
├── defaults <--用于为当前角色设定默认变量,此目录应当包含一个main.yml文件
│ └── main.yml <--main.yml,类似代码中的主函数,进行统一管理
├── files <--用来存放由copy模块或script模块等模块调用的文件
├── handlers <--用于定义此角色中触发条件时执行的动作,此目录应当包含一个main.yml文件
│ └── main.yml
├── meta <--用于定义此角色的特殊设定及其依赖关系,此目录应当包含一个main.yml文件
│ └── main.yml
├── README.md <--说明文件
├── tasks <--用于定义当前角色的任务列表,此目录应当包含一个main.yml文件
│ └── main.yml
├── templates <--用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件
├── tests <--用于存放测试role本身功能的playbook和主机定义文件,在开发测试阶段比较常用,此目录应当包含一个main.yml文件和自身资源设定invetory
│ ├── inventory
│ └── test.yml
└── vars <--用于定义此角色用到的变量,此目录应当包含一个main.yml文件
└── main.yml
#官网给出的项目文件层级样例
site.yml #应该是同一目录层级的3个剧本
webservers.yml
fooservers.yml
roles/ #roels目录,可以看出与剧本是同一层级
common/ #common项目
files/ #项目中的指定文件目录
templates/
tasks/
handlers/
vars/
defaults/
meta/
webservers/ #webservers项目,common项目都在roles目录中,同一目录层级
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
roles实践
将之前写好的一个简单剧本、相关模板与变量,进行拆分迁移写入roles中
源剧本
####################### 剧本 #######################
[ans@node1 ansible]$ vim playbook.yml
- hosts: app
vars:
web_package: httpd
web_service: httpd
tasks:
- name: install apache
yum:
name: "{{ web_package }}"
state: installed
- name: start apache
service:
name: "{{ web_service }}"
state: started
- name: create index.html
copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
- name: config apache
template:
src: files/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify: restart apache
handlers:
- name: restart apache
service:
name: "{{ web_service }}"
state: restarted
tags: web
- hosts: all
tasks:
- name: only node1 install haproxy
block:
- name: install haproxy
yum:
name: haproxy
state: installed
- name: start haproxy
service:
name: haproxy
state: started
- name: config haproxy
template:
src: files/haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: reload haproxy
when: ansible_hostname == 'node1'
handlers:
- name: reload haproxy
service:
name: haproxy
state: reloaded
tags: haproxy
####################### 模板 #######################
[ans@node1 ansible]$ cat files/httpd.conf.j2
…… #httpd配置文件,省略部分未修改内容
Listen {{ http_host }}:{{ http_port }}
……
[ans@node1 ansible]$ vim files/haproxy.cfg.j2
…… #配置文件,省略部分未修改内容
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
{% for host in groups['app']%}
server {{hostvars[host]['ansible_facts']['hostname']}} {{hostvars[host]['ansible_facts']['eth0']['ipv4']['address']}}:80 check
{% endfor %}
拆分迁移
先制作apache项目的roles
- 迁移tasks
#仅为了测试,httpd所以进行了些无谓的拆分
#目录结构
[ans@node1 tasks]$ tree
.
├── index.yml
├── install.yml
├── main.yml
└── start.yml
#main.yml
[ans@node1 tasks]$ cat main.yml
---
- include: install.yml
- include: start.yml
- include: index.yml
#安装task
[ans@node1 tasks]$ cat install.yml
- name: install apache
yum:
name: "{{ web_package }}"
state: installed
#启动task
[ans@node1 tasks]$ cat start.yml
- name: start apache
service:
name: "{{ web_service }}"
state: started
#配置task
[ans@node1 tasks]$ cat index.yml
- name: create index.html
copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
- name: config apache
template:
src: httpd.conf.j2 #注意此次调用模板,直接写文件名即可,应为已设定指定同项目下的templates目录
dest: /etc/httpd/conf/httpd.conf
notify: restart apache
- 设置变量,模板,触发器
#变量
[ans@node1 apache]$ cat vars/main.yml
---
# vars file for apache
web_package: httpd
web_service: httpd
#触发器
[ans@node1 apache]$ cat handlers/main.yml
---
# handlers file for apache
- name: restart apache
service:
name: "{{ web_service }}"
state: restarted
#模板直接拷贝进入templates文件中
[ans@node1 apache]$ ls templates/
httpd.conf.j2
- 设置启动roles的剧本,进行测试
注意启动剧本,应在建立在ploybook的层级中
[ans@node1 ansible]$ ls
ansible.cfg files inventory myroles playbook.yml roles_start.yml test.file vars
#我的启动脚本与管理的myroles文件夹在同一目录中
[ans@node1 ansible]$ cat roles_apache_start.yml
---
- hosts: app
roles:
- role: apache
[ans@node1 ansible]$ ansible-playbook roles_apache_start.yml
PLAY [app] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [node3]
ok: [node2]
TASK [apache : install apache] *****************************************************************************************************
changed: [node2]
changed: [node3]
TASK [apache : start apache] *******************************************************************************************************
changed: [node2]
changed: [node3]
TASK [apache : create index.html] **************************************************************************************************
ok: [node3]
ok: [node2]
TASK [apache : config apache] ******************************************************************************************************
changed: [node3]
changed: [node2]
RUNNING HANDLER [apache : restart apache] ******************************************************************************************
changed: [node3]
changed: [node2]
PLAY RECAP *************************************************************************************************************************
node2 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#测试正常
制作haproxy的roles
- 迁移tasks
#这次就不细拆分了,全部写在main中
[ans@node1 ansible]$ cat myroles/haproxy/tasks/main.yml
---
# tasks file for myroles/haproxy
- name: install haproxy
yum:
name: haproxy
state: installed
- name: start haproxy
service:
name: haproxy
state: started
- name: config haproxy
template:
src: files/haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: reload haproxy
#在task中就不需要原有的when条件判断了,将判断写在启动文件中
- 设置变量,模板,触发器
#没有独立变量
#拷贝模板进入templates中
[ans@node1 ansible]$ ls myroles/haproxy/templates/
haproxy.cfg.j2
#设置触发器
[ans@node1 ansible]$ cat myroles/haproxy/handlers/main.yml
---
# handlers file for myroles/haproxy
- name: reload haproxy
service:
name: haproxy
state: reloaded
- 设置启动roles的剧本,进行测试
[ans@node1 ansible]$ cat roles_haproxy_start.yml
---
- hosts: all ##所有主机节点
roles:
- role: apache
when: ansible_hostname in groups['app'] ##apache这个角色面向的是app组的成员
- role: haproxy
when: ansible_hostname == 'node1' ##haproxy面向的是节点node1
[ans@node1 ansible]$ ansible-playbook roles_start.yml
PLAY [all] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [node2]
ok: [node3]
ok: [node1]
TASK [apache : install apache] *****************************************************************************************************
skipping: [node1]
ok: [node2]
ok: [node3]
TASK [apache : start apache] *******************************************************************************************************
skipping: [node1]
ok: [node3]
ok: [node2]
TASK [apache : create index.html] **************************************************************************************************
skipping: [node1]
ok: [node3]
ok: [node2]
TASK [apache : config apache] ******************************************************************************************************
skipping: [node1]
ok: [node2]
ok: [node3]
TASK [haproxy : install haproxy] ***************************************************************************************************
skipping: [node2]
skipping: [node3]
changed: [node1]
TASK [haproxy : start haproxy] *****************************************************************************************************
skipping: [node2]
skipping: [node3]
changed: [node1]
TASK [haproxy : config haproxy] ****************************************************************************************************
skipping: [node2]
skipping: [node3]
changed: [node1]
RUNNING HANDLER [haproxy : reload haproxy] *****************************************************************************************
changed: [node1]
PLAY RECAP *************************************************************************************************************************
node1 : ok=5 changed=4 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
node2 : ok=5 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
node3 : ok=5 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
#执行正常
[ans@node1 ansible]$ curl node1
node2
[ans@node1 ansible]$ curl node1
node3
#可以调度轮询

Ansible Roles是自1.2版本引入的新特性,用于层次化组织playbook,便于管理和构建服务。本文介绍了Roles的概念,目录结构,以及如何将剧本拆分为roles,包括apache项目和haproxy的roles实践,强调了include与import_tasks的区别,并提到了Ansible Galaxy作为获取和分享角色的平台。
4580

被折叠的 条评论
为什么被折叠?



