学习

3. Ansible Role

2021-02-11  本文已影响0人  随便写写咯

4 Roles

角色可用于层次性, 结构化组织playbook. 角色能够根据层次型结构自动装载变量文件, tasks以及handlers等
要想使用角色, 只需要在playbook中使用include指令即可.
roles就是通过分别将变量, 文件, 任务, 模板及处理器放置于单独的目录中, 并可以便捷地include它们的一种机制
角色一般用于基于主机构建服务的场景, 也可以用于构建守护进程等场景
在复杂场景中, 可以使用roles来做编排, 代码复用性高

roles: 可以作为多个服务的集合, 把多个服务, 分别放置到roles目录下的独立子目录

roles/
  mysql/
  nginx/
  tomcat/
  redis/

4.1 Ansible Roles 目录编排

roles目录结构: 每个角色, 以特定得层级目录结构进行组织

roles structure

roles 目录架构

playbook1.yml  # 在playbook中去调用角色中的项目
playbook2.yml
roles/
  project1/
      tasks/
      files/
      vars/
      templates/
      handlers/
      default/
      meta/
  project2/
      tasks/
      files/
      vars/ 
      templates/
      handlers/

角色中每个目录的作用

roles/project: 项目名称, 有以下子目录

4.2 create role

创建role的步骤

1. 创建目录roles
2. 在roles目录中分别创建以各自角色名称命名的目录, 如webservers等
3. 在每个角色命令的目录中分别创建files, handlers, tasks, templates和vars等目录, 用不到的目录可以创建为空目录, 也可以不创建
4. 在playbook文件中, 调用各角色

针对大型目录使用Roles进行编排

eg: roles的目录结构

[02:29:51 root@ansible /data/files]#tree roles 
roles
└── nginx
    ├── files
    │   └── main.yml
    ├── tasks
    │   ├── groupadd.yml
    │   ├── install.yml
    │   ├── main.yml
    │   ├── restart.yml
    │   └── useradd.yml
    └── vars
        └── main.yml

4.3 playbook中调用角色

调用角色方法1:

---
- hosts: websrvs
  remote_user: root
  roles:
    - mysql
    - memcached
    - nginx   

调用角色方法2:

键role用于指定角色名称, 后续的k/v用于传递变量给角色
---
- hosts: websrvs
  remote_user: root
  roles:
    - mysql
    - { role: nginx, username: nginx} 

调用角色方法3:

还可基于条件测试实现角色调用
---
- hosts: websrvs
  remote_user: root
  roles:
    - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' } 

4.4 roles中使用tags

[02:32:26 root@ansible /data/files]#vim role.yml

---
- hosts: websrvs
  remote_user: root
  roles:
    - { role: nginx, tags: [ 'nginx', 'web' ], when: ansible_distribution_major_version == '6'}
    - { role: httpd, tags: [ 'httpd', 'web' ] }
    - { role: httpd, tags: [ 'mysql', 'web'] }
    - { role: mariadb, tags: [ 'mariadb', 'db'] }   
[02:40:16 root@ansible /data/files]#ansible-playbook   --tags="nginx,httpd,mysql" role.yml

4.5 实战案例: 实现httpd角色

  1. 创建角色相关目录
[15:48:11 root@Ansible ~]#mkdir -pv /data/ansible/roles/httpd/{tasks,files}
mkdir: created directory '/data/ansible/roles/httpd'
mkdir: created directory '/data/ansible/roles/httpd/tasks'
mkdir: created directory '/data/ansible/roles/httpd/files'
  1. 创建角色相关文件
[15:48:32 root@Ansible ~]#cd /data/ansible/roles/httpd

main.yml是tasks的入口文件, 定义了多个tasks的执行顺序. 把每个task的yml文件单独创建在tasks目录下, 用main.yml去调用并且按照顺序执行

[15:49:02 root@Ansible /data/ansible/roles/httpd]#vim tasks/main.yml

- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: mkdir.yml
- include: index.yml
- include: service.yml   

创建group.yml

[15:59:31 root@Ansible /data/ansible/roles/httpd]#vim tasks/group.yml
---
- name: "创建apache用户组"
  group: name=apache system=yes gid=80   

创建user.yml

[16:04:58 root@Ansible /data/ansible/roles/httpd]#vim tasks/user.yml
---
- name: "创建apache用户"
  user: name=apache system=yes shell=/sbin/nologin home=/var/www uid=80 group=apache 

创建install.yml

[16:09:15 root@Ansible /data/ansible/roles/httpd]#vim tasks/install.yml
---
- name: "安装httpd包"
  yum: name=httpd                                                                                                                                  

创建config.yml

准备一个apache配置文件模板放在httpd/files目录下

DocumentRoot "/data/html"

<Directory "/data/html"> 
[03:03:14 root@Ansible /data/ansible/roles/httpd/files]#ls
httpd.conf  index.html
[16:28:41 root@Ansible /data/ansible/roles/httpd]#vim tasks/config.yml 

