介绍
软件包已安装、配置文件存在以及服务能响应,是不同的结果。你将分别明确管理它们:安装和移除工具、配置 nginx、声明其运行状态,并通过处理程序重新加载发生变化的配置。两个受管节点的实际 HTTP 响应将证明服务可用。
声明软件包的已安装与缺失状态
本步骤将安装一个小工具,检查它,然后通过可复用的软件包声明将其移除。
apt 模块管理受管主机上的 Ubuntu 软件包。state: present 请求安装,state: absent 请求移除。此环境包含预先准备的软件包列表和缓存下载,因此请保持 update_cache: false;刷新列表或请求最新版本会引入不必要的网络依赖。生产环境更新策略可能不同。
进入控制节点项目:
cd /home/labex/project
创建 playbook,通过变量选择 tree 软件包的期望状态。软件包操作需要在目标上使用 become。install_recommends: false 避免安装可选的推荐软件包。
cat > packages.yml <<'YAML'
- name: Declare a utility package state
hosts: all
gather_facts: false
become: true
vars:
utility_state: present
tasks:
- name: Converge the tree package
ansible.builtin.apt:
name: tree
state: "{{ utility_state }}"
update_cache: false
install_recommends: false
YAML
安装工具:
ansible-playbook packages.yml
tree 命令显示目录树;这里使用版本选项,证明可执行文件确实安装在各受管节点上:
ansible all -m ansible.builtin.command -a 'tree --version'
各目标应返回 tree 版本。重复运行 playbook;已存在的软件包应无需再次安装:
ansible-playbook packages.yml
现在通过额外变量请求缺失状态,无需编辑可复用任务:
ansible-playbook packages.yml -e utility_state=absent
重复相同的期望缺失状态。两行汇总现在均应显示 changed=0、failed=0 和 unreachable=0:
ansible-playbook packages.yml -e utility_state=absent
软件包状态是关于安装的声明,不能证明服务正在运行或响应。保持 tree 缺失,下一步将部署 nginx。
配置并启动真实的 Web 服务
本步骤将安装 nginx,部署完整且经过验证的配置,并明确保持服务运行。
两个受管节点是具有独立 SSH 端点和文件系统的容器。它们不运行 systemd。service 模块使用其可用的服务管理器;不要在这些目标上运行 systemctl。我们将管理当前运行状态,而非承诺 systemd 开机策略。
在控制节点创建静态页面。页面以换行结尾,使受管字节精确且可预测:
printf 'Ansible service ready\n' > page.txt
编写完整的 nginx 配置。events 和 http 是 nginx 顶层上下文,server 定义网站,listen 选择端口 8080,root 选择文档目录,index 为 / 请求选择页面。这些是 nginx 设置,而非 Ansible YAML。
cat > nginx-course.conf <<'NGINX'
events {}
http {
server {
listen 8080;
root /var/www/ansible-site;
index index.html;
}
}
NGINX
创建部署 playbook。apt 任务使用 policy_rc_d: 101,防止软件包安装器隐式启动 nginx;后续 service 任务明确声明运行状态。copy 任务的 validate 在替换目标前,对临时候选文件(%s)运行 nginx 配置测试。
处理程序是列于 handlers 下的具名操作。发生更改的配置任务通知 Reload nginx,使其在 play 结束时运行一次。配置无更改就无通知。普通 service 任务使用 started,让已运行的服务保持运行,避免无条件重启。
cat > web.yml <<'YAML'
- name: Deploy a working web service
hosts: all
gather_facts: false
become: true
tasks:
- name: Install nginx without refreshing the prepared package lists
ansible.builtin.apt:
name: nginx
state: present
update_cache: false
install_recommends: false
policy_rc_d: 101
- name: Prepare the site directory
ansible.builtin.file:
path: /var/www/ansible-site
state: directory
owner: root
group: root
mode: "0755"
- name: Deploy the static page
ansible.builtin.copy:
src: /home/labex/project/page.txt
dest: /var/www/ansible-site/index.html
owner: root
group: root
mode: "0644"
- name: Validate and deploy nginx configuration
ansible.builtin.copy:
src: /home/labex/project/nginx-course.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
validate: /usr/sbin/nginx -t -c %s
notify: Reload nginx
- name: Keep nginx running
ansible.builtin.service:
name: nginx
state: started
handlers:
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
YAML
检查语法,然后应用部署:
ansible-playbook web.yml --syntax-check
ansible-playbook web.yml
两个节点都应安装 nginx、收到文件并成功启动。首次配置更改也会调度重新加载处理程序。仅检查软件包版本无法证明这些服务行为。
curl 是 HTTP 客户端。--fail 将不成功的 HTTP 状态视为命令失败;--silent 去除进度输出,--show-error 保留失败详情。在各受管主机上,针对其自身的回环接口执行:
ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error http://127.0.0.1:8080/'
各结果应包含 Ansible service ready。控制节点和各目标拥有独立的回环接口;此命令检查的是两个目标服务,而非控制节点。
通过处理程序应用配置更改
本步骤将更改正在运行的 nginx 设置,观察处理程序,并通过 HTTP 响应确认该设置。
nginx 的 server_tokens 指令控制响应头是否暴露 nginx 版本。将控制节点配置替换为以下完整版本,在 http 内添加 server_tokens off:
cat > nginx-course.conf <<'NGINX'
events {}
http {
server_tokens off;
server {
listen 8080;
root /var/www/ansible-site;
index index.html;
}
}
NGINX
应用相同 playbook:
ansible-playbook web.yml
配置复制应在两台主机上报告 changed,并通知 Reload nginx。新配置通过验证后,处理程序重新加载运行中的服务。执行处理程序使配置生效;仅复制文件不能证明进程加载了什么。
curl 的 -I 请求 HTTP 响应头。检查两台主机的实际服务响应:
ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error -I http://127.0.0.1:8080/'
两个响应都应具有成功的 HTTP 状态,Server 响应头为 nginx,不带版本后缀。日期等其他响应头字段会变化。
重复完整 playbook:
ansible-playbook web.yml
两台主机均应报告 changed=0,无失败或不可达任务,也不应调度重新加载处理程序。静态页面仍然可用,tree 仍然缺失,nginx 仍已安装且运行。
总结
你声明了软件包的存在与缺失状态,将安装与服务运行状态分开,并部署了带候选文件验证的完整 nginx 配置。配置更改通知了重新加载处理程序,实际 HTTP 响应证明了实时行为,未更改的重复运行则避免了额外更改和重新加载。


