☰
90DaysOfDevOps 实战:用 Ansible Role 与 Nginx 为 Web 集群搭建负载均衡器(Day 67)
2026/10/7 19:55:25 网站建设 项目流程
  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

本篇指南延续 90DaysOfDevOps 第 66 天的配置管理主题,聚焦于用 Ansible Role 复用机制改造 Playbook:把通用工具安装抽离为commonrole,并新建nginxrole 在独立的loadbalancer虚拟机上完成安装、模板配置与反向代理,最终让http://192.168.169.134/将流量分发到两台 Apache Web 服务器。读完本文,你将掌握import_tasks任务拆分、vagrant up按主机增量拉起、ansible-playbook多主机分组执行以及用ssh-copy-id与 ad-hoc 命令验证环境的方法。

场景回顾:为什么需要 Loadbalancer 虚拟机

在第 66 天我们已经通过ansible-galaxy生成了多个 role 的目录骨架,并把 Apache 的配置代码按 role 收进独立目录。当前环境由 Vagrantfile 定义四台 Ubuntu 21.10 虚拟机:

主机名IPSSH 转发端口角色
db01192.168.169.1302210数据库(本场景未使用)
web01192.168.169.1312211Apache Web 服务器
web02192.168.169.1322212Apache Web 服务器
loadbalancer192.168.169.1342213Nginx 负载均衡/反向代理

在此之前我们只通过vagrant up web01 web02启动了两台 Web 服务器,并依靠playbook3.yml完成 Apache 安装与页面定制。第 67 天的目标是为集群引入入口代理:先启动loadbalancer虚拟机,再让它承载 Nginx,把请求代理到 web01 与 web02 两台上游服务器上。

启动 loadbalancer 虚拟机并打通 SSH

由于 loadbalancer 尚未启动,它虽然已写进 inventory 但还没有配置 SSH 密钥,需要先执行:

vagrant up loadbalancer

该命令会读取 Vagrantfile 中:hostname => "loadbalancer"的定义,复用bento/ubuntu-21.10镜像,分配公网 IP192.168.169.134与宿主机 2213 端口,并沿用 2048MB 内存的 VirtualBox 配置。虚拟机就绪后,把本机 SSH 公钥复制过去,使 Ansible 后续能免密连接:

ssh-copy-id loadbalancer

确认ssh loadbalancer能直接登录后,即可开始改造 Playbook。

common role:把公共工具安装抽成可复用任务

第 66 天创建的commonrole 定位是"所有主机都会用到"的基础角色。查看 roles/common/tasks/main.yml,它不再内联任务,而是通过import_tasks引入独立文件:

--- # tasks file for roles/common - import_tasks: install_tools.yml

选择import_tasks而非旧式的include,是因为 Ansible 已计划弃用include的静态包含语义,import_tasks会在 Playbook 解析阶段静态导入,行为更可预期。被导入的 install_tools.yml 使用 apt 模块批量安装三个通用工具:

- name: "Install Common packages" apt: name={{ item }} state=latest with_items: - neofetch - tree - figlet

要点说明:

  • state=latest表示始终升级到最新版本,适合通用小工具;若希望锁定版本可用state=present;
  • with_items循环让{{ item }}依次取 neofetch、tree、figlet 三个包名,一次任务完成全部安装。

这样无论 webservers 还是 proxy 主机组,都能在各自的 Playbook 块中复用 common role,避免在每个角色里重复编写安装逻辑。

更新 Playbook:为 webservers 挂上 common role

在 Playbook 的 webservers 主机块中,把 common role 追加到 roles 列表,让 Apache 配置之前先完成通用工具安装:

- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" roles: - common - apache2

此处保留了第 66 天的变量定义:Apache 监听 8000 端口、HTTPS 端口 4443、首页欢迎语指向 Day 66。完整文件见 playbook4.yml,其中 apache2 role 的入口同样采用import_tasks: apache2_install.yml的拆分模式(见 roles/apache2/tasks/main.yml),保证各角色结构一致。

nginx role:安装、配置与模板三步走

接下来为负载均衡机新建 nginx role。先看它的任务入口 roles/nginx/tasks/main.yml,同样用两次import_tasks把"安装"与"配置"拆开:

--- # tasks file for roles/nginx - import_tasks: install_packages.yml - import_tasks: configure_nginx.yml

第一步:安装 Nginx 软件包,见 install_packages.yml:

- name: "Install Nginx packages" apt: name: nginx state: present

与 common role 的state=latest不同,这里用state=present,只要 nginx 已安装即视为满足,不强制升级。

第二步:部署站点配置并触发重启,见 configure_nginx.yml:

- name: Deploy Nginx sites configuration template: src: mysite.j2 dest: "/etc/nginx/sites-enabled/mysite" notify: restart nginx - name: Remove defaults file: path="/etc/nginx/sites-enabled/default" state=absent

这里使用了 Ansible 的template模块:把 templates/mysite.j2 渲染后写入/etc/nginx/sites-enabled/mysite,并通过notify关联 handler;同时删除 Nginx 自带的default站点,避免默认配置与我们的代理站点冲突。对应的 handler 在 roles/nginx/handlers/main.yml 中定义:

--- # handlers file for roles/nginx - name: restart nginx service: name=nginx state=restarted

handler 只有在 template 任务真正发生变更(changed)时才会被触发,这是 Ansible 保证配置幂等性的典型写法。

mysite.j2:反向代理核心配置

模板内容定义了一个 upstream 组与一个监听 80 端口的 server 块:

upstream webservers { server 192.168.169.131:8000; server 192.168.169.132:8000; } server { listen 80; location / { proxy_pass http://webservers; } }

语义拆解:

  • upstream webservers声明后端服务器组,web01(131)与 web02(132)都监听 8000 端口,与 Playbook 中http_port: 8000保持一致;
  • listen 80让负载均衡机对外提供 HTTP 服务;
  • location /与proxy_pass http://webservers把全部请求转发给 upstream 组,由 Nginx 在两组服务器间做默认的轮询(round-robin)负载均衡。

由于仓库中的模板使用的是作者环境的固定 IP,如果你的 Vagrant 环境分配了不同地址,必须同步修改此文件中的服务器 IP(可从vagrant ssh web01/web02后用hostname -I确认)。

组合 Playbook 与执行

把 webservers 与 proxy 两个主机块合并进同一个 Playbook,形成 playbook4.yml:

- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" roles: - common - apache2 - hosts: proxy become: yes roles: - common - nginx

执行:

ansible-playbook playbook4.yml

运行顺序与效果:

  1. 先在 webservers 组执行 common role(安装 neofetch、tree、figlet)与 apache2 role;
  2. 再到 proxy 组执行 common role 与 nginx role(安装 Nginx、渲染 mysite.j2、删除 default 站点、重启服务)。

执行结果对应仓库中的运行截图:配置完成的输出摘要见 Day67_config1.png,其中 apache2 与 nginx 两个主机块的 task 均以 ok 收尾。

验证方式:在浏览器访问负载均衡机地址http://192.168.169.134/,应能看到 Day 66 中定制的欢迎页面(运行效果见 Day67_config2.png)。由于 Nginx 会在 web01、web02 之间轮询转发,刷新多次可观察到请求被分发到不同的后端。

若访问结果不符合预期,最常见的根因是模板templates\mysite.j2中写死的后端 IP 与本地 Vagrant 分配不一致,按上文说明修正后重新执行ansible-playbook playbook4.yml即可。

用 ad-hoc 命令快速验证安装

不想重跑整个 Playbook 时,可以用 ad-hoc 命令针对单台主机执行检查。例如验证 loadbalancer 上是否装好了 common 工具:

ansible loadbalancer -m command -a neofetch

该命令直接在 proxy 主机上运行neofetch,命令输出即证明 common role 的安装已生效(截图见 Day67_config3.png)。同理可把命令换成tree、figlet -f banner hello或nginx -v来验证对应组件。

小结与下一步

至此我们完成了一次典型的 Ansible Role 重构闭环:

  • 用import_tasks把"安装工具""安装 Nginx""配置 Nginx"拆成独立任务文件,职责单一、易于复用;
  • common role 挂到每个主机组,nginx role 只作用于 proxy 组,实现"公共逻辑共享、专用逻辑隔离";
  • 通过template+handler实现配置即代码与幂等重启,删除 default 站点避免配置冲突;
  • 用vagrant up、ssh-copy-id完成环境搭建,用ansible-playbook与 ad-hoc 命令完成部署与验证。

最终两台 Apache Web 服务器共享一个 Nginx 入口,反向代理与负载均衡生效。第 68 天将继续推进配置管理场景,读者可对照 2022/Days/day68.md 衔接学习。

  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询