第三十八天:Ansible playbook--Role角色

角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即
可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进
程等场景中
运维复杂的场景:建议使用 roles,代码复用度高
roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下示例
roles/
 mysql/
 nginx/
 tomcat/
 redis/
默认roles存放路径
/root/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles
官方文档:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

 一、Ansible Roles目录编排

roles目录结构如下所示

 

每个角色,以特定的层级目录结构进行组织
roles目录结构:
playbook1.yml
playbook2.yml
roles/
 project1/
   tasks/
   files/
   vars/       
   templates/
   handlers/
   default/    
   meta/       
 project2/
   tasks/
   files/
   vars/       
   templates/
   handlers/
   default/    
   meta/  
Roles各目录作用
roles/project/ :项目名称,有以下子目录
  files/ :存放由copy或script模块等调用的文件
  templates/:template模块查找所需要模板文件的目录 
  tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
  handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
  vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含,也可以通过项目目录中的group_vars/all定义变量,从而实现角色通用
代码和项目数据的分离
  meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
  default/:设定默认变量时使用此目录中的main.yyml文件,比vars的优先级低 
二、创建 role
步骤
1 创建role的目录结构.在以roles命名的目录下分别创建以各角色名称命名的目录,如mysql等,在每个角
色命名的目录中分别创建相关的目录和文件,比如tasks、files、handlers、templates和vars等目录;
用不到的目录可以创建为空目录,也可以不创建
2 编写和准备指定role的功能文件,包括: tasks,templates,vars等相关文件
3 编写playbook文件调用上面定义的role,应用到指定的主机
针对大型项目使用Roles进行编排
范例: 利用 ansible-galaxy 创建角色目录的结构 
#创建初始化目录结构
[root@ansible roles]#ansible-galaxy role init test_role
- Role test_role was created successfully
[root@ansible roles]#tree test_role/
test_role/
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
   └── main.yml
8 directories, 8 files

三、Playbook 调用角色

调用角色方法1: 
---
- hosts: websrvs
 remote_user: root
 roles:
 - mysql
 - memcached
 - nginx
调用角色方法2:
键role用于指定角色名称,后续的k/v用于传递变量给角色 
---
- hosts: all
 remote_user: root
 roles:
   - role: mysql
     username: mysql
   - { role: nginx, username: nginx }
调用角色方法3:
还可基于条件测试实现角色调用
---
- hosts: all
 remote_user: root
 roles:
   - { role: nginx, username: nginx, when: ansible_distribution_major_version 
== '7' }

四、Roles 中 Tags 使用

[root@ansible ~]#vi app-role.yml
---
#可以有多个play
- hosts: lbserver
 roles:
    - role: haproxy
    - role: keepalived
    
- hosts: appsrvs
 remote_user: root
 roles:
    - { role: nginx ,tags: [ 'nginx', 'web' ] ,when: 
ansible_distribution_major_version == "6" }
    - { role: httpd ,tags: [ 'httpd', 'web' ] }
    - { role: mysql ,tags: [ 'mysql', 'db' ] }
    - role: mariadb 
     tags: 
        - mariadb
        - db
 tags: app  #play的tag
[root@ansible ~]#ansible-playbook --tags="nginx,mysql" app-role.yml

五、实战案例

1、实现 Httpd 角色
#创建角色相关的目录
[root@ansible ~]#mkdir -pv /data/ansible/roles/httpd/{tasks,handlers,files}
  
#创建角色相关的文件
[root@ansible ~]#cd /data/ansible/roles/httpd/
#main.yml 是task的入口文件
[root@ansible ~]#vim tasks/main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
[root@ansible ~]#vim tasks/group.yml
- name: create apache group
 group: name=apache system=yes gid=80
  
[root@ansible ~]#vim tasks/user.yml
- name: create apache user
 user: name=apache system=yes shell=/sbin/nologin home=/var/www/ uid=80
group=apache
[root@ansible ~]#vim tasks/install.yml
- name: install httpd package
 yum: name=httpd
#注意: 文件是放在files目录下,但src的路径无需写files目录名
[root@ansible ~]#vim tasks/config.yml
- name: config file
 copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
 notify: restart
[root@ansible ~]# tasks/index.yml
- name: index.html
 copy: src=index.html dest=/var/www/html/
[root@ansible ~]#vim tasks/service.yml
- name: start service
  service: name=httpd state=started enabled=yes
[root@ansible ~]#vim handlers/main.yml
- name: restart
  service: name=httpd state=restarted
  
