当前位置: 首页 > news >正文

Ansible 大项目管理实践笔记:并行任务、角色管理与负载均衡架构部署

管理大项目

Ansible 在大项目管理中的“并行配置与异步任务管理”方法

配置 async

async 异步任务

  • 测试 async + poll 参数对任务调度的影响

示例1: 任务执行失败,在规定时间内容任务没有执行完成。

async: 5 + poll: 2,任务超时 → 演示 异步任务超时失败的情况

[yuxb@controller web 09:53:08]$ vim playbook.yml [yuxb@controller web 09:54:09]$ cat playbook.yml ---- name: connectionhosts: node1tasks:- name: conneciton shell: sleep 10async: 5poll: 2​# 执行[yuxb@controller web 09:51:33]$ ansible-playbook playbook.yml ​PLAY [connection] ***********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]​TASK [conneciton] ***********************************************************************************fatal: [node1]: FAILED! => {"changed": false, "msg": "async task did not complete within the requested time - 5s"}​PLAY RECAP ******************************************************************************************node1                      : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   ​

示例2: 放入后台下载,立刻执行下一个任务。

async: 100 + poll: 0,任务后台运行 → 演示 放到后台执行,立即执行下一个任务

[yuxb@controller web 09:54:12]$ vim playbook.yml [yuxb@controller web 09:55:22]$ cat playbook.yml ---- name: connectionhosts: node1tasks:- name: downloadget_url: url: http://192.168.48.100/ISOS/openEuler-24.03-LTS-x86_64-dvd.isodest: /home/yuxbasync: 100poll: 0​# 执行[yuxb@controller web 09:54:43]$ ansible-playbook playbook.yml ​PLAY [connection] ***********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]​TASK [download] *************************************************************************************changed: [node1]​PLAY RECAP ******************************************************************************************node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ​​

示例3: ansible 默认行为,等该任务执行完,再执行下一个任务。

async: 0 + poll: 2,相当于默认 → 演示 同步等待,按顺序执行任务

[yuxb@controller web 09:55:24]$ vim playbook.yml [yuxb@controller web 09:56:13]$ cat playbook.yml ---- name: connectionhosts: node1tasks:- name: conneciton shell: sleep 10async: 0poll: 2​# 执行[yuxb@controller web 09:55:37]$ ansible-playbook playbook.yml ​PLAY [connection] ***********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]​TASK [conneciton] ***********************************************************************************changed: [node1]​PLAY RECAP ******************************************************************************************node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ​

wait_for 模块

  • 测试 如何让 Playbook 在后台任务完成前,智能等待资源就绪

示例1: 测试文件是否存在

等待文件 /tmp/hello 被创建 → 演示 检测文件存在性

[yuxb@controller web 09:56:16]$ vim playbook.yml [yuxb@controller web 10:11:46]$ cat playbook.yml ---- name: test wait forhosts: node1tasks:- shell: sleep 10 && touch /tmp/hello# async时间要大于sleep的时间async: 20poll: 0register: out​- name: wait for create /tmp/hellowait_for:path: /tmp/hellostate: presentdelay: 5timeout: 30sleep: 2​# 测试[yuxb@controller web 09:56:39]$ ansible-playbook playbook.yml ​PLAY [test wait for] ********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]​TASK [shell] ****************************************************************************************changed: [node1]​TASK [wait for create /tmp/hello] *******************************************************************ok: [node1]​PLAY RECAP ******************************************************************************************node1                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ​

示例2: 测试主机端口是否打开

等待主机端口(22)恢复 → 演示 等待主机重启并恢复服务

[yuxb@controller web 10:11:49]$ vim playbook.yml [yuxb@controller web 10:12:49]$ cat playbook.yml ---- name: test wait_forhosts: node1,node2tasks:- name: reboot node1shell: shutdown -r now "Ansible updates triggered"async: 1poll: 0when: inventory_hostname == "node1"- name: wait for node1 come backwait_for:host: node1port: 22state: started# delay,设置检测前延迟时间。delay: 10# sleep,设置检测时间间隔。sleep: 2# timeout,设置检测超时时间。timeout: 300when: inventory_hostname == "node2"​# 测试# node1会重启,连接会断开[yuxb@controller web 10:12:17]$ ansible-playbook playbook.yml ​PLAY [test wait_for] ********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]ok: [node2]​TASK [reboot node1] *********************************************************************************skipping: [node2]changed: [node1]​TASK [wait for node1 come back] *********************************************************************skipping: [node1]ok: [node2]​PLAY RECAP ******************************************************************************************node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   node2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   ​

