目录



  • 五、roles基本使用
  • 1、单个角色编排
  • 2、多个角色编排
  • 3、角色之间调用tasks
  • 4、根据tags标签选择性执行
  • 5、使用when来判断条件执行
  • 6、综合示例



五、roles基本使用

  • 了解roles
    ansible从1.2版本引入的新特性,用于层次型,结构化的组织playbook。roles能够根据层次型结构自动装在变量文件、tasks一级handles等,要使用roles只需要在playbook内增加include指令即可,简单的说,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的include他们的一种机制。角色一般用于基于主机构建服务的场景,但也可以是用于构建守护进程的场景中(类似于用nginx.conf内的include xxx.conf ,比较灵活应用,可以多个YML调用一个,思想就是模块化)。(include已经过时,现在使用 来替代)
  • 复杂场景:建议使用roles,代码复用率高
    变更制定主机或者主机组
    如命名不规范维护和传承成本大
    某些功能需多个playbook,通过includes即可实现
  • 语法
    roles:角色集合
    roles/ #文件夹,官方默认路径在 /etc/ansible/roles,习惯放在/root/roles
    mysql/
    httpd/
    nginx/
    redis/

1、单个角色编排

需求:部署nginx(默认yum安装会自带用户,此时为了演示roles功能,自己创建)

思路:1、用户 nginx 2、 组:nginx 用户加入组内,3、安装nginx包 4、配置文件模板 5、启动建议:roles文件夹和执行该roles的YML文件放在同级目录,roles内放tasks,files,templated,handlers等

#整个roles列表
[root@ansible ansible]# tree roles/
roles/
└── nginx
    ├── tasks
    │   ├── group.yml     #创建组任务
    │   ├── main.yml      #主程序,调用其余tasks
    │   ├── restart.yml   #重启任务
    │   ├── templ.yml     #复制模板任务
    │   ├── user.yml      #创建用户
    │   ├── start.yml  #开启服务
    │   └── yum.yml       #安装任务
    └── templates
        └── nginx.conf.j2
#group
[root@ansible tasks]# cat group.yml 
- name: create group
  group: name=nginx
  
#main
[root@ansible tasks]# cat main.yml 
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: start.yml

#restart
[root@ansible tasks]# cat restart.yml 
- name: restart service
  service: name=nginx state=restarted
  
#templ
[root@ansible tasks]# cat templ.yml 
- name: copy conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

#user
[root@ansible tasks]# cat user.yml 
- name: create user
  user: name=nginx group=nginx system=yes shell=/sbin/nologin

#yum
[root@ansible tasks]# cat yum.yml 
- name: install 
  yum: name=nginx 
#nginx.conf.j2
[root@ansible nginx]# vim templates/nginx.conf.j2 
worker_processes  {{ ansible_processor_vcpus+2 }};
#nginx_role.yml
[root@ansible ansible]# pwd
/root/ansible      #该YML在于roles同级目录下
[root@ansible ansible]# vim nginx_role.yml 

- hosts: web
  remote_user: root
  roles:
    - role: nginx       #制定role角色名,就是roles下的目录
#验证后执行
[root@ansible ansible]# ansible-playbook nginx_role.yml
[root@ansible ansible]# ansible web -m shell -a 'ps -ef|grep nginx'
172.16.111.8 | SUCCESS | rc=0 >>
root      43057      1  0 22:01 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     43058  43057  0 22:01 ?        00:00:00 nginx: worker process
nginx     43059  43057  0 22:01 ?        00:00:00 nginx: worker process
nginx     43060  43057  0 22:01 ?        00:00:00 nginx: worker process
nginx     43061  43057  0 22:01 ?        00:00:00 nginx: worker process
root      43113  43108  0 22:02 pts/0    00:00:00 /bin/sh -c ps -ef|grep nginx
root      43115  43113  0 22:02 pts/0    00:00:00 grep nginx

172.16.111.7 | SUCCESS | rc=0 >>
root      38645      1  0 22:01 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx     38646  38645  0 22:01 ?        00:00:00 nginx: worker process
nginx     38647  38645  0 22:01 ?        00:00:00 nginx: worker process
nginx     38648  38645  0 22:01 ?        00:00:00 nginx: worker process
nginx     38649  38645  0 22:01 ?        00:00:00 nginx: worker process
root      38700  38695  0 22:02 pts/0    00:00:00 /bin/sh -c ps -ef|grep nginx
root      38702  38700  0 22:02 pts/0    00:00:00 grep nginx
#虚拟机为双核,j2文件中变量是把CPU个数+2 所以nginx用户进程是4个