---
- name: "拷贝配置文件"   # src不用写全路径, 直接写文件名即可, 可以自动找到
  copy: src=httpd.conf dest=/etc/httpd/conf backup=yes

创建mkdir.yml, 用来创建必要的目录

[16:20:32 root@Ansible /data/ansible/roles/httpd]#vim tasks/mkdir.yml

---
- name: "创建目录"
  file: path=/data/html state=directory  

创建index.yml

准备index.html文件, 放在httpd/files目录下

[16:13:54 root@Ansible ~]#echo "httpd website based on ansible" > /data/ansible/roles/httpd/files/index.html
[16:20:56 root@Ansible /data/ansible/roles/httpd]#vim tasks/index.yml

- name: index.html
  copy: src=index.html dest=/data/html 

创建service.yml

[16:21:59 root@Ansible /data/ansible/roles/httpd]#vim tasks/service.yml 
---
- name: httpd service
  service: name=httpd state=started enabled=yes 

创建调用roles的文件, 该文件和roles目录平级

[02:54:54 root@Ansible /data/ansible/]#vim role_httpd.yml

---
- hosts: 10.0.0.86
  gather_facts: no
  remote_user: root

  roles:
    - httpd 

执行剧本

ansible-playbook role_httpd.yml
PLAY RECAP ***************************************************************************************************************************************************************
10.0.0.86                  : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
  1. 下面通过handler和notify实现配置文件修改后能重启服务
[16:08:48 root@Ansible /data/ansible/roles/httpd]#mkdir handlers
[16:08:53 root@Ansible /data/ansible/roles/httpd]#ls
files  handlers  tasks
[16:48:13 root@Ansible /data/ansible/roles]#vim httpd/handlers/main.yml
- name: restart httpd
  service: name=httpd state=restarted  

修改config.yml

[16:57:16 root@Ansible /data/ansible/roles]#vim httpd/tasks/config.yml 

- name: config
  copy: src=/data/ansible/roles/httpd/files/httpd.conf dest=/etc/httpd/conf
  notify: restart httpd    

修改httpd/files目录下的配置文件,监听端口号

Listen 8080

重新执行role_httpd.yml

RUNNING HANDLER [restart httpd] ******************************************************************************************************************************************
changed: [10.0.0.86]

PLAY RECAP ***************************************************************************************************************************************************************
10.0.0.86                  : ok=8    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

验证端口号修改即可

[17:04:14 root@Ansible /data/ansible/roles]#curl 10.0.0.86:8080
httpd website based on ansible
  1. 下面实现配置文件模板
[17:05:46 root@Ansible /data/ansible/roles]#mkdir httpd/templates

把配置文件从files目录移动到templates里, 并添加.j2后缀. 利用j2模板生成配置文件,而不用统一的配置文件了

[17:05:50 root@Ansible /data/ansible/roles]#mv httpd/files/httpd.conf httpd/templates/httpd.conf.j2

修改j2模本文件的监听端口

Listen {{ listen_port }}

在主机清单中定义主机变量, 实现利用j2模板, 不同的服务器能监听不同的端口

[websrvs]
10.0.0.85 listen_port=9090  # 把10.0.0.85也加入到部署列表, 实现根据不同变量, 生成配置文件
10.0.0.86 listen_port=7070 

修改config.yml文件

- name: config
  template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf # 利用j2模本后, 这里要写全路径和文件名, 否则j2文件拷贝到被管理节点, 还是.j2结尾, 配置文件并不会被修改.                                                        
  notify: restart httpd

修改role_httpd.yml文件, 添加10.0.0.85

[16:25:31 root@Ansible /data/ansible/]#vim role_httpd.yml 

---
- hosts: websrvs                                                                                                                                                          
  gather_facts: no
  remote_user: root

  roles:
    - httpd

执行剧本, 验证

[17:15:34 root@Ansible ~]#curl 10.0.0.86:7070
httpd website based on ansible
[17:15:37 root@Ansible ~]#curl 10.0.0.85:9090
httpd website based on ansible

注意: 角色中利用vars目录定义的变量是比主机变量优先级高的, 如果定义了主机变量, 又定义了vars变量, 那么vars的会优先生效

命令行变量 > vars变量 > 主机变量

案例: 验证统一vars变量的优先级高于主机变量

1. 添加vars变量
[17:17:45 root@Ansible /data/ansible/roles/httpd]#ls
files  handlers  tasks  templates
[17:17:45 root@Ansible /data/ansible/roles/httpd]#mkdir vars
[17:17:47 root@Ansible /data/ansible/roles/httpd]#vim vars/main.yml