async_status 模块

  • 使用 async_status 跟踪任务的 ansible_job_id,直到 finished

  • 演示 如何主动检查后台任务的执行状态,而不是被动等待。

  • 测试 如何追踪和确认异步任务的完成情况

使用 async_status 模块检查之前的任务是否运行完成。

[yuxb@controller web 10:12:51]$ vim playbook.yml [yuxb@controller web 10:14:35]$ cat playbook.yml ---- name: test async_statushosts: node1tasks:- shell: sleep 10 async: 20poll: 0register: out- name: wait forasync_status:# 通过任务的 ansible_job_id 属性跟踪任务jid: "{{ out.ansible_job_id }}"register: job_result# 根据当前任务执行结果的finished值,判断跟踪任务是否执行完成until: job_result.finished#retries,设置重试次数,默认值为3。retries: 30# delay,设置检测时间间隔,默认5秒检测一次。delay: 2​# 测试[yuxb@controller web 10:14:53]$ ansible-playbook playbook.yml ​PLAY [test async_status] ****************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node1]​TASK [shell] ****************************************************************************************changed: [node1]​TASK [wait for] *************************************************************************************FAILED - RETRYING: wait for (30 retries left).FAILED - RETRYING: wait for (29 retries left).FAILED - RETRYING: wait for (28 retries left).FAILED - RETRYING: wait for (27 retries left).FAILED - RETRYING: wait for (26 retries left).changed: [node1]​PLAY RECAP ******************************************************************************************node1                      : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ​

Including 和 importing 文件

Ansible 的 Playbook 拆分与调用

playbook 级别(在 Playbook 层级做 include/import)
[yuxb@controller web 10:38:50]$ vim playbook.yml [yuxb@controller web 10:39:34]$ cat playbook.yml - name: prepare the web serverimport_playbook: pre_web.yml​- name: prepare the vsftpd serverimport_playbook: pre_vsftpd.yml​- name: prepare the databse serverimport_playbook: pre_db.yml​

其余文件

[yuxb@controller web 10:40:06]$ cat > pre_web.yml << EOF> - name: Play web>   hosts: node1>   tasks:>     - name: install httpd>       yum:>         name: httpd>         state: present> EOF[yuxb@controller web 10:40:10]$ cat > pre_vsftpd.yml << EOF> - name: Play vsftpd>   hosts: node1>   tasks:>     - name: install vsftpd>       yum:>         name: vsftpd>         state: present> EOF[yuxb@controller web 10:40:17]$ cat > pre_db.yml << EOF> - name: Play db>   hosts: node1>   tasks:>     - name: install mariadb-server>       yum:>         name: mariadb-server>         state: present> EOF​
# 执行[yuxb@controller web 10:15:07]$ ansible-playbook playbook.yml

Ansible 角色管理

Ansible 角色

什么是角色(Role)

  • 角色(Role) 是 Ansible 提供的一种 分层组织 Playbook 的方式

  • 它可以把任务(tasks)、变量(vars)、文件(files)、模板(templates)等内容,按功能模块化、目录化管理。

  • 适合 大项目多人协作,让 Playbook 更加清晰、可复用。

角色目录结构

一个标准角色目录通常长这样:

roles/└── webserver/         # 角色名称├── tasks/         # 主要任务(main.yml 必须有)│    └── main.yml├── files/         # 静态文件├── templates/     # Jinja2 模板├── vars/          # 变量(优先级较高)│    └── main.yml├── defaults/      # 默认变量(优先级最低)│    └── main.yml├── handlers/      # handlers(如服务重启)│    └── main.yml└── meta/          # 角色依赖信息└── main.yml

Ansible 角色结构

[yuxb@controller web 11:28:30]$ ansible-galaxy init yubb- Role yubb was created successfully[yuxb@controller web 11:29:28]$ tree yubbyubb├── defaults│   └── main.yml├── files├── handlers│   └── main.yml├── meta│   └── main.yml├── README.md├── tasks│   └── main.yml├── templates├── tests│   ├── inventory│   └── test.yml└── vars└── main.yml​8 directories, 8 files​

Ansible 角色目录位置

  • 本地项目目录:./roles/(最常用)

  • 全局目录:/etc/ansible/roles//usr/share/ansible/roles/

  • 自定义目录:通过 ansible.cfg 设置 roles_path

优先级从上到下依次降低。

可以在ansible.cfg配置文件[defaults]块中通过变量roles_path定义role位置:

[defaults]roles_path  = ./roles......

多个路径使用冒号分隔:

roles_path = /etc/ansible/roles:/home/student/web/roles

:w

用 Ansible 创建并编写一个角色(Role)来自动化部署 Apache(httpd)Web 服务。

创建角色
[yuxb@controller web 11:29:33]$ mkdir roles[yuxb@controller web 11:30:33]$ ansible-galaxy init apache- Role apache was created successfully[yuxb@controller web 11:30:39]$ mv apache/ roles# 命令一样[yuxb@controller web 11:30:45]$ ansible-galaxy init apache --init-path=./roles# 生成了 roles/apache/ 目录结构(tasks、handlers、templates、defaults 等)。​​# 查看角色列表[yuxb@controller web 11:31:34]$ ansible-galaxy list# /usr/share/ansible/roles# /etc/ansible/roles[WARNING]: - the configured path /home/yuxb/.ansible/roles does not exist.​[yuxb@controller web 11:31:54]$ cd roles/apache/
# 核心任务逻辑:安装、启动、配置、创建目录和首页[yuxb@controller apache 11:31:55]$ vim tasks/main.yml[yuxb@controller apache 11:33:11]$ cat tasks/main.yml ---# tasks file for apache​# 1. 安装 Apache 软件包(默认为 httpd)- name: install webyum:name: "{{ web_package }}"   # 使用变量,便于修改state: latest               # 确保安装最新版本​# 2. 启动并设置 Apache 开机自启- name: "start {{ web_service }}"service:name: "{{ web_service }}"   # 服务名(默认为 httpd)state: started              # 确保服务已启动enabled: yes                # 开机自动启动​# 3. 渲染 motd 模板,更新 /etc/motd 欢迎信息- name: prepare motdtemplate:src: motd.j2                # 模板文件路径(位于 templates/)dest: /etc/motd             # 渲染后生成的目标文件​# 4. 渲染 Apache 虚拟主机配置- name: prepare yuxb sitetemplate:src: yuxb.conf.j2           # 虚拟主机配置模板dest: /etc/httpd/conf.d/yuxb.confnotify:                       # 如果文件有变化,触发 handlers- restart_web​# 5. 创建站点目录(以主机名区分,避免冲突)- name: prepare DocumentRoot file:path: "/var/www/html/{{ ansible_hostname }}"  # 每台主机单独目录state: directory                              # 确保存在目录​# 6. 渲染首页 index.html- name: prepare index.htmltemplate:src: index.html.j2          # 首页模板dest: "/var/www/html/{{ ansible_hostname }}/index.html"​
# 定义默认变量,便于在 tasks 中引用[yuxb@controller apache 11:33:15]$ vim defaults/main.yml[yuxb@controller apache 11:34:04]$ cat defaults/main.yml ---# defaults file for apache# 定义默认软件包和服务名称,方便在 tasks 中调用web_package: httpd # Apache 软件包web_service: httpd # Apache 服务名​​[yuxb@controller apache 11:34:18]$ vim templates/motd.j2[yuxb@controller apache 11:34:33]$ cat templates/motd.j2hello guys!Welcome to {{ ansible_fqdn }}!​​[yuxb@controller apache 11:36:48]$ cat templates/yuxb.conf.j2 # {{ ansible_managed }}<VirtualHost *:80>ServerAdmin yuxb@{{ ansible_fqdn }}ServerName {{ ansible_fqdn }}ErrorLog logs/{{ ansible_hostname }}-error.logCustomLog logs/{{ ansible_hostname }}-common.log commonDocumentRoot /var/www/html/{{ ansible_hostname }}/​<Directory /var/www/html/{{ ansible_hostname }}/>Options +Indexes +FollowSymlinks +IncludesOrder allow,denyAllow from all</Directory></VirtualHost>​# 定义“触发器”,当配置文件变化时执行[yuxb@controller apache 11:36:56]$ vim handlers/main.yml[yuxb@controller apache 11:37:42]$ cat handlers/main.yml ---# handlers file for apache- name: restart_webservice:name: "{{ web_service }}" # 使用变量,默认为 httpdstate: restarted          # 重启 Apache 服务​# 模板文件:系统欢迎信息(motd)[yuxb@controller apache 11:37:46]$ vim templates/index.html.j2[yuxb@controller apache 11:38:31]$ cat templates/index.html.j2 Welcome to {{ ansible_fqdn }} !​
调用角色
[yuxb@controller web 11:46:25]$ cat playbook.yml ---- name: deploy apachehosts: node2roles:- apache​[yuxb@controller web 11:52:31]$ ansible-playbook playbook.yml ​PLAY [deploy apache] ********************************************************************************​TASK [Gathering Facts] ******************************************************************************ok: [node2]​TASK [apache : install web] *************************************************************************ok: [node2]​TASK [apache : start httpd] *************************************************************************ok: [node2]​TASK [apache : prepare motd] ************************************************************************changed: [node2]​TASK [apache : prepare yuxb site] *******************************************************************changed: [node2]​TASK [apache : prepare DocumentRoot] ****************************************************************changed: [node2]​TASK [apache : prepare index.html] ******************************************************************changed: [node2]​RUNNING HANDLER [apache : restart_web] **************************************************************changed: [node2]​PLAY RECAP ******************************************************************************************node2                      : ok=8    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ​

