☰
90DaysOfDevOps 实战 Day 67:使用 Ansible 角色(Roles)与 Nginx 部署负载均衡器
2026/10/6 12:11:49 网站建设 项目流程
  • 文档/教程

【免费下载链接】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-galaxy生成的角色(Role)体系,在 Vagrant 搭建的 Ubuntu 环境中为 Web 服务器集群部署一个 Nginx 反向代理负载均衡器。文章以仓库中的ansible-scenario4实战场景为骨架,逐层拆解 Common 角色(通用工具安装)、Nginx 角色(安装与配置)、playbook4.yml的多主机编排逻辑,以及 ad-hoc 命令验证方法,读完即可独立复现"两台 Apache Web 服务器 + 一台 Nginx 负载均衡器"的完整自动化部署流程。

场景回顾:从 Day 66 的角色骨架到 Day 67 的负载均衡器

在第 66 天中,我们使用ansible-galaxy命令初始化了一批角色(Role)的文件夹结构,并将之前零散的配置代码收拢进各自的角色目录,使配置仓库变得整洁、职责清晰。当时只有apache2角色投入了实际使用,通过playbook3.yaml管理两台 Web 服务器。

进入 Day 67,目标非常明确:

  1. 新增一台运行 Nginx 的负载均衡器/代理服务器;
  2. 让 Web 服务器与代理服务器都复用通用的common角色;
  3. 为代理主机编写专属的nginx角色(安装 Nginx 并配置反向代理);
  4. 运行更新后的playbook4.yml完成一键部署。

整套实战文件均可在仓库的 ansible-scenario4 目录 中查看,其核心编排入口是 playbook4.yml。

拉起负载均衡器虚拟机

此前环境只启动了web01与web02两台 Web 服务器,现在执行:

vagrant up loadbalancer

即可多出一台作为负载均衡器/代理使用的 Ubuntu 系统。该主机虽然早已写入hosts清单文件,但在虚拟机就绪之前 SSH 密钥尚未配置,因此首次启动完成后还需要手动执行:

ssh-copy-id loadbalancer

把本机的公钥拷贝到新主机上,Ansible 才能通过 SSH 正常连接管理它。

深入角色目录结构:一次看清三个角色的完整骨架

整个场景的目录结构如下(详见 ansible-scenario4 目录):

ansible-scenario4/ ├── playbook4.yml └── roles/ ├── apache2/ # Web 服务器角色 │ ├── defaults/ │ ├── handlers/ │ ├── meta/ │ ├── tasks/ # apache2_install.yml、main.yml │ ├── templates/ # index.html.j2、ports.conf.j2 │ ├── tests/ │ └── vars/ ├── common/ # 所有主机通用角色 │ ├── defaults/ │ ├── handlers/ │ ├── meta/ │ ├── tasks/ # install_tools.yml、main.yml │ ├── tests/ │ └── vars/ └── nginx/ # 负载均衡器角色 ├── defaults/ ├── handlers/ # restart nginx 处理器 ├── meta/ ├── tasks/ # install_packages.yml、configure_nginx.yml、main.yml ├── templates/ # mysite.j2 ├── tests/ └── vars/

这是 Ansible 角色的标准布局:tasks存放实际执行的任务,handlers存放可由任务触发的事件处理器,templates存放基于 Jinja2 的可渲染配置模板,defaults/vars存放变量,meta存放角色依赖等元数据。三个角色共享同一套骨架,但各自只关心自己的职责,这正是"角色化"带来的模块化收益。

Common 角色:为所有服务器统一安装通用工具

common角色被设计为所有主机都会引用的基础角色,而其他角色则按使用场景按需引入。虽然名为 "Common" 的安装包(neofetch、tree、figlet)看起来像玩具,但它的意义在于演示"公共逻辑抽取 + 跨主机复用"这一角色化的核心目的。

用 import_tasks 串联任务文件

角色入口 common/tasks/main.yml 非常精简,只做一件事——把实际任务文件引入进来:

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

注意这里使用的是import_tasks而非旧式的include。include是静态/动态混用的旧写法,已被官方标记为即将弃用;import_tasks在 playbook 解析阶段就会静态展开,任务结构清晰、调试时可预测,是当前推荐的写法。

安装通用包

实际任务定义在 install_tools.yml:

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

逐项说明:

  • apt:基于 Debian/Ubuntu 的包管理模块(当前仓库场景全部为 Ubuntu 主机);
  • name={{ item }}:通过with_items循环批量安装多个包;
  • state=latest:确保软件包升级到最新版本(若希望固定版本,可改为state=present或指定版本号);
  • 安装清单:neofetch(终端系统信息展示)、tree(目录树查看)、figlet(ASCII 艺术字)。

在 playbook 中挂载 Common 角色

随后在 playbook 的每个主机块中追加common角色:

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

