管理软件包与可用的服务

AnsibleBeginner
立即练习

介绍

软件包已安装、配置文件存在以及服务能响应,是不同的结果。你将分别明确管理它们:安装和移除工具、配置 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 响应证明了实时行为,未更改的重复运行则避免了额外更改和重新加载。