以上为roles基本使用,思想就是模块化,把多个任务拆分,然后统一调用,比较灵活,日后如果需要其他role ,只需要将需要的配置文件拷贝适当修改就可以直接使用。

对于编译安装的程序,一般是在控制端编译安装好后打包调用copy模块发送到被控端然后解压执行即可

2、多个角色编排

增加一个httpd的角色,

思路 创建apache用户 yum安装httpd服务 启动服务

过程和上面nginx基本一样

(需要删除之前创建的nginx和apache用户,卸载nginx和httpd)

[root@ansible httpd]# ansible all -m shell -a 'yum remove httpd -y'
[root@ansible httpd]# ansible all -m shell -a 'userdel apache -r'
[root@ansible httpd]# ansible all -m shell -a 'yum remove nginx -y'

[root@ansible httpd]# ansible all -m shell -a 'userdel nginx -r'
[root@ansible httpd]# tree
.
├── files
│   └── httpd.conf   #复制在文件放在tasks同级的files内,可以直接写文件名调用
└── tasks
    ├── copy.yml
    ├── main.yml
    └── user.yml
#copy
[root@ansible tasks]# vim copy.yml 

- name: copy files
  copy: src=httpd.conf dest=/data/ owner=apache

如果两个不同功能的角色(此处只是为演示举例说明)都需要被调用 ,只需要在yml文件内roles内增加即可 类似字典

[root@ansible ansible]# vim test_roles1.yml 

---
- hosts: web
  remote_user: root
  roles:
    - role: httpd
    - role: nginx
#测试执行验证 略

3、角色之间调用tasks

如果一个角色执行期间需要调用另外一个角色的任务

还是以上为基础,nginx的role需要调用httpd中的copy.yml任务

[root@ansible tasks]# pwd
/root/ansible/roles/nginx/tasks
[root@ansible tasks]# vim main.yml 

- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: start.yml
- include: roles/httpd/tasks/copy.yml
#跨角色之间调用任务,只需要在main.yml文件内增加 - include: 后面加上该任务的路径,从roles开始  
#执行后验证  注意执行的是nginx_role.yml 
[root@ansible ansible]# ansible-playbook nginx_role.yml
[root@ansible ansible]# ansible web -m shell -a 'ls -l /data/httpd.conf'
172.16.111.7 | SUCCESS | rc=0 >>
-rw-r--r--. 1 apache root 11755 Oct 28 23:00 /data/httpd.conf

172.16.111.8 | SUCCESS | rc=0 >>
-rw-r--r--. 1 apache root 11755 Oct 28 23:00 /data/httpd.conf

4、根据tags标签选择性执行

可以很对不同角色加不同标签tags,标签可以都个 tags: ['tag1','tag2']

[root@ansible ansible]# vim test_roles2.yml 

---
- hosts: web
  remote_user: root
  roles:
    - role: { httpd,tags: ['web','httpd'] }
    - role: { nginx,tags: ['web','nginx'] }
    - role: { php, tags: 'php' }  #需要提前创建,否则无法执行
[root@ansible ansible]# ansible-playbook -t web test_roles2.yml -C   #-t制定标签执行

此时执行剧本的时候就可以选择性的执行标签,此时只会执行带有web标签的role

5、使用when来判断条件执行

[root@ansible ansible]# vim test_roles3.yml 

---
- hosts: web
  remote_user: root
  roles:
    - { role: httpd, tags: ['web','httpd'] }
    - { role: nginx, tags: ['web','nginx'],when: nsible_hostname == "node3" }
    - { role: php, tags: "php" }
#加入when判断条件

6、综合示例

综合以上模块,实现以下功能

创建php角色
创建用户名php uid10010
创建组php gid 10010
安装服务(使用httpd代替效果明显) httpd
启动服务
拷贝配置文件 :模板和copy两种
拷贝文件后出发handlers重启服务

准备工作

[root@ansible ansible]# tree roles/php/
roles/php/
├── files
│   └── file.conf.j2
├── handlers
│   └── main.yml
├── tasks
│   ├── copyfile.yml
│   ├── group.yml
│   ├── main.yml
│   ├── start.yml
│   ├── templ.yml
│   ├── user.yml
│   └── yum.yml
├── templates
│   └── httpd.conf.j2
└── vars
    └── main.yml
# file.conf.j2为空文件,只为看效果
#注意handlers和vars下面的文件必须有一个main.yml文件 默认调用

