Playbook简介
Playbooks与Ad-Hoc相比,是一种完全不同的运用Ansible的方式,而且是非常之强大的;也是系统ansible命令的集合,其利用yaml语法编写,运行过程,ansbile-playbook命令根据自上而下的顺序
依次执行任务。playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’为元素的列表,在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible模块的调用。当第一个任务依次在所有主机上执行完毕后,开始执行第二个任务。如果某个主机执行时发生错误,则所有操作将会回滚。
Playbook基础组件
hosts
:运行执行任务(task)的目标主机remote_user
:在远程主机上执行任务的用户tasks
:任务列表handlers
:任务,与tasks不同的是只有在接受到通知时才会被触发templates
:使用模板语言的文本文件,使用jinja2语法。variables
:变量,变量替换tag
:标签,为某tasks指定标签,运行该标签可以即运行特定的tasks,定义为always的tag总会执行when
: 条件判断,当条件成立则执行tasks,不成立不执行表达式 判断表达式如:not
or
and
!=
=
with_items
:循环迭代需要重复执行的任务列表,用{item}}
引用列表值
例如一个简单的playbook文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- hosts: test # 指定运行任务的主机组
remote_user: root # 指定远程执行任务的用户
vars: # 指定变量
- bsh: b.sh
- httprpm: httpd
task: # 任务的开始
- name: install httpd # 一个安装httpd的任务
yum: name={{ httprpm }} state=present # ansible的yum模块
tags: install_httpd # 为该任务打一个install_httpd的标签
- name: copy b.sh # 又一个复制b.sh脚本的任务
copy: src=/root/{{ bsh }} dest=/root/ owner=ala group=ala mode=0644
notify: # 如果copy的文件内容发生改变就会触发
- reload httpd # 指定通知的哪个handlers
when: ansible_distribution == "CentOS" # 通过变量判断系统为CentOS时才执行该copy任务
- name: copy b.sh
copy: src=/root/{{ bsh }} dest=/opt/ owner=ala group=ala mode=0644
notify:
- reload httpd
when: ansible_distribution == "Ubuntu" # 通过变量判断系统为Ubuntu时才执行该copy任务
- name: start httpd # 又一个启动httpd服务的任务
service: name=httpd state=started enabled=yes
handlers: # 满足触发条件则执行的任务
- name: reload httpd # 满足触发条件的任务名
service: name=httpd state=reloaded # 该任务为重新加载一下httpd服务
其中的
ansible_distribution
是ansible收集的facts变量。
playbook定义变量
ansible 常见定义变量有以下 6 种
- /etc/ansible/hosts文件主机中定义
- /etc/ansible/hosts/文件主机组中定义
- playbook的yaml文件中通过vars定义
- 获取系统变量,也称facts变量
- 分文件定义主机和主机组的变量
- playbook 的role中定义
1 | # /etc/ansible/hosts文件主机中定义 主机变量 |
playbook role目录结构
Roles简介
Ansible为了层次化、结构化地组织Playbook,使用了角色(roles)。Roles能够根据层次型结构自动装载变量文件、task及handlers等。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们,roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
创建Roles
创建roles时一般需要以下步骤:首先创建以roles命名的目录。然后在roles目标下分别创建以这个角色名称命令的目录,如websevers等,然后在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录。最后在Playbook文件中调用各角色进行使用。
roles内各目录含义解释
files
:用来存放由copy模块或script模块调用的文件。templates
:用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。tasks
:此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。handlers
:此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。vars
:此目录应当包含一个main.yml文件,用于定义此角色用到的变量。defaults
:此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。meta
:此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。
如下定义了一个nginx服务的playbook目录结构树。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[root@k8s-master1 roles]# tree /etc/ansible/roles/nginx
/etc/ansible/roles/nginx
├── defaults
│ └── main.yml
├── files
│ └── nginx.tar.gz
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── nginx.conf.j2
│ └── default.conf.j2
└── vars
└── main.yml
使用roles安装nginx案例
实例环境
主机名 | IP | 系统 | 角色 |
---|---|---|---|
ansible | 192.168.20.210 | centos7.5 | ansible控制器 |
web-nginx | 192.168.20.213 | centos7.5 | web服务器 |
hosts主机组清单
1 | $ cat /etc/ansilbe/hosts # ansible hosts主机组配置 |
生成ssh密钥
1 | # 在ansible控制机上生成ssh密钥对 |
创建nginx的roles结构目录
1 | $ mkdir -pv /etc/ansible/roles/nginx/{defaults,files,handlers,meta,tasks,templates,vars} |
准备安装包和依赖包
1 | cd /etc/ansible/roles/nginx/files |
准备安装脚本
该脚本已在手动安装测试过,建议各位在通过ansible playbook安装服务器前,先手动安装一遍确保无误。
1 | $ cat /etc/ansible/roles/nginx/files/install_nginx.sh |
配置变量
在安装nginx的时候或者其他服务的时候常常用到变量,下面配置变量是通过roles方式配置。
1
2
3
4
5$ cat /etc/ansible/roles/nginx/vas/main.yml
cat nginx/vars/main.yml
nginx_user: nginx
nginx_port: 80
nginx_dir: /usr/local/nginx
准备nginx.conf模版
1 | $ cat /etc/ansible/roles/nginx/templates/nginx.conf.j2 |
nginx.conf.j2文件中
nginx_user
和ansible_processor_vcpus
分别为用户自定义变量和-m setup
获取的facts。
定义默认server模版
1 | ```bash |
default.conf.j2文件中
nginx_port
和ansible_all_ipv4_addresses
分别为用户自定义变量和-m setup
获取的facts。
定义一个测试index.html文件
1 | $ cat /etc/ansible/roles/nginx/templates/index.html |
定义nginx启动脚本
1 | $ cat /etc/ansible/roles/nginx/files/nginx.service |
定义tasks任务
1 | # 在tasks目录中定义了一个copy.yaml文件用户复制files目录下的文件到nginx服务器 |
1 | # 定义main.yaml文件 |
定义触发通知handlers
1 | $ cat /etc/ansible/roles/nginx/handlers/main.yml |
定义role入口文件
1 | $ cat /etc/ansible/roles/nginx.yml |
查看当前nginx roles目录树结构
1 | $ tree /etc/ansible/roles/ |
playbook语法检测
通过上面的配置,我们已经完成了使用playbook方式安装nginx所需要的步骤,现在我们应该在执行该playbook前检查一下上述语法有没有错误。1
2
3$ ansible-playbook --syntax-check /etc/ansible/roles/nginx.yml
playbook: /etc/ansible/roles/nginx.yml # 如果语法没问题,将直接显示文件名称,如果有错误将告知你那里错了
测试安装
ansible-playbook -C
命令可以测试运行playbook剧本,而非真正在远端服务器上执行,这样可以方便查看playbook在执行过程中将会做哪些事情。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44$ ansible-playbook -C nginx.yml
PLAY [web-node] ************************************************************************************************************************************************
TASK [nginx : copy nginx-1.16.0.tar.gz to client] **************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : copy install_nginx.sh to client] *****************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : mkdir nginx data directory] **********************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : copy index.html] *********************************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : copy nginx systemctl file] ***********************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : copy dependency package] *************************************************************************************************************************
changed: [192.168.20.213] => (item=openssl-1.0.2r.tar.gz)
changed: [192.168.20.213] => (item=pcre-8.42.tar.gz)
changed: [192.168.20.213] => (item=zlib-1.2.11.tar.gz)
TASK [nginx : install nginx] ***********************************************************************************************************************************
skipping: [192.168.20.213]
TASK [nginx : replace nginx.conf file] *************************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : mkdir nginx vhost directory] *********************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : relpace default.conf file] ***********************************************************************************************************************
changed: [192.168.20.213]
TASK [nginx : start nginx] *************************************************************************************************************************************
skipping: [192.168.20.213]
RUNNING HANDLER [nginx : reload nginx] *************************************************************************************************************************
skipping: [192.168.20.213]
PLAY RECAP *****************************************************************************************************************************************************
192.168.20.213 : ok=8 changed=8 unreachable=0 failed=0
运行nginx playbook
1 | $ ansible-playbook nginx.yml |
执行
ansible-playbook nginx.yml
命令后,ansible将会按照刚刚测试安装的步骤在远端进行安装nginx服务并且启动。
验证安装结果
等待一会nginx playbook将会在远端服务器上安装完毕,现在我们来验证一下结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 在web服务器上查看nginx端口
$ netstat -ptln | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14461/nginx: master
# 查看nginx进程
$ ps -ef | grep nginx
root 14461 1 0 00:39 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 14474 14461 0 00:39 ? 00:00:00 nginx: worker process
nginx 14475 14461 0 00:39 ? 00:00:00 nginx: worker process
nginx 14476 14461 0 00:39 ? 00:00:00 nginx: worker process
nginx 14477 14461 0 00:39 ? 00:00:00 nginx: worker process
root 39501 1664 0 11:38 pts/0 00:00:00 grep --color=auto nginx
# 让我们在内网任意一台电脑上来访问一下该nginx页面
$ curl http://192.168.20.213
this is a test pages! # 结果是我们前面定义的index.html内容
# 访问一下nginx_status的uri
$ curl http://192.168.20.213/nginx_status #前面default.conf.j2文件中定义的nginx location
Active connections: 1
server accepts handled requests
8 8 10
Reading: 0 Writing: 1 Waiting: 0
至此,一个使用ansible-playbook安装nginx服务已完成。