listen_port: 8888   
2. 执行剧本
[17:17:41 root@Ansible ~]#curl 10.0.0.85:8888
httpd website based on ansible
[17:20:47 root@Ansible ~]#curl 10.0.0.86:8888
httpd website based on ansible
3. 由此可以看到, 统一的vars变量优先级高于主机变量, 不过这样就无法实现根据不同的服务器生成不同的配置文件了

或者也可以在playbook中调用when条件判断, 实现不同主机监听不同端口号

  1. 在files目录下准备两个配置文件
[17:26:24 root@Ansible /data/ansible/roles/httpd/files]#ls
httpd_85.conf  httpd_86.conf  index.html
  1. 修改config.yml文件, 实现基于ip地址拷贝不同的配置文件
[17:46:57 root@Ansible /data/ansible/roles]#vim httpd/tasks/config.yml 

---
- name: "拷贝10.0.0.85配置文件"
  copy: src=httpd_85.conf dest=/etc/httpd/conf/httpd.conf backup=yes
  when: ansible_default_ipv4['address'] == "10.0.0.85"
  notify: restart httpd

- name: "拷贝10.0.0.86配置文件"
  copy: src=httpd_86.conf dest=/etc/httpd/conf/httpd.conf backup=yes
  when: ansible_default_ipv4['address'] == "10.0.0.86"                                                                                                                              
  notify: restart httpd
  1. 验证
[17:48:16 root@Ansible ~]#curl 10.0.0.85:85
httpd website based on ansible
[17:53:20 root@Ansible ~]#curl 10.0.0.86:86
httpd website based on ansible

补充: 如果希望复用文件, 比如在apache和nginx间复用默认页面, 只需要把文件拷到不同的roles文件夹里即可, 或者直接从roles目录开始找httpd的index.html文件, src=roles/httpd/files/index.html, 即可实现复用默认页面. 不过其他的配置文件还是要修改的

  1. 创建目录
[17:56:53 root@Ansible /data/ansible/roles]#mkdir -pv nginx/{tasks,files}
mkdir: created directory ‘nginx’
mkdir: created directory ‘nginx/tasks’
mkdir: created directory ‘nginx/files’
  1. 创建tasks/main.yml文件
[17:58:49 root@Ansible /data/ansible/roles]#vim nginx/tasks/main.yml

- include: install.yml
- include: config.yml
- include: index.yml                                                                                                                                                                
- include: service.yml
  1. 准备以上4个文件
[17:59:28 root@Ansible /data/ansible/roles]#cp httpd/tasks/install.yml nginx/tasks
[17:59:58 root@Ansible /data/ansible/roles]#cp httpd/tasks/config.yml nginx/tasks
[18:00:02 root@Ansible /data/ansible/roles]#cp httpd/files/index.yml nginx/files
[18:00:06 root@Ansible /data/ansible/roles]#cp httpd/tasks/service.yml nginx/tasks
  1. 编辑install文件
[18:01:01 root@Ansible /data/ansible/roles/nginx/tasks]#vim install.yml 

---
- name: "安装nginx包"
  yum: name=nginx  
  1. 编辑config文件
[18:26:25 root@Ansible /data/ansible/roles/nginx/tasks]#vim config.yml 
---
- name: "拷贝10.0.0.85配置文件"
  copy: src=nginx_885.conf dest=/etc/nginx/nginx.conf backup=yes
  when: ansible_default_ipv4['address'] == "10.0.0.85"


- name: "拷贝10.0.0.86配置文件"
  copy: src=nginx_886.conf dest=/etc/nginx/nginx.conf backup=yes
  when: ansible_default_ipv4['address'] == "10.0.0.86"                                                                                                                              


  1. 编辑service文件
[18:28:45 root@Ansible /data/ansible/roles/nginx/tasks]#vim service.yml 

---
- name: "start nginx"                                                                                                                                                               
  service: name=nginx state=started enabled=yes
  1. 准备两个nginx配置文件
[18:21:35 root@Ansible ~]#vim /data/ansible/roles/nginx/files/nginx_885.conf
    server {
        listen       885 default_server;
        listen       [::]:885 default_server; 
[18:22:27 root@Ansible ~]#vim /data/ansible/roles/nginx/files/nginx_886.conf
    server {
        listen       886 default_server;
        listen       [::]:886 default_server; 
  1. 编辑index.yml
[18:49:34 root@Ansible /data/ansible/roles/nginx/tasks]#vim index.yml 

---
- name: index.html
  copy: src=roles/httpd/files/index.html dest=/data/html 
# 由于需要复用httpd的页面, 因此, 需要指定src路径, 从roles开始既可以找到index.html, 因为, 执行playbook就是在roles同级目录执行的
  1. 准备nginx的role文件
[18:51:14 root@Ansible /data/ansible/roles]#cp role_httpd.yml role_nginx.yml
[18:51:25 root@Ansible /data/ansible/roles]#vim role_nginx.yml 

---
- hosts: websrvs
  remote_user: root
  
  roles:
    - nginx  
上一篇下一篇

猜你喜欢

热点阅读