#templates/httpd.conf.j2  修改模板文件
[root@ansible php]# vim templates/httpd.conf.j2 
Listen {{ ansible_processor_vcpus+990 }} #调用setup自带变量端口=CPU数+990
User {{ username}} #调用变量username,在vars/main.yml内定义
Group {{ groupname}} #调用变量groupname,在vars/main.yml内定义

#vars/main.yml  定义变量
[root@ansible php]# vim vars/main.yml 
username: php
groupname: php
#handlers/main.yml 触发器执行操作
[root@ansible php]# vim handlers/main.yml 
- name: restart service
  service: name=httpd state=restarted

#user.yml 创建用户
[root@ansible tasks]# vim user.yml 
- name: create user
  user: name=php group=php system=yes shell=/sbin/nologin uid=10010

#group.yml 创建组
[root@ansible tasks]# vim group.yml 
- name: create group
  group: name=php system=yes gid=10010

#yum.yml  安装软件
[root@ansible tasks]# vim yum.yml 
- name: install php
  yum: name=httpd

#start.yml 启动httpd并设置为开机自启动
[root@ansible tasks]# vim start.yml 
- name: start service
  service: name=httpd state=started enabled=true
  
#templ.yml  使用模板模块执行conf文件拷贝并使用notify触发器调用handlers
[root@ansible tasks]# vim templ.yml 
- name: copy conf
  template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  notify: restart service
  
#copyfile.yml  调用copy磨块实现文件拷贝,此处该文件file.conf没有实际用处,只为熟悉操作
[root@ansible tasks]# vim copyfile.yml 
- name: copy file
  copy: src=file.conf.j2 dest=/data/httpd1.conf onwer=php
  
#main.yml 主调用文件 调用其他模块  注意顺序
[root@ansible tasks]# vim main.yml 
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: copyfile.yml
- include: start.yml

#php_role.yml 调用角色
[root@ansible ansible]# vim php_role.yml
- hosts: web
  remote_user: root

  roles:
    - php
    
#-C 测试   执行   查看端口  查看  文件是否复制 等 
#根据进程查看
[root@ansible ansible]# ansible all -m shell -a 'ps -ef|grep httpd'
172.16.111.9 | SUCCESS | rc=0 >>
root      13556  13555  0 23:20 pts/0    00:00:00 /bin/sh -c ps -ef|grep httpd
root      13558  13556  0 23:20 pts/0    00:00:00 grep httpd

172.16.111.8 | SUCCESS | rc=0 >>
root      53970      1  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       53971  53970  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       53972  53970  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       53973  53970  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       53974  53970  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       53975  53970  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      54411  54406  0 00:35 pts/0    00:00:00 /bin/sh -c ps -ef|grep httpd
root      54413  54411  0 00:35 pts/0    00:00:00 grep httpd

172.16.111.7 | SUCCESS | rc=0 >>
root      50027      1  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       50028  50027  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       50029  50027  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       50030  50027  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       50031  50027  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
php       50032  50027  0 00:34 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      50465  50460  0 00:35 pts/0    00:00:00 /bin/sh -c ps -ef|grep httpd
root      50467  50465  0 00:35 pts/0    00:00:00 grep httpd


#根据服务查看端口
[root@ansible ansible]# ansible all -m shell -a 'netstat -lntup|grep httpd'
172.16.111.9 | FAILED | rc=1 >>
non-zero return code

172.16.111.8 | SUCCESS | rc=0 >>
tcp6       0      0 :::992                  :::*                    LISTEN      53970/httpd         

172.16.111.7 | SUCCESS | rc=0 >>
tcp6       0      0 :::992                  :::*                    LISTEN      50027/httpd 

#根据端口990+CPU个数查询
[root@ansible ansible]# ansible all -m shell -a 'lsof -i:992'
172.16.111.9 | FAILED | rc=1 >>
non-zero return code

172.16.111.7 | SUCCESS | rc=0 >>
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   50027 root    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)
httpd   50028  php    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)
httpd   50029  php    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)
httpd   50030  php    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)
httpd   50031  php    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)
httpd   50032  php    4u  IPv6 356735      0t0  TCP *:telnets (LISTEN)

172.16.111.8 | SUCCESS | rc=0 >>
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   53970 root    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)
httpd   53971  php    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)
httpd   53972  php    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)
httpd   53973  php    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)
httpd   53974  php    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)
httpd   53975  php    4u  IPv6 375561      0t0  TCP *:telnets (LISTEN)