目录
3、如果想触发 notify和handlers 这个角色,可以修改配置文件
[root@k8s-master-1 ansible]# tree
├── playbook.yaml <==执行剧本
├── roles <==角色必须与执行剧本在同一级目录中
│ ├── mysql <==项目名称
│ │ ├── default
│ │ │ └── main.yaml
│ │ ├── files
│ │ ├── handlers
│ │ │ └── main.yaml
│ │ ├── meta
│ │ │ └── main.yaml
│ │ ├── tasks
│ │ │ └── main.yaml
│ │ ├── templates
│ │ └── vars
│ └── nginx <==另一个项目
roles:<--所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在/etc/ansible/roles
project:<---具体的角色项目名称。比如 nginx、tomcat、mysql
default: <--角色使用到的变量在此目录中的main.yml文件中,defaults/main.yml文件中的变量都用于设置默认值,以便在没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
main.yaml
files:<--角色可能会用到的一些其他文件可以放置在此目录中。或者 用来存放由copy模块或script模块调用的文件。
handlers:<--此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
main.yaml
meta:<--如果想要赋予这个角色一些元数据,则可以将元数据写到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定。
main.yaml
tasks: <--此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
main.yaml
templates:<--用来存放jinjia2模板,如果没有指定目录,template模块会自动在此目录中寻找jinjia2模板文件。
vars:<--此目录应当包含一个main.yml文件,用于定义此角色用到的变量。看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
示例:
1、先创建roles_test 项目目录结构,并创建下面的子目录,最基本的子目录需要有tasks目录。
[root@k8s-master-1 ansible]# cd roles/
[root@k8s-master-1 roles]# mkdir roles_test
[root@k8s-master-1 roles]# cd roles_test/
[root@k8s-master-1 roles_test]# mkdir tasks
[root@k8s-master-1 roles_test]# cd tasks/
[root@k8s-master-1 tasks]# pwd
/etc/ansible/roles/roles_test/tasks
2、然后在tasks中编写相关的任务,在tasks中必须有一个 main.yaml 文件。可以把编写的任务直接写到 main.yaml 文件中,也可以写到其他文件中,然后在main.yaml中通过 include 的方式引用这些文件。在 tasks 中 不需要写 play 部分,只写tasks部分就行。
[root@k8s-master-1 tasks]# vim main.yaml
- name: test roles
debug:
msg: "this is test roles"
------或者----
[root@k8s-master-1 tasks]# vim test.yaml
- name: test roles
debug:
msg: "this is test roles"
[root@k8s-master-1 tasks]# vim main.yaml
- include: test.yaml
3、写好之后 编写playbook调用roles,playbook剧本必须要与roles角色在同一目录
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
remote_user: root
roles:
- role: roles_test
4、测试
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
ok: [192.168.134.138] => {
"msg": "this is test roles"
}
在playbook调用roles时,如何找到roles所在的目录呢?有以下几种方式:
? ? ? ? 1、playbook文件会在同级目录中寻找与调用的角色同名的roles,例如在上例中,roletest.yaml这个playbook文件调用了roles_test这个角色,会自动在同级目录中寻找roles_test这个目录,并执行其中的tasks。
[root@k8s-master-1 roles]# ll
总用量 2
drwxr-xr-x 3 root root 19 8月 9 09:25 roles_test
-rw-r--r-- 1 root root 68 8月 9 10:08 roletest.yaml
????????2、playbook文件也会寻找同级目录中的roles 目录,执行roles目录中同名的角色项目
[root@k8s-master-1 ansible]# tree
.
├── roles
│ └── roles_test
│ └── tasks
│ ├── main.yaml
│ └── test.yaml
├── roletest.yaml
????????3、也可以修改ansible配置文件中定义的roles的路径,多个路径之间使用冒号 :隔开
roles_path = /etc/ansible/roles:/data/ansible/roles:/opt
????????4、在playbook文件中,直接写roles的绝对路径也可以调用
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
remote_user: root
roles:
- role: /etc/ansible/roles/roles_test
? ? ? ? 修改roles文件,引入变量
1、[root@k8s-master-1 ansible]# vim roles/roles_test/tasks/test.yaml
- name: test roles
debug:
msg: "{{ var }}"
2、在调用这个角色时,则需要传入对应的变量,否则就会报错,调用上例角色的示例如下:
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
remote_user: root
roles:
- role: roles_test
vars:
- var: test vars
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
ok: [192.168.134.138] => {
"msg": "test vars"
}
-----或者---- 变量定义在vars文件中
3、也可以为变量设置默认值,这样即使在调用角色时没有传入任何参数,也有默认的值可以使用,同时也不会在调用时因为没有传入对应变量而报错,需要在roles_test目录中创建一个defaults目录/vars 目录,并且创建defaults/main.yml文件/vars/main.yaml文件,文件内容如下:
[root@k8s-master-1 roles_test]# mkdir vars
[root@k8s-master-1 roles_test]# cd vars/
[root@k8s-master-1 vars]# vim main.yaml
var: test abc
4、然后在运行playbook,结果一样
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
ok: [192.168.134.138] => {
"msg": "test abc"
}
结论:变量的优先级
ansible-playbook > vars/main.yaml > 其他变量定义的方式
默认情况下,我们无法多次调用同一个角色,也就是说,如下playbook只会调用一测role角色:
[root@k8s-master-1 ansible]# cat roletest.yaml
---
- hosts: web
remote_user: root
roles:
- role: roles_test
- role: roles_test
执行上边的playbook,会发现roles_test 的debug 模块只输出了一次,如果想多次调用同一个角色,有两种方法:
1、设置角色的 allow_duplicates 属性,让其支持重复使用
[root@k8s-master-1 roles_test]# mkdir meta
[root@k8s-master-1 ansible]# cat roles/roles_test/meta/main.yaml
allow_duplicates: true
2、调用角色时,传入不同的参数
先把vars 文件中的main.yaml 定义的变量注释掉
然后在playbook中添加变量
roles:
- role: roles_test
vars:
var: 123
- role: roles_test
vars:
var: test vars
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
TASK [roles_test : test roles] *******************************************************************
ok: [192.168.134.138] => {
"msg": 123
}
TASK [roles_test : test roles] **********************************************************************
ok: [192.168.134.138] => {
"msg": "test vars"
}
前文中提到,roles中把所有的模板文件放置到templates 目录中,我么来测试下:
1、新增template 目录,建立模板文件
[root@k8s-master-1 roles_test]# mkdir templates
[root@k8s-master-1 templates]# vim temp.j2
something in template;
{{ template_var }}
2、tasks/main.yaml 如下:
- name: test roles
debug:
msg: "{{ var }}"
- name: copy template
template:
src: temp.j2
dest: /tmp/temp
3、变量文件如下:
var: test abc
template_var: tempvar
4、playbook文件如下:
---
- hosts: web
remote_user: root
roles:
- role: roles_test
[root@k8s-master-1 ansible]# ansible-playbook roletest.yaml
TASK [roles_test : test roles] **************************************************************************
ok: [192.168.134.138] => {
"msg": "test abc"
}
TASK [roles_test : copy template] ***********************************************************************
changed: [192.168.134.138]
如果想要在角色中使用一些handlers 以便进行触发,则可以直接将对应的handlers 任务写到 handlers/main.yaml文件中
1、创建handlers 目录
[root@k8s-master-1 roles_test]# mkdir handlers
[root@k8s-master-1 handlers]# vim main.yaml
- name: test_handlers
debug:
msg: "this is a test handler"
2、编辑tasks任务
[root@k8s-master-1 tasks]# vim main.yaml
- name: test roles
debug:
msg: "{{ var }}"
changed_when: true
notify: test_handlers
3、把之前测试template 的变量注释掉
4、运行playbook文件
[root@k8s-master-1 ansible]# ansible-playbook -C roletest.yaml
TASK [roles_test : test roles] *******************************************************************************
changed: [192.168.134.138] => {
"msg": "test abc"
}
RUNNING HANDLER [roles_test : test_handlers] ********************************************************************************
ok: [192.168.134.138] => {
"msg": "this is a test handler"
}
????????roles 允许在使用时自动引入其他roles,role 依赖关系存储在meta/main.yaml文件中
示例:
安装WordPress 项目时:
1、需要先确保 nginx 与 php-fpm的role 都能正常运行;
2、然后在WordPress的role中定义,依赖关系;
3、依赖的role 有nginx 以及 php-fpm;
4、 在WordPress的role中新街meta 目录,编写main.yaml文件
[root@k8s-master-1 meta]# vim main.yaml
dependencies:
- { role: nginx }
- { role: php-fpm }
5、在WordPress的playbook中就不需要在安装 nginx 和php-fpm了,只写一个 WordPress就可以了,安装WordPress之前会自动先部署 nginx和php-fpm
[root@k8s-master-1 ansible]# vim roletest.yaml
---
- hosts: web
remote_user: root
roles:
- role: WordPress
????????roles 中的各项目之间的文件是可以跨项目相互调用的。跨项目调用时,需要指明要调用的role的名称。
示例:
要同时部署nginx 和apache 两个项目,这俩项目使用了相同的index.hetm主页文件,这个主页文件已经在nginx项目中定义过了,若此时需要在Apache项目中引用,使用如下方式
[root@localhost /data/roles]$vim apache/tasks/html.yml <==页面配置
- name: Copy Index File
copy:
src:roles/nginx/files/index.html #跨项目调用路径要写roles的名称
dest: /var/www/nginx/html/
1、创建项目目录,httpd
[root@k8s-master-1 roles]# mkdir httpd
2、创建roles相关目录
[root@k8s-master-1 httpd]# mkdir tasks files vars
[root@k8s-master-1 httpd]# cd tasks/
3、创建用户组
[root@k8s-master-1 tasks]# vim group.yaml
- name: create group
group:
name: apache
state: present
system: yes
gid: 80
4、创建用户
[root@k8s-master-1 tasks]# vim user.yaml
- name: create user
user:
name: apache
group: apache
state: present
uid: 80
system: yes
shell: /sbin/nologin
home: /usr/share/httpd
5、安装httpd包
[root@k8s-master-1 tasks]# vim install.yaml
- name: yum httpd
yum:
name: httpd
state: installed
6、在files目录下,创建配置文件 httpd.conf文件。将httpd.conf配置文件的端口修改为9527:
[root@k8s-master-1 files]# vim httpd.conf
Listen 9527
7、创建一个网页文件,用于验证当前信息
[root@k8s-master-1 files]# vim index.html
<h1> welcome to beijing! </h1>
8、将创建的配置文件复制到被管理端主机上
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
copy:
src: httpd.conf
dest: /etc/httpd/conf
backup: yes
9、将创建的index.html数据复制到/var/www/html目录下,相当于是给页面准备一个文件:
[root@k8s-master-1 tasks]# vim data.yaml
- name: copy data file
copy:
src: index.html
dest: /var/www/html/
10、创建服务文件
[root@k8s-master-1 tasks]# vim service.yaml
- name: started service
service:
name: httpd
state: started
enabled: yes
11、将任务按顺序编排到main.yaml 文件中
[root@k8s-master-1 tasks]# vim main.yaml
- include: group.yaml
- include: user.yaml
- include: install.yaml
- include: copy.yaml
- include: service.yaml
- include: data.yaml
12、编写playbook,用来调用httpd整个目录下的内容。注意:需要与roles 是同级目录
[root@k8s-master-1 ansible]# vim httpd_roles.yaml
---
- hosts: web
remote_user: root
roles:
- role: httpd
13、当前项目目录结构
[root@k8s-master-1 ansible]# tree roles/httpd/
roles/httpd/
├── files
│ ├── httpd.conf // 配置文件
│ └── index.html // html 文件
├── tasks
│ ├── copy.yaml
│ ├── data.yaml
│ ├── group.yaml
│ ├── install.yaml
│ ├── main.yaml
│ ├── service.yaml
│ └── user.yaml
└── vars
14、执行playbook
[root@k8s-master-1 ansible]# ansible-playbook -C httpd_roles.yaml
PLAY [web] ****************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.134.138]
TASK [httpd : create group] ***********************************************************
changed: [192.168.134.138]
TASK [httpd : create user] **************************************************************
changed: [192.168.134.138]
TASK [yum httpd] *****************************************************************
changed: [192.168.134.138]
TASK [httpd : copy file] *******************************************************************
changed: [192.168.134.138]
TASK [httpd : started service] ****************************************************************
changed: [192.168.134.138]
TASK [httpd : copy data file] ********************************************************************
changed: [192.168.134.138]
PLAY RECAP *********************************************************************************
192.168.134.138 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@k8s-master-1 ansible]#
ok 没有问题
1、将之前httpd的子目录都复制一份到nginx目录下
[root@k8s-master-1 roles]# cp -r httpd ./nginx
2、修改main.yaml 文件
[root@k8s-master-1 tasks]# vim main.yaml
- include: install.yaml
- include: copy.yaml
- include: service.yaml
- include: data.yaml
3、删除不需要的文件
[root@k8s-master-1 tasks]# rm -rf group.yaml user.yaml
4、将安装的文件和启动的文件 name修改成nginx
5、修改copy.yaml文件改成使用template 模板的方式修改
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
6、在本地下载一个nginx ,并将配置文件拷贝到 templates目录下
[root@k8s-master-1 nginx]# mkdir tamplates
[root@k8s-master-1 nginx]# yum -y install nginx
[root@k8s-master-1 templates]# cp /etc/nginx/nginx.conf ./nginx.conf.j2
7、修改nginx.conf.j2配置文件的CPU内核
user nginx;
worker_processes {{ ansible_processor_count*3 }};
8、跨角色调用httpd服务的文件内容
[root@k8s-master-1 tasks]# vim data.yaml
- name: copy data file
copy:
src: roles/httpd/files/index.html
dest: /usr/share/nginx/html/
9、编写playbook文件
[root@k8s-master-1 ansible]# vim nginx_roles.yaml
---
- hosts: web
remote_user: root
roles:
- role: nginx
10、执行playbook
[root@k8s-master-1 ansible]# ansible-playbook nginx_roles.yaml
PLAY [web] ***********************************************
TASK [Gathering Facts] ***********************************
ok: [192.168.134.138]
TASK [nginx : yum nginx] *********************************
changed: [192.168.134.138]
TASK [nginx : copy file] ********************************
changed: [192.168.134.138]
TASK [nginx : started service] *************************
changed: [192.168.134.138]
TASK [nginx : copy data file] **************************
changed: [192.168.134.138]
PLAY RECAP *********************************************
192.168.134.138 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
11、查看进程
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ps -ef |grep nginx'
192.168.134.138 | CHANGED | rc=0 >>
root 13623 1 0 14:41 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 13624 13623 0 14:41 ? 00:00:00 nginx: worker process
nginx 13625 13623 0 14:41 ? 00:00:00 nginx: worker process
nginx 13626 13623 0 14:41 ? 00:00:00 nginx: worker process
12、查看端口
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ss -nlt'
13、浏览器访问
http://192.168.134.138:80
1、修改copy任务的配置文件,添加notify,如果文件有更改就触发
[root@k8s-master-1 tasks]# vim copy.yaml
- name: copy file
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart_nginx
2、创建handlers文件,并添加main.yaml文件
[root@k8s-master-1 nginx]# mkdir handlers
[root@k8s-master-1 nginx]# vim main.yaml
- name: restart_nginx
service:
name: nginx
state: restarted
3、为了验证效果 我们把配置文件端口改成8080,并且将nginx配置文件的名称,以变量的方式传递
[root@k8s-master-1 templates]# vim nginx.conf.j2
user {{ username }};
server {
listen 8080;
listen [::]:8080;
4、创建变量目录和main.yaml文件
[root@k8s-master-1 vars]# vim main.yaml
username: daemon
4、执行playbook,并查看端口 已改为8080,查看用户一改为 daemon
[root@k8s-master-1 ansible]# ansible-playbook nginx_roles.yaml
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ss -lnt'
[root@k8s-master-1 ansible]# ansible web -m shell -a 'ps -aux |grep nginx'
1、修改playbook文件
[root@k8s-master-1 ansible]# vim nginx_roles.yaml
---
- hosts: web
remote_user: root
roles:
- {role: nginx,tags: ["nginx","test1"]}
- {role: mysql,tags: db}
2、[root@k8s-master-1 ansible]# ansible-playbook -t nginx nginx_roles.yaml
3、最后 卸载nginx
[root@k8s-master-1 ansible]# ansible web -m yum -a 'name=nginx state=absent'
1、编写任务(tasks)时候,里面不需要写需要执行的主机,单纯的写某个任务是干什么的即可,装软件就写装软件的,启动就写启动的,单独做某一件事即可,最后通过main.yaml将这些单独的任务按照执行顺序 include 进来即可。这样方便维护,且一目了然。
2、定义变量时,直接按照 K: V 的格式在vars/main.yaml文件写即可,然后tasks或者template直接调用就行,会自动去var/main.yaml文件里找。
3、定义handlers时,直接在handlers/main.yaml文件中写需要做的事情即可,多的话可以写在该文件里,也可向像tasks那样写多个文件,然后include 引入。在task调用notify时,两者名字必须一致
4、模板文件放在templates目录下,tasks调用直接写文件名就行,会自动去template 目录下找。注意:如果一个角色调用另一个角色的任务的时候,那么tasks中有些模板或者文件,就得些绝对路径了。