在本章中,我将为您介绍什么是 Ansible Playbook,以及为什么您需要它。我们将从一个简单的 Playbook 开始,涵盖基本语法以及如何添加更多任务。
Playbook 是什么?
Playbook 是一组针对主机清单执行的“Play(场次)”。每个 Playbook 都基于 YAML 语法编写,因此文件易于阅读和理解。YAML 是一种文本格式,您可以通过文件开头的三个破折号(---)和结尾的三个点(...)来识别它。虽然结尾的三个点不是必需的,但很多人会省略它们。这种文件类型对元素之间的空格非常敏感,同一级别的元素必须具有相同的缩进。您可以使用“#”符号添加注释,即使在已有代码的行上也可以。字符串非常重要,您可以直接指定,也可以使用单引号或双引号。我建议您通常使用双引号。通过使用管道符号(|)和大于号(>)语句,您可以定义多行字符串。第一种语句会保留换行符,而第二种则不会。其他有用的数据结构包括字典和列表,您可以在灰板中看到它们的实际应用。
示例:Hello World Playbook
文件名:helloworld.yml
---
- name: Hello World sample
hosts: all
tasks:
- name: Hello message
ansible.builtin.debug:
msg: "Hello World!"
...
- 文件名:
helloworld.yml - Playbook 名称:Hello World sample
- 执行目标主机:所有主机(
all) - 任务列表:一个名为“Hello message”的任务
- 模块:
ansible.builtin.debug - 模块参数:
msg参数的值为“Hello World!”
这是执行“helloworld.yml”时的输出。请注意,使用的命令是 ansible-playbook,第一个参数是主机清单文件,第二个参数是 Playbook 文件。在此执行中,Play 针对 host1.example.com 节点运行。输出清晰地展示了逐步执行的过程。当命令成功时,输出会以绿色突出显示。警告会以橙色显示,错误则以红色显示。细心的读者可能注意到,执行中有一个额外的任务“Gathering Facts(收集事实)”,这是 Ansible 用来获取受管节点信息的操作。我们将在后续课程中进一步讨论事实收集。您可以尝试自己执行这段代码,并熟悉这种输出总结,这将非常有用。在此示例中,共执行了两个任务。
提示 1:--check 选项
$ ansible-playbook -i inventory --check helloworld.yml
--check 是 ansible-playbook 命令的一个非常有用的选项。它允许您对 Playbook 执行进行“试运行”,Ansible 会报告如果执行 Playbook 将会发生哪些更改,但不会对受管主机进行任何实际更改。
提示 2:调试的日常使用
文件名:helloworld_debug.yml
---
- name: Hello World sample
hosts: all
tasks:
- name: Hello message
debug:
msg: "Hello World!"
verbosity: 2
...
- 文件名:
helloworld_debug.yml - Playbook 名称:Hello World sample
- 执行目标主机:所有主机(
all) - 任务列表:一个名为“Hello message”的任务
- 模块:
debug - 模块参数:
msg参数的值为“Hello World!” - 参数:
verbosity设置为“2”
此提示允许您在 Playbook 中保留调试代码,并仅在需要时启用执行。例如,只有在使用 Ansible 时指定输出级别为 2,才会打印消息。
示例:helloworld_debug.yml 的执行(第一部分)
$ ansible-playbook -i inventory helloworld_debug.yml
这是以正常模式(非调试模式)执行“helloworld_debug.yml”时的输出。正如您所看到的,“Hello message” 被跳过了。
示例:helloworld_debug.yml 的执行(第二部分)
$ ansible-playbook -i inventory -vv helloworld_debug.yml
这是以调试级别 2 模式执行“helloworld_debug.yml”时的输出。请注意命令行中的两个“v”。正如您所看到的,“Hello message” 被打印出来了。
幂等性(Idempotency)
Ansible 模块的一个重要特性是“幂等性”。这意味着在对目标节点执行任何操作之前,模块会检查当前状态。如果当前状态与期望状态一致,则不会执行任何操作;如果当前状态与期望状态不一致,则会执行操作。请注意,如果您再次执行 Playbook,期望状态将被找到,且不会执行任何进一步的操作。这种特性称为“幂等性”,您可以充分利用它。
示例:包含多个 Play 的 Playbook
文件名:multipleplays.yml
---
- name: first play
hosts: web.example.com
tasks:
- name: first task
ansible.builtin.yum:
name: httpd
state: present
- name: second task
ansible.builtin.service:
name: httpd
enabled: true
- name: second play
hosts: database.example.com
tasks:
- name: first task
ansible.builtin.service:
name: mariadb
enabled: true
- 文件名:
multipleplays.yml - 包含两个 Play:第一个 Play 针对
web.example.com主机,安装并启用 Apache Web 服务器;第二个 Play 针对database.example.com主机,启用 MariaDB 数据库管理系统。
“multipleplays.yml” Playbook 包含两个 Play。第一个 Play 针对 web.example.com 主机,安装并启用 Apache Web 服务器;第二个 Play 针对 database.example.com 主机,启用 MariaDB 数据库管理系统。正如您所看到的,使用多个 Play 在不同主机上执行不同任务是非常强大的功能。现在,Playbook 的定义变得更加清晰。
示例:特权提升
文件名:privilege_escalation.yml
---
- name: install httpd
hosts: web.example.com
become: true
become_method: sudo
become_user: root
tasks:
- name: install httpd
ansible.builtin.yum:
name: httpd
state: present
become:指定需要特权提升。become_method:指定提升方法(如sudo)。become_user:指定目标用户(默认为root)。
某些操作需要由具有管理员权限的用户执行。在 Linux 中,这通常是 root 用户。某些发行版允许通过 sudo 命令和 wheel 组进行特权提升。在此示例中,我需要安装软件,因此需要特权提升。yum 模块需要在受管节点上执行某些操作。如果不需要,您可以在 Playbook 中禁用特权提升。
常见的 Ansible 模块
文件模块
copy:将本地文件复制到受管主机。fetch:从远程节点复制文件到本地。file:设置文件的权限和其他属性。lineinfile:确保文件中存在或不存在某一行。synchronize:使用rsync同步内容。
软件包模块
package:通过操作系统原生的包管理器管理软件包。yum:通过 YUM 包管理器管理软件包。apt:通过 APT 包管理器管理软件包。dnf:通过 DNF 包管理器管理软件包。gem:管理 Ruby gem 包。pip:从 PyPI 管理 Python 包。
系统模块
firewalld:通过 firewalld 管理任意端口和服务。reboot:重启机器。service:管理服务。user:添加、删除和管理用户账户。
网络工具模块
get_url:通过 HTTP、HTTPS 和 FTP 下载文件。nmcli:管理网络配置。uri:与 Web 服务交互。
总结
在本章中,我们为后续的 Ansible Playbook 操作奠定了基础。继续学习,很快您就能自动化所有系统管理员的任务。