
文档/教程【免费下载链接】90DaysOfDevOpsThis 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 2022 年路线中 Ansible 配置管理专题的实战进度基于 2022/Days/day66.md 展开。在上一节Day 65我们已经用 Vagrantfile 拉起 4 台虚拟机并以其中一台 Linux 机器作为 Ansible 控制节点通过 playbook 把 web01、web02 配置成了 Web 服务器。本文要解决的是当 playbook 越写越大时如何保持整洁先把 tasks 与 handlers 拆进独立子目录再用ansible-galaxy把 Apache2 相关逻辑封装成标准 Role最终让 playbook 从几百行可读性灾难变成一行roles: - apache2的声明式引用。读完本篇你将掌握 Ansible 大规模编排的三件核心工具任务文件拆分、handlers 处理器、以及 Ansible Galaxy 的 Role 标准化结构。回顾从裸机到两台 Web 服务器在进入整洁化之前先明确我们当前的基线状态。上节我们完成了两个实验场景全部代码都存放在 2022/Days/Configmgmt 目录下ansible-scenario1最朴素的 playbook1.yml所有任务和 handlers 直接内联在 playbook 里ansible-scenario2开始引入模板文件配套 templates/ports.conf.j2 与 templates/index.html.j2基础设施层面由 Vagrantfile 负责拉起 4 台虚拟机两台 Web、一台数据库、一台负载均衡/代理的雏形其中一台 Linux 机器同时充当 Ansible 控制节点。两个场景结束时web01 和 web02 已经可以通过各自独立的 playbook 变成可用的 Web 服务器。下图展示了我们当前 playbook 的整体形态来自原文 Images/Day66_config1.png保持整洁把 Tasks 与 Handlers 拆进独立目录当任务数量继续增长时把所有内容塞进单个 playbook 文件会让可读性和可复用性同时崩盘。我们的第一步是把任务和处理器分别抽取到独立文件中为后续规模扩张做准备。1. 抽出任务文件把原先内联在 playbook 中的 4 个 Apache2 任务整体剪切到独立文件 tasks/apache2_install.yml- name: ensure apache is at the latest version apt: nameapache2 statelatest - name: write the apache2 ports.conf config file template: srctemplates/ports.conf.j2 dest/etc/apache2/ports.conf notify: restart apache - name: write a basic index.html file template: src: templates/index.html.j2 dest: /var/www/html/index.html notify: - restart apache - name: ensure apache is running service: name: apache2 state: started这四个任务构成了 Apache2 部署的最小闭环安装apt模块、写配置template渲染ports.conf、写页面渲染index.html、启动服务service模块。其中两个template任务都通过notify触发了名为restart apache的处理器——注意notify只有在模板内容实际发生变化时才会触发 handler这保证了配置没变就不重启服务的高效幂等行为。2. 抽出处理器文件处理器同样被拆到独立文件 handlers/main.yml- name: restart apache service: name: apache2 state: restartedHandler 是 Ansible 中被动的动作它本身不会执行只有其他任务通过notify点名时才运行且默认在 play 收尾阶段只执行一次。把 handler 单独归档便于多个任务、多个 role 复用同一个重启逻辑。3. 改造 playbook用 import_tasks 组装任务与处理器被拆出去之后playbook 本体瘦身为一个装配清单。改造后的 playbook2.yml 如下- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 66! tasks: - import_tasks: tasks/apache2_install.yml handlers: - import_tasks: handlers/main.yml这里有两个值得注意的细节import_tasks是静态导入在 playbook 解析阶段就把目标文件的内容合并进来变量可被提前解析、报错更早暴露变量http_port: 8000、https_port: 4443、html_welcome_msg依然声明在 play 级vars中它们会在模板渲染时注入。以 ports.conf.j2 为例模板内通过Listen {{ http_port }}与Listen {{ https_port }}消费变量而 index.html.j2 则用h1{{ html_welcome_msg }}/h1把欢迎语写进页面。4. 验证一个小改动引发的连锁反应如果你从仓库复制了场景 2 的文件会注意到index.html任务和之前的版本相比有了一处简单变化见原文 Images/Day66_config2.png。在控制节点上执行验证curl web01:8000返回结果见原文 Images/Day66_config3.png印证了html_welcome_msg变量已经成功渲染进网页——这就是模板 变量组合拳的直观效果改一处变量声明所有主机的页面内容随之更新无需手动编辑文件。至此我们完成了第一步整洁化任务文件、处理器文件、模板文件各归其位playbook 只负责声明 hosts、变量和装配顺序。但这种方式仍然要求我们在 playbook 里手动维护import_tasks路径对于更大规模的仓库依然不够优雅于是我们进入 Ansible 给出的标准化答案——Roles。Roles 与 Ansible Galaxy真正的规模化方案当前我们只配置了 4 台 VM 中的 2 台 Web 服务器接下来还有数据库服务器、负载均衡/代理节点待办。要让整个仓库保持可维护Ansible 提供了官方推荐的抽象单元——Role。而ansible-galaxy命令就是用来在共享仓库中创建和管理 Role 的标准工具。1. 用 ansible-galaxy 初始化 Role在控制节点上执行ansible-galaxy init roles/apache2该命令会一次性生成标准 Role 目录骨架见原文 Images/Day66_config5.png这是 Ansible 社区公认的九宫格结构仓库中 roles/apache2 目录完整保留了这一布局roles/apache2/ ├── defaults/ # 最低优先级变量通常放可被覆盖的默认值 ├── handlers/ # 该 Role 专属的处理器 ├── meta/ # Role 的元信息与依赖声明 ├── tasks/ # 核心任务文件main.yml 为入口 ├── templates/ # Jinja2 模板 ├── tests/ # 本地验证用的 inventory 与 test.yml ├── vars/ # 较高优先级变量 └── README.md # Role 使用说明各目录职责从仓库实际文件即可印证defaults/main.yml目前是空壳等待填充默认值tasks/存放真正的执行逻辑templates/存放ports.conf.j2与index.html.j2handlers/main.yml定义重启动作meta/main.yml记录作者与依赖tests/下提供了 inventory 与 test.yml 供独立测试。2. 迁移现有内容到 Role 结构接下来把场景 2 中已拆好的任务与模板搬进新结构的对应目录原文 Images/Day66_config6.pngtasks/apache2_install.yml与两个模板文件分别移入 Role 的tasks/、templates/。复制粘贴之外还差关键一步修改 tasks/main.yml让 Role 的入口指向真正的执行文件--- # tasks file for roles/apache2 - import_tasks: apache2_install.ymltasks/main.yml是 Ansible 执行 Role 时默认读取的入口文件这一行import_tasks把它与apache2_install.yml串联起来任务逻辑本体无需任何改动。3. playbook 改为引用 Roleplaybook 也从手动装配进化为声明式引用。新建 playbook3.yml- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 66! roles: - apache2对比场景 2tasks:与handlers:两节被一个roles:列表取代。执行方式不变ansible-playbook playbook3.yml运行输出原文 Images/Day66_config8.png会显示 playbook 成功执行但同时在任务导入处出现一条deprecation 警告。这正是我们的下一个修复目标。4. 修复 deprecation 警告include 换成 import_tasks虽然 playbook 能跑通但 Ansible 在输出中明确标记了被废弃的用法原文 Images/Day66_config9.png。仓库中 tasks/main.yml 的实际内容已经使用了推荐的import_tasks写法--- # tasks file for roles/apache2 - import_tasks: apache2_install.yml为什么推荐import_tasks而不是include两者语义不同include是动态包含在 play 运行到该行时才解析文件、变量可以在运行时才生效也因此不参与提前的语法检查与标签处理import_tasks是静态导入在解析阶段就完成合并错误暴露更早、变量解析更可预期、--tags/--list-tasks等静态能力兼容性更好。对 Role 内部这种入口固定、逻辑明确的场景静态导入是更稳的默认选择。至此Apache2 的一切细节安装、模板、端口、处理器都被封装进了roles/apache2playbook 与 Web 服务器的具体实现彻底解耦。完整的场景 3 代码可在 ansible-scenario3 目录查看。为后续节点创建更多 Roles场景 3 只完成了 Apache2 的封装而我们的实验环境还有数据库节点和负载均衡节点待配置。为此继续使用ansible-galaxy初始化两个新 Role原文 Images/Day66_config10.pngansible-galaxy init roles/common ansible-galaxy init roles/nginxcommon面向全部服务器的基础角色适合放通用工具安装、时区、安全加固等所有节点都需要的公共逻辑nginx面向负载均衡/反向代理节点对应我们四台虚拟机中尚未动工的 proxy 角色。这两个 Role 在仓库中已经拥有完整骨架common角色在后续场景中演化出 tasks/install_tools.ymlnginx角色则演化出 tasks/install_packages.yml 与 tasks/configure_nginx.yml 等执行文件以及 templates/mysite.j2 站点模板——这为下一篇Day 67继续配置数据库与负载均衡节点预留了清晰的落点。仓库中 ansible-scenario4 及之后的场景ansible-scenario5、ansible-scenario6、ansible-scenario7正是在这套 Role 体系上逐步叠加mysql角色、group_vars与更多变量分层的最佳实践。小结Day 66 完成了从单文件 playbook到Role 化仓库的关键一跃三步走路径清晰可复现拆文件把 tasks 与 handlers 从 playbook 中剥离为独立文件用import_tasks静态装配封装 Roleansible-galaxy init roles/apache2生成标准九宫格结构将任务、模板、处理器各归其位声明式引用playbook 从tasks:/handlers:块简化为roles: - apache2同时用import_tasks消除include带来的 deprecation 警告。对规模化的价值在于Web 服务器的实现细节被彻底封装新增一个 Web 节点只需要把它加进webservers主机组新增一类服务器数据库、负载均衡只需要ansible-galaxy init一个新 Role 并在 playbook 中声明。下一篇将继续利用这套 Role 体系去配置我们已经部署但尚未动工的其他节点。参考资料本文对应原文2022/Days/day66.md场景 2 完整代码ansible-scenario2tasks/handlers 拆分场景 3 完整代码ansible-scenario3Apache2 Role 封装后续演进代码ansible-scenario4common/nginx Role、ansible-scenario7mysql Role group_vars基础设施Vagrantfile原文同时推荐了 Ansible 入门系列视频What is Ansible、Ansible 101 系列等本文配套实操可继续前往 Day 67 学习赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis 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点击查看免费下载相关推荐一条命令拆开 PyInstaller 打包的黑匣子pyinstxtractor 逆向分析工具实战一条命令拆开 PyInstaller 打包的黑匣子pyinstxtractor 逆向分析工具实战 pyinstxtractor 是一个能把 PyInstall逆向工程开发工具90DaysOfDevOps 第 65 天用 Ansible Playbook 声明式配置你的服务器群90DaysOfDevOps 第 65 天用 Ansible Playbook 声明式配置你的服务器群 导读 本文是 90DaysOfDevOps 学习路线图文档/教程Aptos Move Lean 验证器中的无转换整数规范Conversion-free Integer Specifications设计解析Aptos Move Lean 验证器中的无转换整数规范Conversion free Integer Specifications设计解析 导读 本文解读文档/教程上一篇Textual 应用焦点事件 AppFocus原理、监听与焦点恢复机制详解下一篇B站评论区成分识别工具终极指南从信息过载到精准认知的智能跃迁创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考