验证

[yuxb@controller web 11:52:45]$ curl http://node2/Welcome to node2.yuxb.cloud ![yuxb@controller web 11:53:37]$ ssh node2Last login: Tue Aug 19 11:52:43 2025 from 10.1.8.10hello guys!Welcome to node2.yuxb.cloud!​

使用系统角色

系统角色安装和说明

[yuxb@controller web 13:36:00]$ sudo yum install -y rhel-system-roles​

角色使用案例-timesync

使用 Ansible 的系统角色(system roles)来管理 NTP 时间同步服务

[yuxb@controller web 13:45:52]$ vim ansible.cfg [yuxb@controller web 13:46:53]$ cat ansible.cfg [defaults]inventory = ./inventoryremote_user = yuxbvault_password_file = ./password-for-vaultroles_path  = ./roles:/usr/share/ansible/roles/ #设置了角色搜索路径,保证 Ansible 可以找到系统角色和本地自定义角色。#ask_pass = True#module_name = command#private_key_file = /opt/id_rsa#host_key_checking = False​[privilege_escalation]become=Truebecome_method=sudobecome_user=rootbecome_ask_pass=False​​# playbook内容取自如下[yuxb@controller web 13:47:23]$ vim /usr/share/ansible/roles/rhel-system-roles.timesync/README.md ​​# 调用了 rhel-system-roles.timesync 角色,自动配置时间同步服务。# 通过变量 timesync_ntp_servers 指定 NTP 服务器(这里是 ntp.aliyun.com)。# 角色内部会根据变量去修改系统配置(如 /etc/chrony.conf 或 /etc/ntp.conf),启动时间同步服务,并确保服务开机自启。[yuxb@controller web 13:46:56]$ vim playbook.yml [yuxb@controller web 13:51:24]$ cat playbook.yml - name: Manage timesync with 1 servershosts: allvars:timesync_ntp_servers:- hostname: ntp.aliyun.comiburst: trueroles:- rhel-system-roles.timesync​# 执行# Ansible 会在所有目标主机上执行系统角色 tasks,实现 自动化时间同步配置。[yuxb@controller web 13:54:08]$ ansible-playbook playbook.yml ​

Ansible 自动化部署“负载均衡 + Web 服务”架构

  1. 准备工具

    • 下载两个“现成脚本包”:

      • apache:能一键帮你装好 Apache Web 服务。

      • haproxy:能一键帮你装好 HAProxy 负载均衡。

  2. 写了“任务清单”(Playbook)

    • controller 机器去装 HAProxy,配置好后端的 4 台 Web 节点。

    • node1-4 机器去装 Apache,每台都能跑网站。

  3. 写了“通讯录”(Inventory)

    • controller 这一台 = 负载均衡器。

    • node1~node4 四台 = 网站服务器。

  4. 一键执行任务

    • 运行 Playbook,Ansible 就自动去所有机器执行任务,不用你一台一台手动配置。

  5. 验证效果

    • 访问 http://controller,请求被 HAProxy 自动分发到不同的 Web 节点。

    • 所以可以看到:一会儿是 node2 的欢迎语,一会儿是 node3、node4、node1 的。

    • 这就是 负载均衡:把访问请求平均分到多台服务器上