这里roles列表中的顺序即执行顺序:先运行common(安装通用工具),再运行apache2(配置 Web 服务)。become: yes表示以提权方式执行(apt 安装需要 root 权限),vars块中定义了本组主机使用的端口与欢迎语变量。

Nginx 角色:在代理主机上安装并配置负载均衡器

下一步是为负载均衡器虚拟机安装并配置 Nginx。与上一节同理,我们同样基于标准角色骨架来组织,只是这次nginx角色的任务拆得更细:安装与配置分离,职责边界更清晰。

playbook 新增 proxy 主机块

在 playbook4.yml 中,原有webservers块保持不变,新增proxy块:

- 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

proxy主机组同样先执行common再执行nginx,实现"基础工具 + 专属服务"的组合式管理。

任务入口:安装与配置两步走

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

state: present保证 nginx 已安装(不要求升级到最新),比latest更稳,适合生产环境锁定可预期状态。

第二步:配置站点并移除默认站点,见 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

关键点:

  • template模块将 Jinja2 模板 mysite.j2 渲染后写入/etc/nginx/sites-enabled/mysite;
  • notify: restart nginx触发同名 handler——只有当模板内容发生变化时,handler 才会真正重启 Nginx,这是 Ansible 幂等性的典型体现;
  • 第二条任务删除 Nginx 自带的default站点,避免默认配置抢占 80 端口;
  • 重启动作定义在 nginx/handlers/main.yml:
--- # handlers file for roles/nginx - name: restart nginx service: name=nginx state=restarted

负载均衡配置模板:mysite.j2

模板 mysite.j2 是负载均衡的核心,内容如下:

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

配置语义:

  • upstream webservers:定义一个名为webservers的后端服务器组,包含两台 Web 服务器的 IP 与端口(web01与web02,对应http_port: 8000);
  • listen 80:Nginx 监听 80 端口对外提供服务;
  • location / { proxy_pass http://webservers; }:将所有请求反向代理到webservers组,由 Nginx 按默认的轮询(round-robin)策略在两端点间分发流量,从而实现负载均衡。

注意 IP 地址适配:如果按教程执行后页面未按预期出现,很可能是环境中的服务器 IP 不同。此时只需编辑该模板,把server行更新为你环境中真实的 Web 服务器 IP 地址,再重新运行 playbook 即可。

运行更新后的 playbook

至此,我们在昨天的common角色(安装通用包)基础上,又增加了覆盖安装与配置全流程的nginx角色。现在执行:

ansible-playbook playbook4.yml

playbook 会依次对webservers(执行 common + apache2)和proxy(执行 common + nginx)两个主机组展开部署。执行过程输出如下:

部署完成后,Web 服务器与负载均衡器均已就绪,在浏览器中访问负载均衡器的 IP 地址:

http://192.168.169.134/

即可看到经由 Nginx 代理转发过来的 Web 页面内容:

如果页面不是预期效果,请回到 mysite.j2 核对后端 Web 服务器 IP 是否与实际环境一致。

用 ad-hoc 命令验证通用工具安装

虽然可以确信刚才的部署一切正常,但为了快速验证common角色是否真的在负载均衡器主机上安装了工具,我们还可以使用 Ansible 的 ad-hoc(临时命令)模式直接执行单条命令:

ansible loadbalancer -m command -a neofetch
  • loadbalancer:目标主机(对应 hosts 清单中的主机名);
  • -m command:使用 command 模块执行普通命令;
  • -a neofetch:实际执行的命令为neofetch。

执行后可以看到该主机上neofetch正常输出系统信息,从而确认common角色(neofetch、tree、figlet)确实已被正确安装:

小结

Day 67 完整走通了 Ansible 角色化改造的核心闭环:

  1. 角色复用:common角色被webservers与proxy两组主机同时引用,一次定义、处处生效;
  2. 任务拆分:nginx角色将安装与配置拆成两个任务文件,入口main.yml通过import_tasks静态引入,配合 handler 实现配置变更才重启的幂等行为;
  3. 负载均衡落地:借助 mysite.j2 中的upstream+proxy_pass,一台 Nginx 即成为两台 Apache Web 服务器的反向代理入口;
  4. 快速验证:ad-hoc 命令ansible loadbalancer -m command -a neofetch无需编写 playbook 即可确认远端状态。

所有文件均可在 ansible-scenario4 目录 中对照学习,从 playbook4.yml 到三个角色的tasks、handlers、templates,就是一套可复制、可运行的完整示例。下一节(Day 68)将继续深入 Ansible 的配置管理实践。

  • 文档/教程

【免费下载链接】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
点击查看免费下载
上一篇:Nativefier 终极启动指南:让你的网站应用随系统自动启动
下一篇:Gitness敏捷开发实践:将Scrum融入开发流程

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

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

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

立即咨询