编辑
2025-11-14
Ansible
00
请注意,本文编写于 99 天前,最后修改于 98 天前,其中某些信息可能已经过时。

目录

一、介绍
二、实操
步骤 1:创建项目目录结构
步骤 2:编写 Roles 各组件文件
defaults/main.yml(默认变量,可被外部覆盖)
templates/nginx.conf.j2(Nginx 配置模板,用变量定义端口)
templates/index.html.j2(自定义首页模板,显示主机名和标题)
tasks/main.yml(核心任务列表,按顺序执行)
handlers/main.yml(处理器:配置变化后重启 Nginx)
步骤 3:编写主 Playbook(deploy_nginx.yml)
步骤 4:执行 Playbook 部署服务

一、介绍

在 Ansible 中,Roles(角色) 是一种模块化、结构化的组织方式,用于将复杂的 Playbook 拆分为多个独立的 “功能单元”(如 “部署 Nginx”“配置数据库”“安装 ELK” 等)。它通过固定的目录结构,将任务、变量、模板、文件等按功能分类存放,让代码更清晰、更易复用和维护,尤其适合大型项目、团队协作或需要跨项目复用的场景。

为什么需要 Roles?

  • 当 Playbook 用于复杂场景(如部署一个完整的 ELK 集群)时,直接写在单个 YAML 文件中会导致:
  • 代码冗长(几百行甚至上千行),难以阅读和修改;
  • 功能耦合严重(比如 “安装 Elasticsearch” 和 “配置 Logstash” 的代码混在一起);
  • 无法复用(换一个项目部署 ELK 时,需要重新复制粘贴代码,容易出错)。
  • Roles 则通过标准化目录结构解决这些问题:将一个完整功能(如 “部署 Elasticsearch”)拆分为独立角色,每个角色内部包含自己的任务、变量、配置文件等,需要时直接 “调用” 即可。
  • Roles 的核心目录结构
  • 每个 Role 必须遵循固定的目录结构(Ansible 会自动识别这些目录的作用),典型结构如下:
js
roles/ └── elasticsearch/ # 角色名称(比如“部署 Elasticsearch”的角色) ├── tasks/ # 核心任务(必须有,存放要执行的任务列表) │ └── main.yml # 任务入口文件(Ansible 会自动加载) ├── handlers/ # 处理器(存放被 notify 触发的任务,如重启服务) │ └── main.yml ├── vars/ # 角色专属变量(优先级较高,通常不允许用户修改) │ └── main.yml ├── defaults/ # 角色默认变量(优先级较低,允许用户在外部覆盖) │ └── main.yml ├── templates/ # 模板文件(带变量的配置文件,如 elasticsearch.yml.j2) ├── files/ # 静态文件(无需渲染的文件,如证书、脚本) └── meta/ # 角色元信息(如作者、依赖关系) └── main.yml

二、实操

  • 目标场景
  • 通过 Roles 实现:
  • 在目标主机(elk1组)安装 Nginx;
  • 用模板生成 Nginx 配置文件(支持自定义端口);
  • 替换默认首页为带动态内容的 HTML(显示主机名和自定义标题);
  • 配置防火墙允许 Nginx 端口访问;
  • 确保 Nginx 服务启动并开机自启。

步骤 1:创建项目目录结构

js
# 创建项目根目录 mkdir -p ~/nginx_role_demo cd ~/nginx_role_demo # 创建Roles及子目录(nginx为角色名) mkdir -p roles/nginx/{tasks,handlers,templates,defaults,files} # 最终目录结构如下 tree . . ├── roles/ │ └── nginx/ # 角色名:部署Nginx │ ├── tasks/ # 任务列表(核心) │ ├── handlers/ # 处理器(重启服务等) │ ├── templates/ # 模板文件(带变量) │ ├── defaults/ # 默认变量(可被覆盖) │ └── files/ # 静态文件(可选) └── deploy_nginx.yml # 主Playbook:调用角色

步骤 2:编写 Roles 各组件文件

defaults/main.yml(默认变量,可被外部覆盖)

js
vi /root/nginx_role_demo/roles/nginx/defaults/main.yml

定义 Nginx 端口、首页标题等默认值:

yml
nginx_port: 80 # 默认端口 page_title: "Default Web Page" # 默认首页标题 firewall_service: "firewalld" # 防火墙服务名(CentOS默认firewalld)

templates/nginx.conf.j2(Nginx 配置模板,用变量定义端口)

模板文件以.j2为后缀,通过{{ 变量名 }}引用变量:

js
vi /root/nginx_role_demo/roles/nginx/templates/nginx.conf.j2
js
server { listen {{ nginx_port }}; # 监听端口(引用defaults中的变量) server_name _; root /usr/share/nginx/html; index index.html; # 日志配置 access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; }

templates/index.html.j2(自定义首页模板,显示主机名和标题)

用{{ ansible_hostname }}(Ansible 内置变量,获取主机名)和自定义标题:

js
vi /root/nginx_role_demo/roles/nginx/templates/index.html.j2
js
<!DOCTYPE html> <html> <head> <title>{{ page_title }}</title> </head> <body> <h1>Welcome to {{ page_title }}!</h1> <p>Hostname: {{ ansible_hostname }}</p> <!-- 显示当前主机名 --> <p>Deployed by Ansible Roles.</p> </body> </html>

tasks/main.yml(核心任务列表,按顺序执行)

js
vi /root/nginx_role_demo/roles/nginx/tasks/main.yml

定义安装、配置、启动等步骤:

yml
# 任务1:安装Nginx - name: 安装Nginx服务 yum: name: nginx state: present # 确保已安装 tags: install # 打标签,方便单独执行 # 任务2:复制Nginx配置文件(用templates目录的模板) - name: 配置Nginx监听端口 template: src: nginx.conf.j2 # 从templates目录加载模板 dest: /etc/nginx/conf.d/default.conf # 远程目标路径 mode: 0644 # 文件权限 notify: 重启Nginx # 配置文件变化时,触发handlers重启服务 tags: config # 任务3:替换默认首页(用templates目录的模板) - name: 部署自定义首页 template: src: index.html.j2 dest: /usr/share/nginx/html/index.html mode: 0644 tags: page # 任务4:配置防火墙允许Nginx端口访问 - name: 防火墙允许{{ nginx_port }}端口 firewalld: port: "{{ nginx_port }}/tcp" permanent: yes # 永久生效 immediate: yes # 立即生效(无需重启防火墙) state: enabled tags: firewall # 任务5:确保Nginx服务启动并开机自启 - name: 启动Nginx服务 service: name: nginx state: started enabled: yes # 开机自启 tags: service

handlers/main.yml(处理器:配置变化后重启 Nginx)

仅在被notify触发时执行:

js
vi /root/nginx_role_demo/roles/nginx/handlers/main.yml
js
# roles/nginx/handlers/main.yml - name: 重启Nginx service: name: nginx state: restarted

步骤 3:编写主 Playbook(deploy_nginx.yml)

在项目根目录创建 Playbook,指定目标主机并调用nginx角色,可覆盖默认变量:

js
vi /root/nginx_role_demo/deploy_nginx.yml
js
# ~/nginx_role_demo/deploy_nginx.yml - name: 使用Roles部署Nginx服务 hosts: elk1 # 目标主机组(对应hosts文件中的elk1) remote_user: root # 远程执行用户 roles: - role: nginx # 调用roles/nginx角色 vars: # 覆盖默认变量:端口改为8080,首页标题改为"ELK Web Server" nginx_port: 8080 page_title: "ELK Web Server"

步骤 4:执行 Playbook 部署服务

在控制机项目目录下执行命令:

js
cd ~/nginx_role_demo ansible-playbook deploy_nginx.yml

只要看到都是绿色就没问题了, image.png

image.png

  • 执行过程说明:
  • Ansible 会先解析deploy_nginx.yml,找到roles: nginx,然后加载roles/nginx/tasks/main.yml中的任务。
  • 按顺序执行 “安装 Nginx→配置端口→部署首页→配置防火墙→启动服务”。
  • 若 Nginx 配置文件有变化(如端口从默认 80 改为 8080),会触发handlers中的 “重启 Nginx”。

验证

js
curl 192.168.183.112:8080

本文作者:松轩(^U^)

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

Document