目录
- 写在前面
- 5. Ansible Playbook 剧本
- 5.1 YAML语法
- 5.1.1 语法规定
- 5.1.2 示例
- 5.1.3 YAML数据类型
- 5.2 Playbook组件
- 5.3 Playbook 案例
- 5.3.1 Playbook语句
- 5.3.2 Playbook1 分发hosts文件
- 5.3.3 Playbook2 分发软件包,安装软件包,启动服务
- 5.3.3.1 任务拆解
- 5.3.3.2 步骤变模块
- 5.3.3.3 编写playbook
- 5.3.3.4 测试并运行playbook
- 5.3.4 Playbook3 nfs服务
- 5.3.4.1 任务拆解
- 5.3.4.2 步骤变模块
- 5.3.4.3 编写playbook
- 5.3.4.4 测试并运行
写在前面
这是Ansible系列第三篇,内容为Ansible Playbook的介绍、使用
序号连续上篇笔记 Ansible02-Ansible Modules模块详解
回顾一下Ansible架构:
5. Ansible Playbook 剧本
Playbook,剧本,即Ansible中的脚本。用于配置、部署、管理被控节点。
就如同这个名字,Ansible会一步步执行Playbook中的内容,并相应返回OK
,Changed
,False
,Skipped
等反馈。
Ad-hoc的执行方式在多Modules时,过于繁琐,而为Ad-hoc编写shell脚本,又有点本末倒置。
Playbook语法尊崇yaml语法格式,文件名以.yaml
或.yml
为后缀。
5.1 YAML语法
一种类似XML、JSON的标记性语言。强调以数据为中心,号称“一种人性化的数据格式语言”(我没觉得多人性化)
5.1.1 语法规定
- 严格区分大小写
- 使用缩进标识层级关系
- 缩进不可用tab,只使用空格。空格数量没有要求,但同一层级需要保持一致。
#
标识注释"
后需要有一个空格- 多段YAML配置放在一个文件,用
---
分割
YAML转JSON语法网站,可用于验证yaml语法是否正确
http://json2yaml.com/convert-yaml-to-json
5.1.2 示例
#xml
<zhangsan>
<age>30</age>
<address>tianjin</address>
<dianha>132xxxxxx</dianha>
<youxiang>xx@163.com</youxiang>
</zhangsan>
#yaml
yunwei:
chengyuan: 10
gangwei: weihu
---
kaifa:
chengyuan: 25
gangwei: kaifa
---
ceshi:
chengyuan: 5
gangwei: ceshi
5.1.3 YAML数据类型
- 纯量(布尔值、整数、浮点数、Null、时间、日期、字符串)
#布尔类型
c1: true(真),false(假)
#整数
c2: 123
#浮点型(小数)
c3: 123.1
#null类型(使用~表示null)
c4: ~
#日期类型,日期必须使用ISO 8601格式,即yyyy-MM-dd
c5: 2024-05-28
#时间类型,时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
c6: 2024-05-28T08:34:20+08:00
#字符串类型,简单写法直接写值即可,如果字符串中间有特殊字符,必须使用单引或双引括起来
c7: 'thi*!$hello'
#字符串类型,字符串过多的情况可以使用引号拆成多行,每一行会被转化成一个空格
c8: "hello word
xxxxxxxxxx"
- 对象(键值对)
#对象形式一(推荐)
zhangsan:
age: 25
address: beijing
#对象形式二(了解)
zhangsan: {age: 25,address: beijing}
- 数组(列表)
#数组形式一(推荐)
lisi:
age: 24
address:
- nanjing
- beijing
#数组形式二(了解)
address: [nanjing,beijing]
5.2 Playbook组件
playbook是由一个或者多个play组成的列表,可以让这些列表按事先编排的机制执行
task是调用ansible的具体模块,在模块参数中可以使用变量。模块执行是幂等性的,意味着多次执行结果相同。
- hosts:执行的远程主机列表
- remote_user: 指定以远程主机哪个用户的身份执行命令
- tasks:任务集
- variables:内置变量或自定义变量在playbook中调用
- tempaltes 模板,可替换文件中的变量并实现一些简单逻辑的文件
- handles 处理程序和notify结合使用,由特定条件触发的操作,满足条件方执行,否则不执行
- tags标签,指定某条任务执行,用于选择运行playbook中的部分代码。
5.3 Playbook 案例
5.3.1 Playbook语句
#运行剧本,playbook以yml或yaml结尾皆可
ansible-playbook xxx.yaml/xxx.yml
#--syntax-check 用于检测playbook语法是否正确,如果正确只返回playbook名称
ansible-playbook --syntax-check xxx.yaml/xxx.yml
#--check 用于模拟执行playbook
ansible-playbook --check xxx.yaml/xxx.yml
5.3.2 Playbook1 分发hosts文件
# 编写playbook
[root@manager playbook]# cat 02.fenfa.yaml
- hosts: front,docker
tasks:
- name: 01.create the directory
# file: path=/server/files state=directory
file:
path: /server/files
state: directory
- name: 02.send the file
copy:
src: /etc/hosts
dest: /server/files
- 解释:
## Playbook 文件:`02.fenfa.yaml`
这个Playbook 指定了两个任务,这些任务将在名为 `front` 和 `docker` 的主机上执行。
### 主机(Hosts)
- `front,docker`:这些是目标主机的名称,Playbook 将会在这两个主机上执行定义的任务。
### 任务列表(Tasks)
#### 任务 1: 创建目录 (`01.create the directory`)
- **名称**: `01.create the directory` — 此任务的描述性名称。
- **模块**: `file` — Ansible 的文件模块,用于文件和目录的管理。
- **参数**:
- `path`: `/server/files` — 指定了要创建的目录的路径。
- `state`: `directory` — 确保指定路径被创建为一个目录。
#### 任务 2: 发送文件 (`02.send the file`)
- **名称**: `02.send the file` — 此任务的描述性名称。
- **模块**: `copy` — Ansible 的复制模块,用于将文件从本地复制到远程主机。
- **参数**:
- `src`: `/etc/hosts` — 指定了要复制的源文件的路径,这里是本地的 `/etc/hosts` 文件。
- `dest`: `/server/files` — 指定了复制文件到远程主机上的目标路径。
### 特殊说明
- 注释掉的行(以 `#` 开头)表示该行被注释,不会执行。在这个例子中,`file` 模块的一行被注释了,这意味着实际执行时将使用未注释的 `file` 模块的配置。
这个Playbook 的目的是在 `front` 和 `docker` 这两个主机上创建一个名为 `/server/files` 的目录,并将本地的 `/etc/hosts` 文件复制到该目录中。
# 执行语法检查,若成果只返回文件名
[root@manager playbook]# ansible-playbook --syntax-check 02.fenfa.yaml
playbook: 02.fenfa.yaml
# 模拟运行,只会返回结果而不会真实运行
[root@manager playbook]# ansible-playbook --check 02.fenfa.yaml
PLAY [front,docker] **************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.100.148]
ok: [192.168.100.141]
TASK [01.create the directory] ***************************************************************************************
ok: [192.168.100.148]
changed: [192.168.100.141]
TASK [02.send the file] **********************************************************************************************
changed: [192.168.100.141]
changed: [192.168.100.148]
PLAY RECAP ***********************************************************************************************************
192.168.100.141 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.148 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#真正的playbook运行
[root@manager playbook]# ansible-playbook 02.fenfa.yaml
PLAY [front,docker] **************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.100.148]
ok: [192.168.100.141]
TASK [01.create the directory] ***************************************************************************************
ok: [192.168.100.148]
changed: [192.168.100.141]
TASK [02.send the file] **********************************************************************************************
changed: [192.168.100.148]
changed: [192.168.100.141]
PLAY RECAP ***********************************************************************************************************
192.168.100.141 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.148 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 检查运行结果是否正确
[root@manager playbook]# ansible docker,front -m shell -a 'tree /server/files; cat /server/files/hosts'
192.168.100.141 | CHANGED | rc=0 >>
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.151 manager
192.168.100.150 storage
192.168.100.149 backup
192.168.100.148 front
192.168.100.141 docker
192.168.100.148 | CHANGED | rc=0 >>
/server/files
└── hosts
0 directories, 1 file
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.151 manager
192.168.100.150 storage
192.168.100.149 backup
192.168.100.148 front
192.168.100.141 docker
5.3.3 Playbook2 分发软件包,安装软件包,启动服务
以zabbix-agent为例
5.3.3.1 任务拆解
- 下载
wget https://mirrors.aliyun.com/zabbix/zabbix/6.5/centos/8/x86_64/zabbix-agent-7.0.0-alpha3.release1.el8.x86_64.rpm
- 安装
yum install -y zabbix-agent-7.0.0-alpha3.release1.el8.x86_64.rpm
-
配置(略)
-
启动开机
5.3.3.2 步骤变模块
wget -> get_url
yum -> yum
配置 -> debug模拟
systemctl -> systemd
5.3.3.3 编写playbook
- hosts: front,docker
tasks:
- name: 01.download the zabbix-agent
get_url:
url: https://mirrors.aliyun.com/zabbix/zabbix/6.5/centos/8/x86_64/zabbix-agent-7.0.0-alpha3.release1.el8.x86_64.rpm
dest: /tmp/
validate_certs: no #关闭校验
- name: 02.yum install za
yum:
name: /tmp/zabbix-agent-7.0.0-alpha3.release1.el8.x86_64.rpm
state: present
disable_gpg_check: yes #关闭gpgcheck
- name: 03.配置
debug:
msg: "模拟配置zabbix-agent"
- name: 04.startup
systemd:
name: zabbix-agent
enabled: yes
state: started
5.3.3.4 测试并运行playbook
#测试语法合格
[root@manager playbook]# ansible-playbook --syntax-check 03.install-zabbix-agent.yaml
playbook: 03.install-zabbix-agent.yaml
#模拟测试运行
[root@manager playbook]# ansible-playbook --check 03.install-zabbix-agent.yaml
#运行
[root@manager playbook]# ansible-playbook 03.install-zabbix-agent.yaml
PLAY [front,docker] **************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.100.148]
ok: [192.168.100.141]
TASK [01.download the zabbix-agent] **********************************************************************************
ok: [192.168.100.148]
ok: [192.168.100.141]
TASK [02.yum install za] *********************************************************************************************
changed: [192.168.100.141]
changed: [192.168.100.148]
TASK [03.配置] *******************************************************************************************************
ok: [192.168.100.148] => {
"msg": "模拟配置zabbix-agent"
}
ok: [192.168.100.141] => {
"msg": "模拟配置zabbix-agent"
}
TASK [04.startup] ****************************************************************************************************
changed: [192.168.100.148]
changed: [192.168.100.141]
PLAY RECAP ***********************************************************************************************************
192.168.100.141 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.148 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5.3.4 Playbook3 nfs服务
5.3.4.1 任务拆解
- 服务端backup:
- 部署nfs-utils,rpcbind
- 修改配置文件
- 创建共享目录并修改所有者
- 启动服务rpcbind、nfs
- 客户端front:
- 安装nfs-utils
- 配置挂载
5.3.4.2 步骤变模块
- 服务端:
- 部署 -> yum
- 配置文件 -> lineinfile
- 创建共享目录 -> file
- 启动服务 -> systemd
- 客户端:
- 安装 -> yum
- 挂载 -> mount
5.3.4.3 编写playbook
- hosts: backup
tasks:
- name: 1. 部署nfs-utils,rpcbind
yum:
name: nfs-utils,rpcbind
state: present
- name: 2. 修改配置文件
lineinfile:
path: /etc/exports
line: "/backup-nfs *(rw,all_squash)"
create: true
- name: 3. 创建共享目录并修改所有者
file:
path: /backup-nfs
state: directory
owner: nobody
group: nobody
- name: 4. 启动服务rpcbind
systemd:
name: rpcbind
enabled: yes
state: started
- name: 5. 启动服务nfs
systemd:
name: nfs-server
enabled: yes
state: started
- hosts: front
tasks:
- name: 1. 安装nfs-utils
yum:
name: nfs-utils
state: present
- name: 2. 配置挂载
mount:
src: 192.168.100.149:/backup-nfs
path: /ans-upload
#挂载点不存在会自动创建
fstype: nfs
state: mounted
5.3.4.4 测试并运行
# 语法测试
[root@manager playbook]# ansible-playbook --syntax-check 04.deploy_nfs.yaml
playbook: 04.deploy_nfs.yaml
#运行
[root@manager playbook]# ansible-playbook 04.deploy_nfs.yaml
PLAY [backup] ********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.100.149]
TASK [1. 部署nfs-utils,rpcbind] *************************************************************************************
ok: [192.168.100.149]
TASK [2. 修改配置文件] ***********************************************************************************************
ok: [192.168.100.149]
TASK [3. 创建共享目录并修改所有者] ***********************************************************************************
ok: [192.168.100.149]
TASK [4. 启动服务rpcbind] ********************************************************************************************
ok: [192.168.100.149]
TASK [5. 启动服务nfs] ************************************************************************************************
ok: [192.168.100.149]
PLAY [front] *********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.100.148]
TASK [1. 安装nfs-utils] **********************************************************************************************
ok: [192.168.100.148]
TASK [2. 配置挂载] ***************************************************************************************************
changed: [192.168.100.148]
PLAY RECAP ***********************************************************************************************************
192.168.100.148 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.149 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0