一个数据中心有可能存在好多类型的服务器。比如WEB类型、DB类型、开发人员使用的开发类型、QA使用的测试类型等等。
实际生产中,基本每个类型的服务器的初始化行为都不一致。
那要在一个PlayBook中将这些动作完成,这个PlayBook将变得臃肿、庞大,且难以后续维护和更新。
如果能够针对每个类型的服务器单独编写PlayBook,最后通过某种方式整合这PlayBook,在管理方式上就又会变得简单。Ansible中提供了类似的概念,也就是Role。它允许管理员将他们复杂的PlayBook分解成一个个小的逻辑单元,以便于维护和管理。
ROLE 是什么呢
先看一个示例:
webservers/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
└── vars
└── main.yml
从表面上看,它就是一个目录。目录的名字也就是role的名字,示例中,role 的名字叫做 webservers
。
进到这个role名字的目录里,会发现好多子目录。
使用时,每个目录必须包含一个main.yml文件,这个文件应该包含如下目录名称对应的内容:
tasks
-包含角色要执行的任务的主要列表。handlers
-包含处理程序,此角色甚至该角色之外的任何地方都可以使用这些处理程序。defaults
-角色的默认变量。vars
-角色的其他变量。files
-包含可以通过此角色部署的文件。templates
-包含可以通过此角色部署的模板。meta
-为此角色定义一些元数据。角色必须至少包含这些目录之一,但是最好排除任何未使用的目录。
常用指令
// 在galaxy 上搜索共享的ROLE
[root@localhost ~]# ansible-galaxy search
// 安装 galaxy 上共享的 ROLE
[root@localhost ~]# ansible-galaxy install
// 列举已经通过 ansible-galaxy 工具安装的ROLE
[root@localhost ~]# ansible-galaxy list
// 创建一个ROLE 的空目录架构, 这样我们在开发一个ROLE的时候,就不需要手动创建目录了。
[root@localhost ~]# ansible-galaxy init --offline
// 创建了名字为testrole的空ROLE目录结构,默认在执行命令的目录生产。
[root@localhost ~]#ansible-galaxy init testrole
[root@localhost ~]#tree testrole/
testrole/
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── tests
│ ├── hosts
│ └── test.yml
└── vars
└── main.yml
// 创建一个ROLE 的空目录架构, 这样我们在开发一个ROLE的时候,就不需要手动创建目录了。
[root@localhost ~]# ansible-galaxy init nginx
// nginx结构树 yum tree
[root@localhost ~]# tree nginx
nginx
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
[root@localhost ~]# cat nginx/vars/main.yml
---
createuser:
- tomcat
- www
- mysql
[root@localhost ~]# cat nginx/tasks/main.yml
---
#tasks file for nginx
- name: create tomcat user
with_items: "{{ createuser }}"
user:
name: "{{ item }}"
state: present
- name: yum nginx webserver
yum: name=nginx state=present
- name: update nginx main config
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: updateconfig
notify: reload config file
- name: add virtualhost config
copy: src=www.qfedu.com.conf dest=/etc/nginx/conf.d/
tags: updateconfig
notify: reload config file
- name: 检查nginx 配置文件的语法
shell: /usr/sbin/nginx -t
register: nginxsyntax
tags: updateconfig
- name: test nginx is running
shell: "ps -ef|grep 'nginx: maste[r]'|awk '{print $2}'"
register: nginxrunning
tags: updateconfig
- name: start nginx server
when:
- nginxsyntax.rc == 0
- nginxrunning.stdout == ""
service: name=nginx state=started
tags: updateconfig
[root@localhost ~]# cat nginx/handlers/main.yml
---
- name: reload config file
when: nginxsyntax.rc == 0 and nginxrunning.stdout
service:
name: nginx
state: reloaded
[root@localhost ~]# cat nginx.conf
user nginx;
{# start process equal cpu cores #}
worker_processes {{ ansible_processor_vcpus }};
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
keepalive_timeout 0;
gzip on;
gzip_min_length 1k;
gzip_buffers 8 64k;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_types text/plain application/x-javascript text/css application/json application/xml application/x-shockwave-flash application/javascript image/svg+xml image/x-icon;
gzip_vary on;
{# add_header {{ ansible_hostname }}; #}
add_header x-hostname {{ ansible_hostname }};
include /etc/nginx/conf.d/*.conf;
}
[root@localhost ~]# cat hosts
[webservers]
192.168.116.145
Role 本身不能被直接执行,还是需要借助PlayBook进行间接的调用。
需要创建一个入口文件,来调用 role 中的各种资源
[root@localhost ~]# ansible-playbook -i hosts nginx.yml
ansible 批量自动推送公钥 https://blog.csdn.net/qq_22648091/article/details/108697801
ansible 高级知识
https://www.bilibili.com/video/BV1ui4y1b7DY/