#在files目录下准备两个文件
[root@ansible ~]#ls files/
httpd.conf index.html

#在playbook中调用角色
[root@ansible ~]#vim /data/ansible/role_httpd.yml
---
# httpd role
- hosts: websrvs
 remote_user: root
 roles:
    - httpd
    
#运行playbook
[root@ansible ~]#ansible-playbook /data/ansible/role_httpd.yml

 

2、实现 Nginx 角色

[root@ansible ~]#mkdir -pv 
/data/ansible/roles/nginx/{tasks,handlers,templates,vars}
#创建task文件
[root@ansible ~]#cd /data/ansible/roles/nginx/
[root@ansible nginx]#vim tasks/main.yml 
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
[root@ansible nginx]#vim tasks/install.yml 
- name: install
 yum: name=nginx 
[root@ansible nginx]#vim tasks/config.yml 
- name: config file for centos7
 template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf
 when: ansible_distribution_major_version=="7"
 notify: restart
- name: config file for centos8
 template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf
 when: ansible_distribution_major_version=="8"
 notify: restart

#跨角色调用文件
[root@ansible nginx]#vim tasks/index.yml 
- name: index.html
 copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/
[root@ansible nginx]#vim tasks/service.yml 
- name: start service
  service: name=nginx state=started enabled=yes
#创建handler文件
[root@ansible nginx]#cat handlers/main.yml 
- name: restart
  service: name=nginx state=restarted
#创建两个template文件
[root@ansible nginx]#cat templates/nginx7.conf.j2
...省略...
user {{user}};
worker_processes {{ansible_processor_vcpus+3}};   #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
...省略...
[root@ansible nginx]#cat templates/nginx8.conf.j2
...省略...
user {{user}};
worker_processes {{ansible_processor_vcpus**3}};  #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
...省略...
#创建变量文件
[root@ansible nginx]#vim vars/main.yml 
user: daemon

#在playbook中调用角色
[root@ansible ~]#vim /data/ansible/role_nginx.yml
---
#nginx role 
- hosts: websrvs
  
 roles:
    - role: nginx
    
#运行playbook
[root@ansible ~]#ansible-playbook /data/ansible/role_nginx.yml

3、实现 Memcached 角色

[root@ansible ~]#mkdir -pv /data/ansible/roles/memcached/{tasks,templates}
[root@ansible ~]#cd /data/ansible/roles/memcached
[root@ansible memcached]#vim tasks/main.yml 
- include: install.yml
- include: config.yml
- include: service.yml
[root@ansible memcached]#vim tasks/install.yml 
- name: install
 yum: name=memcached
[root@ansible memcached]#vim tasks/config.yml 
- name: config file
 template: src=memcached.j2  dest=/etc/sysconfig/memcached
[root@ansible memcached]#vim tasks/service.yml 
- name: service
  service: name=memcached state=started enabled=yes
[root@ansible memcached]#vim templates/memcached.j2 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}"
OPTIONS=""

[root@ansible ~]#vim /data/ansible/role_memcached.yml 
---
- hosts: appsrvs
  
 roles:
    - role: memcached
[root@ansible ~]#ansible-play /data/ansible/role_memcached.yml

 4、调用变量

[root@ansible ~]#vim /data/ansible/roles/test_role/tasks/main.yml
- name: Include OS-specific variables
 include_vars: {{ ansible_os_family}}.yml
....
[root@ansible ~]#ls /data/ansible/roles/test_role/vars/
Archlinux.yml Debian.yml FreeBSD.yml OpenBSD.ymL RedHat.yml

5、实现多角色的选择

[root@ansible ~]#vim /data/ansible/role_httpd_nginx.yml 
---
- hosts: websrvs
  
 roles:
    - {role: httpd,tags: [httpd,web], when: 
ansible_distribution_major_version=="7" }
    - {role: nginx,tags: [nginx,web], when: 
ansible_distribution_major_version=="8" }
[root@ansible ~]#ansible-playbook -t nginx /data/ansible/role_httpd_nginx.yml

6、依赖其它角色

[root@ansible roles]#vim wordpress/meta/main.yml
dependencies:
  - role: nginx
  - role: php-fpm
  - role: mysql

7、实现 NFS 服务

[root@ansible ~]#cat /data/ansible/roles/nfs-server/tasks/main.yml
- name: Configre NFS Server
 template:
   src: exports.j2
   dest: /etc/exports
   owner: root
   group: root
   mode: '0644'
 notify: Restart NFS Server
