介绍
在本实验中,你将学习如何实现一个完整的 Ansible playbook,在 Red Hat Enterprise Linux (RHEL) 系统上部署一个 Apache Web 服务器。你将从设置 Ansible 项目的基础组件开始,包括创建一个静态 inventory 文件来定义你的托管节点,以及使用 ansible.cfg 文件配置本地 Ansible 环境。
在初始设置之后,你将编写一个多任务 playbook 来自动化核心部署过程。这包括安装和启动 Apache 服务,部署自定义网页,以及配置系统防火墙以允许 HTTP 流量。为了完成实验,你将在 playbook 中添加第二个 play,从命令行测试 Web 服务器,以验证整个部署是否成功。
为 Web 服务器创建静态 Inventory 文件
在本步骤中,你将学习 Ansible inventory 的基础知识。Inventory 是一个文本文件,列出了 Ansible 将要管理的服务器(或“托管节点”)。你将为一组 Web 服务器创建一个简单的静态 inventory 文件,并学习如何验证其内容。
首先,你需要确保你的系统已安装 Ansible。由于它不是默认安装的,你将使用 dnf 包管理器来安装它。
打开你的终端并安装
ansible-core包,它提供了 Ansible 的基础命令行工具。sudo dnf install -y ansible-core你应该会看到输出表明该软件包正在安装和验证。
... Installed: ansible-core-2.16.x-x.el9.x86_64 ... Complete!为了更好地组织,请在你的主目录下为这个项目创建一个专用目录。我们将其命名为
ansible-lab。mkdir -p ~/project/ansible-lab进入你新创建的项目目录。本实验中所有后续操作都将在此位置进行。
cd ~/project/ansible-lab现在,你将创建你的第一个 inventory 文件。Inventory 文件通常以类似 INI 的格式编写。你将使用
nano文本编辑器创建一个名为inventory的文件。nano inventory在
nano编辑器中,添加以下内容。此配置定义了一个名为[webservers]的组,并将你的本地机器localhost添加到该组中。[webservers]是一个组名。组用于通过单个命令定位多个主机。localhost是你要管理的机器的主机名。在这种情况下,它是 LabEx 虚拟机本身。ansible_connection=local是一个特殊变量,它告诉 Ansible 直接在控制节点(你的虚拟机)上执行命令,而不是尝试通过 SSH 连接到它。
[webservers] localhost ansible_connection=local要在
nano中保存文件,请按Ctrl+O,然后按Enter确认文件名,最后按Ctrl+X退出编辑器。创建了 inventory 文件后,你可以使用
ansible-inventory命令来解析该文件并显示其中包含的主机列表。-i标志指定了 inventory 文件的路径。ansible-inventory --list -i inventory该命令将输出 inventory 的 JSON 格式表示,这证实了 Ansible 可以正确读取和理解你的文件。
{ "_meta": { "hostvars": { "localhost": { "ansible_connection": "local" } } }, "all": { "children": ["ungrouped", "webservers"] }, "webservers": { "hosts": ["localhost"] } }
你已成功创建了一个基本的静态 inventory 文件,并验证了 Ansible 可以正确解析它。此 inventory 文件将是你后续步骤中编写 playbook 的基础。
使用 ansible.cfg 配置 Ansible 环境
在本步骤中,你将创建一个 Ansible 配置文件 ansible.cfg。此文件允许你设置 Ansible 的默认行为,从而避免反复在命令行中输入常用选项。通过将 ansible.cfg 文件放在你的项目目录中,你可以定义诸如默认 inventory 文件路径之类的设置,Ansible 在该目录运行时将自动使用这些设置。
你应该仍然处于上一步的 ~/project/ansible-lab 目录中。
使用
nano文本编辑器在当前目录(~/project/ansible-lab)中创建一个名为ansible.cfg的新文件。nano ansible.cfg在
nano编辑器中,添加以下内容。此配置告诉 Ansible 在哪里可以找到你的默认 inventory 文件。[defaults]部分是ansible.cfg文件的一个标准部分,你可以在其中定义大多数默认设置。inventory = ./inventory行将默认 inventory 设置为位于当前目录(.)下的inventory文件。
[defaults] inventory = ./inventory通过按
Ctrl+O,然后按Enter保存文件,最后按Ctrl+X退出。现在你已经配置了默认 inventory 路径,只要你还在
~/project/ansible-lab目录中,就不再需要对 Ansible 命令使用-i标志了。为了测试这一点,再次运行
ansible-inventory --list命令,但这次省略-i inventory部分。ansible-inventory --list你应该会看到与上一步完全相同的 JSON 输出,这证实了由于新的
ansible.cfg配置,Ansible 能够自动找到并使用你的inventory文件。{ "_meta": { "hostvars": { "localhost": { "ansible_connection": "local" } } }, "all": { "children": ["ungrouped", "webservers"] }, "webservers": { "hosts": ["localhost"] } }
通过创建特定于项目的 ansible.cfg,你已经提高了工作流程的效率。这是 Ansible 项目中常见的做法,以确保一致的行为并减少命令行复杂性。
编写 Playbook 来安装和启动 Apache 服务
在本步骤中,你将编写你的第一个 Ansible Playbook。Playbook 是一个用 YAML 格式编写的文件,它描述了要在托管主机上执行的一系列任务。你将创建一个 Playbook,该 Playbook 将在你的 inventory 中定义的 localhost 机器上安装 Apache Web 服务器(httpd)并启动其服务。
你应该仍然处于 ~/project/ansible-lab 目录中。
首先,使用
nano文本编辑器创建一个名为apache.yml的新文件。此文件将包含你的 Playbook。nano apache.yml在
nano编辑器中,你将定义一个“play”。Play 是 Playbook 的核心单元,它将一组主机映射到一组任务。将以下内容添加到apache.yml。---: 这是一个标准的 YAML 标记,表示文档的开始。- name: ...: 这是你的 play 的开始。给它一个描述性的名称是一种最佳实践。hosts: webservers: 这告诉 Ansible 在你的 inventory 文件中的webservers组中的所有主机上运行此 play。become: true: 这指示 Ansible 使用权限提升(如sudo)来执行任务。这对于安装软件或管理服务等操作是必需的。tasks:: 这个关键字开始要执行的任务列表。
--- - name: Install and start Apache web server hosts: webservers become: true tasks:现在,将任务添加到你的 Playbook 中。每个任务都是一个调用 Ansible 模块的单一操作。YAML 中的缩进至关重要,因此请确保任务在
tasks:部分下正确缩进。- 任务 1:安装 httpd。 此任务使用
ansible.builtin.dnf模块来确保安装httpd包。state: present参数意味着如果包缺失,Ansible 将安装它;如果已安装,则不执行任何操作。 - 任务 2:启动 httpd 服务。 此任务使用
ansible.builtin.service模块。state: started确保服务正在运行,而enabled: true确保它将在系统启动时自动启动。
将以下任务添加到你的
apache.yml文件中,直接放在tasks:行下方:- name: Install httpd package ansible.builtin.dnf: name: httpd state: present - name: Start and enable httpd service ansible.builtin.service: name: httpd state: started enabled: true- 任务 1:安装 httpd。 此任务使用
你完整的
apache.ymlPlaybook 现在应该如下所示。请仔细检查缩进。--- - name: Install and start Apache web server hosts: webservers become: true tasks: - name: Install httpd package ansible.builtin.dnf: name: httpd state: present - name: Start and enable httpd service ansible.builtin.service: name: httpd state: started enabled: true保存文件并退出
nano(Ctrl+O,Enter,Ctrl+X)。在运行你的 Playbook 之前,最好使用
ansible-playbook命令和--syntax-check标志来检查其语法错误。ansible-playbook --syntax-check apache.yml如果语法正确,该命令将打印 Playbook 的文件名而不会出现任何错误。
playbook: apache.yml现在,执行 Playbook。
ansible-playbook apache.ymlAnsible 将执行这些任务。由于这是第一次运行,你将看到两个任务的状态都显示为
changed,这表明系统状态已被修改。PLAY [Install and start Apache web server] ************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Install httpd package] *************************************************** changed: [localhost] TASK [Start and enable httpd service] ****************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0最后,通过使用
curl从localhost请求默认网页来验证 Apache Web 服务器是否正在运行。curl http://localhost你应该会看到默认的 Apache 测试页面,这证实了你的 Playbook 已成功运行。
<html> <head> <title>Test Page</title> </head> <body> <h1>Test Page</h1> <p>This is the default test page for the Apache HTTP server.</p> </body> </html>
添加任务以部署网页
在本步骤中,你将扩展你的 Playbook 以执行更实际的 Web 服务器配置。你将添加一个任务来部署自定义的 index.html 页面。这演示了如何使用 Ansible 的文件管理模块来管理文件。
你应该仍然处于 ~/project/ansible-lab 目录中。
首先,创建一个简单的 HTML 文件,你的 Playbook 将部署该文件。使用
nano在当前目录中创建一个名为index.html的文件。nano index.html将以下 HTML 内容添加到文件中。这将是你自定义网页的内容。
<h1>Welcome to the Ansible-managed Web Server!</h1> <p>This page was deployed using an Ansible Playbook.</p>保存并退出
nano(Ctrl+O,Enter,Ctrl+X)。现在,你将更新你的
apache.ymlPlaybook 以添加新任务。为避免 YAML 格式错误,建议用下面显示的完整内容重新创建该文件。重要提示:为确保正确的 YAML 格式并避免缩进错误,请删除现有的
apache.yml文件,并用下面显示的完整内容创建一个新文件。rm apache.yml nano apache.yml你将向 Playbook 添加一个新任务。此任务会将
index.html文件复制到 Web 服务器的文档根目录(/var/www/html/)。- 任务:部署 index.html。 此任务使用
ansible.builtin.copy模块。src指定控制节点上的源文件(index.html),dest指定托管主机上的目标路径。
- 任务:部署 index.html。 此任务使用
复制并粘贴下面完整的
apache.ymlPlaybook 内容。这确保了正确的 YAML 格式和缩进。--- - name: Install and start Apache web server hosts: webservers become: true tasks: - name: Install httpd package ansible.builtin.dnf: name: httpd state: present - name: Deploy custom index.html ansible.builtin.copy: src: index.html dest: /var/www/html/index.html - name: Start and enable httpd service ansible.builtin.service: name: httpd state: started enabled: true保存并退出
nano。保存文件并退出
nano(Ctrl+O,Enter,Ctrl+X),然后运行更新后的 Playbook。ansible-playbook apache.yml这次,你应该会看到新任务正在执行。“Install httpd”和“Start httpd”任务应报告
ok,因为它们的目标状态已满足。“Deploy custom index.html”任务将报告changed。PLAY [Install and start Apache web server] ************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Install httpd package] *************************************************** ok: [localhost] TASK [Deploy custom index.html] ************************************************ changed: [localhost] TASK [Start and enable httpd service] ****************************************** ok: [localhost] PLAY RECAP ********************************************************************* localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0最后,再次使用
curl来验证你的自定义网页是否已提供服务。curl http://localhost输出现在应该是你的
index.html文件中的内容。<h1>Welcome to the Ansible-managed Web Server!</h1> <p>This page was deployed using an Ansible Playbook.</p>
实现第二个 Play 来测试 Web 服务器部署
在最后这个步骤中,你将为你的 Playbook 添加第二个 Play。一个 Playbook 文件可以包含多个 Play,它们会按顺序执行。这对于组织针对不同主机或具有不同目的的任务非常有用。你将添加一个新 Play,该 Play 只在控制节点(localhost)上运行,以测试在第一个 Play 中配置的 Web 服务器。
你应该仍然处于 ~/project/ansible-lab 目录中。
你现在将为你的 Playbook 添加第二个 Play。为确保在添加第二个 Play 时具有正确的 YAML 格式,建议用下面显示的完整双 Play 内容重新创建该文件。
重要提示:为避免在添加第二个 Play 时出现 YAML 缩进错误,请删除现有的
apache.yml文件,并用下面显示的完整双 Play 内容创建一个新文件。rm apache.yml nano apache.yml你将向 Playbook 添加第二个 Play。第二个 Play 允许你组织针对不同主机或具有不同目的的任务。
name: Test web server: 为新 Play 提供一个描述性名称。hosts: localhost: 此 Play 将在localhost(即控制节点本身)上运行。become: false: 此测试不需要 root 权限,因此我们显式禁用了权限提升。- 任务:验证 Web 内容。 此任务使用
ansible.builtin.uri模块向 Web 服务器发出 HTTP 请求。它检查服务器是否返回状态码 200(OK),并且返回的内容是否包含字符串 "Ansible-managed"。这自动化了你一直在手动进行的curl和grep检查。
复制并粘贴下面完整的
apache.ymlPlaybook 内容,该内容现在包含两个 Play:--- - name: Install and start Apache web server hosts: webservers become: true tasks: - name: Install httpd package ansible.builtin.dnf: name: httpd state: present - name: Deploy custom index.html ansible.builtin.copy: src: index.html dest: /var/www/html/index.html - name: Start and enable httpd service ansible.builtin.service: name: httpd state: started enabled: true - name: Test web server from localhost hosts: localhost become: false tasks: - name: Verify web server is serving correct content ansible.builtin.uri: url: http://localhost return_content: yes status_code: 200 register: result failed_when: "'Ansible-managed' not in result.content"保存文件并退出
nano(Ctrl+O,Enter,Ctrl+X)。运行完整的 Playbook。Ansible 将执行第一个 Play,发现所有任务都已处于其目标状态(
ok),然后继续执行第二个 Play 来运行测试。ansible-playbook apache.yml输出将显示两个 Play 的执行情况。所有任务都应成功完成,状态为
ok。PLAY [Install and start Apache web server] ************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Install httpd package] *************************************************** ok: [localhost] TASK [Deploy custom index.html] ************************************************ ok: [localhost] TASK [Start and enable httpd service] ****************************************** ok: [localhost] PLAY [Test web server from localhost] ****************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Verify web server is serving correct content] **************************** ok: [localhost] PLAY RECAP ********************************************************************* localhost : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
通过添加第二个 Play,你创建了一个更健壮的自动化工作流,该工作流不仅配置了服务,还包含了一个内置测试来验证部署是否成功。
总结
在本实验中,你学习了如何通过安装 ansible-core 包和构建项目目录来准备 RHEL 环境以进行 Ansible 自动化。你创建了一个基础的静态 inventory 文件来定义一组托管节点,指定了使用本地连接的 localhost。你还使用 ansible.cfg 文件配置了 Ansible 环境,使其指向你的自定义 inventory,从而为运行 Playbook 建立了一个干净且有组织的 workspace。
然后,你编写了一个全面的 Ansible Playbook 来自动化 Apache Web 服务器的部署。这包括使用 ansible.builtin.dnf 模块编写安装 httpd 包的任务,以及使用 ansible.builtin.service 模块确保服务已启动并启用。该 Playbook 通过使用 ansible.builtin.copy 模块部署自定义的 index.html 网页进行了增强。最后,你在同一个 Playbook 中实现了第二个 Play 来验证部署,使用 ansible.builtin.uri 模块测试与新部署的 Web 服务器的连接性,展示了一个完整的设置和验证工作流。