[yuxb@controller web 14:10:27]$ ansible-galaxy role search --author geerlingguy apache​Found 2 roles matching your search:​Name                       Description----                       -----------geerlingguy.apache         Apache 2.x for Linux.geerlingguy.apache-php-fpm Apache 2.4+ PHP-FPM support for Linux.[yuxb@controller web 14:10:52]$ ansible-galaxy role install geerlingguy.apache- downloading role 'apache', owned by geerlingguy- downloading role from https://github.com/geerlingguy/ansible-role-apache/archive/4.0.0.tar.gz- extracting geerlingguy.apache to /home/yuxb/web/roles/geerlingguy.apache- geerlingguy.apache (4.0.0) was installed successfully[yuxb@controller web 14:12:02]$ ls roles/apache  geerlingguy.apache​[yuxb@controller web 14:17:18]$ ansible-galaxy install http://192.168.42.100/%E8%BD%AF%E4%BB%B6/ansible-role-haproxy-1.3.1.tar.gz- downloading role from http://192.168.42.100/%E8%BD%AF%E4%BB%B6/ansible-role-haproxy-1.3.1.tar.gz- extracting ansible-role-haproxy-1.3.1 to /home/yuxb/web/roles/ansible-role-haproxy-1.3.1- ansible-role-haproxy-1.3.1 was installed successfully​[yuxb@controller web 14:20:18]$ mv roles/ansible-role-haproxy-1.3.1/ roles/haproxy[yuxb@controller web 14:21:19]$ ls roles/apache  geerlingguy.apache  haproxy​[yuxb@controller web 14:24:02]$ vim playbook.yml [yuxb@controller web 14:28:59]$ cat playbook.yml - name: deploy LBhosts: LBsvars:haproxy_backend_servers:- name: node1address: 10.1.8.11:80- name: node2address: 10.1.8.12:80- name: node3address: 10.1.8.13:80- name: node4address: 10.1.8.14:80roles:- haproxy- name: deploy apachehosts: WEBsroles:- apache ​[yuxb@controller web 14:29:02]$ vim inventory [yuxb@controller web 14:30:26]$ cat inventory [LBs]controller[WEBs]s                  674321`234CXanode[1:4]​​[yuxb@controller web 14:32:02]$ ansible all -a 'systemctl disable nginx --now'​​[yuxb@controller web 14:30:49]$ ansible-playbook playbook.yml ​[yuxb@controller web 14:33:09]$ curl http://controllerWelcome to node2.yuxb.cloud ![yuxb@controller web 14:33:25]$ curl http://controllerWelcome to node3.yuxb.cloud ![yuxb@controller web 14:33:29]$ curl http://controllerWelcome to node4.yuxb.cloud ![yuxb@controller web 14:33:29]$ curl http://controllerWelcome to node1.yuxb.cloud !​
http://www.lryc.cn/news/625706.html

相关文章:

  • 基于Python的宠物服务管理系统 Python+Django+Vue.js
  • 当机器猫遇上具身智能:一款能读懂宠物心思的AI守护者
  • XML 序列化与操作详解笔记
  • Gemini CLI 自定义主题配置
  • 块存储 对象存储 文件存储的区别与联系
  • es9.0.1语义检索简单示例
  • RNN(循环神经网络)和Transformer是处理自然语言处理(NLP)任务区别
  • 《用Proxy解构前端壁垒:跨框架状态共享库的从零到优之路》
  • 高校数字化转型实战:破解数据孤岛、构建智能指标体系与AI落地路径
  • C++代码解释:实现一个 mystring 类,用于表示字符串,实现构造函数,默认构造长度为 10 的空间,提供打印字符串,获取空间大小,修改内容的成员函数
  • InnoDB为什么使用B+树实现索引?
  • Word——正确调整文字与编号的距离
  • 4.Kotlin 集合 Map 所有方法
  • Linux系统安全补丁管理与自动化部署研究与实现(LW+源码+讲解+部署)
  • Ubuntu 20 各种网卡配置IP的方法
  • pnpm 和 npm 差异
  • MySQL 三大日志:redo log、undo log、binlog 详解
  • Git+Jenkins实战(一)
  • 软件测试核心概念拆解:需求、开发模型与测试模型全解析
  • JVM调优实战指南:从原理到落地的全面优化方案
  • 安装DDNS-go
  • FlexSim-线平衡优化仿真
  • Qt元对象
  • Qt消息队列
  • es7.x es的高亮与solr高亮查询的对比对比说明
  • 使用Tomcat Clustering和Redis Session Manager实现Session共享
  • Auto-CoT:大型语言模型的自动化思维链提示技术
  • 基于“R语言+遥感“水环境综合评价方法技术应用——水线提取、水深提取、水温提、水质提取、水环境遥感等
  • STM32-FreeRTOS快速入门指南(下)
  • LLM 中 token 简介与 bert 实操解读