- name: Create NFS dir
 file:
   path: "{{ item }}"
   state: directory
   owner: "{{ all_user }}"
   group: "{{ all_group }}"
   mode: '0755'
   recurse: yes
 loop:
    - "{{ nfs_share_blog }}"
    - "{{ nfs_share_zrlog }}"
- name: Start NFS Server
 systemd:
   name: nfs
   state: started
[root@ansible ~]#cat /data/ansible/roles/nfs-server/handlers/main.yml
- name: Restart NFS Server
 systemd:
   name: nfs
   state: restarted
[root@ansible ~]#cat /data/ansible/roles/nfs-server/templates/exports.j2
{{ nfs_share_blog }} {{ nfs_allow_ip }}(rw,all_squash,anonuid={{ all_uid 
}},anongid={{ all_gid }}) 
{{ nfs_share_zrlog }} {{ nfs_allow_ip }}(rw,all_squash,anonuid={{ all_uid 
}},anongid={{ all_gid }}) 
[root@ansible ~]#cat /data/ansible/roles/group_vars/all
nfs_share_blog: /data/blog
nfs_share_zrlog: /data/zrlog
nfs_allow_ip: 10.0.0.0/24

8、实现 Redis 服务

[root@ansible ~]#cat /data/ansible/roles/redis/tasks/main.yml
- name: Installed Redis Server
 yum:
   name: redis
   state: present
- name: Configure Redis Server
 template:
   src: redis.conf.j2
   dest: /etc/redis.conf
   owner: redis
   group: root
   mode: '0640'
 notify: Restart Redis Server
- name: Start Redis Server
 systemd:
name: redis
   state: started
   enabled: yes
[root@ansible ~]#cat /data/ansible/roles/redis/templates/redis.conf.j2
bind 127.0.0.1 {{ ansible_eth0.ipv4.address }}
[root@ansible ~]#cat /data/ansible/roles/redis/handlers/main.yml
- name: Restart Redis Server
 systemd:
   name: redis
   state: restarted

9、实现 Nginx 服务

[root@ansible ~]#cat /data/ansible/roles/nginx/tasks/main.yml
- name: Install Nginx Server
 yum:
   name: nginx
   enablerepo: nginx
   state: present
- name: Configure Nginx nginx.conf
 template:
   src: nginx.conf.j2
   dest: "{{ nginx_conf_path }}"
 notify: Restart Nginx Server
- name: Start Nginx Server
 systemd:
   name: nginx 
   state: started
   enabled: yes
[root@ansible ~]#cat /data/ansible/roles/nginx/handlers/main.yml
- name: Restart Nginx Server
 systemd:
   name: nginx
   state: restarted
[root@ansible ~]#cat /data/ansible/roles/nginx/templates/nginx.conf.j2
user {{ all_user }};
worker_processes {{ ansible_processor_vcpus }} ;
events {
 workder_connections {{ ansible_processor_vcpus *10240 }};
}
http  {
 include {{ nginx_include_path }};
}
[root@ansible ~]#cat /data/ansible/roles/group_vars/all
# nginx
nginx_conf_path: /etc/nginx/nginx.conf
nginx_include_dir: /etc/nginx/conf.d
nginx_include_path: /etc/nginx/conf.d/*.conf

六、Ansible Tower 介绍

 公司中实现运维自动化的架构中主要用到ansible,但是ansible脚本在部署服务器指令行中显得不太直观
Ansible Tower (最早以前叫’AWX’)是能够帮助IT团队更容易使用Ansible的解决方案。
Ansible Tower是一个图形化基于WEB的任务调度,复杂服务部署,IT自动化的一个管理平台,属于发布配置管理系统,支持Api及界面操作,基于Django编写
Tower允许对用户进行权限控制,即使某用户不能传送某SSH凭证,你也可以通过Tower来对该用户共享该凭证。我们可以通过图形化界面来管理 Inventory,也可以对各种各样的云资源做同步。Tower可以记录所有job的日志,也可以与LDAP集成,并且拥有强大的可浏览的REST API。Tower也提供了命令
行工具,可以与Jenkins轻松集成。Provisioning回调对自动伸缩拓扑图提供了强大的支持。
可以在 Ansible Tower 页面 <http://ansible.com/tower> _了解Tower更多的功能,并且了解如何下载使用。Tower的免费版本最多支持10个节点,并且Ansible公司会提供强大的支持。可以支持用Ansible playbook来安装Tower
 七、Ansible 推荐学习资料
http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
https://github.com/ansible/ansible-examples

 

posted @ 2024-05-05 21:39  djyhello  阅读(679)  评论(0编辑  收藏  举报