Ansible 角色管理指南

发布于:2025-08-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

Ansible 角色管理指南

实验环境设置

以下命令用于准备实验环境,创建一个工作目录并配置基本的Ansible设置:

# 创建web工作目录并进入
[azurewhisky@controller ~]$ mkdir web && cd web

# 创建Ansible配置文件
[azurewhisky@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = azurewhisky  # 设置远程登录用户名
inventory = ./inventory    # 指定清单文件位置

[privilege_escalation]
become = True              # 启用权限提升
become_user = root         # 提升到root用户
become_method = sudo       # 使用sudo方法
become_ask_pass = False    # 不询问密码
EOF

# 创建主机清单文件
[azurewhisky@controller web]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF

Ansible 角色详解

什么是Ansible角色?

在实际生产环境中,Playbook往往会变得很长且复杂,包含许多文件、任务和处理程序。随着编写的Playbook越来越多,我们会发现有很多机会可以复用之前编写的代码。

Ansible角色提供了一种标准化方式来打包和复用自动化代码。它将任务、变量、文件、模板等资源组织在一个标准化的目录结构中,只需将角色从一个项目复制到另一个项目,然后在Playbook中调用即可。

Ansible角色结构

通过以下命令可以初始化一个标准的Ansible角色:

[azurewhisky@controller web]$ ansible-galaxy init azurewhisky
- azurewhisky was created successfully

# 查看角色目录结构
[azurewhisky@controller web]$ tree azurewhisky
azurewhisky
├── 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

各目录用途说明:

  • defaults:包含角色变量的默认值(低优先级,易被覆盖)
  • files:存放角色任务引用的静态文件
  • handlers:包含角色的处理程序定义
  • meta:包含角色元信息(作者、许可证、依赖等)
  • tasks:包含角色的主要任务定义
  • templates:存放Jinja2模板文件
  • tests:包含测试用的清单和Playbook
  • vars:定义角色变量(高优先级,用于内部功能)
  • README.md:角色使用说明文档

角色存放位置

Ansible默认在以下位置查找角色:

  • ~/.ansible/roles
  • /usr/share/ansible/roles
  • /etc/ansible/roles

优先级从上到下递减。可以通过配置文件自定义角色路径:

# 在ansible.cfg中设置角色路径
[defaults]
roles_path = ./roles  # 相对路径示例

# 多个路径用冒号分隔
roles_path = /etc/ansible/roles:/home/azurewhisky/web/roles

创建自定义角色

下面创建一个Apache Web服务器角色的完整示例:

# 创建角色目录并初始化Apache角色
[azurewhisky@controller web]$ mkdir roles
[azurewhisky@controller web]$ ansible-galaxy init apache --init-path=./roles
配置任务文件
# roles/apache/tasks/main.yml
---
# Apache角色任务文件
- name: 安装Web服务器
  yum:
    name: "{{ web_package }}"  # 使用变量指定软件包名
    state: latest

- name: "启动{{ web_service }}服务"
  service:
    name: "{{ web_service }}"  # 使用变量指定服务名
    state: started
    enabled: yes  # 设置开机自启

- name: 配置登录提示信息
  template:
    src: motd.j2           # 源模板文件
    dest: /etc/motd        # 目标文件位置

- name: 配置AzureWhisky站点
  template:
    src: azurewhisky.conf.j2  # 虚拟主机配置模板
    dest: /etc/httpd/conf.d/azurewhisky.conf
  notify:
    - 重启Web服务         # 触发处理程序

- name: 创建网站根目录
  file:
    path: "/var/www/html/{{ ansible_hostname }}"  # 使用主机名创建目录
    state: directory

- name: 创建首页文件
  template:
    src: index.html.j2     # 首页模板
    dest: "/var/www/html/{{ ansible_hostname }}/index.html"
配置默认变量
# roles/apache/defaults/main.yml  
---
# Apache角色默认变量
web_package: httpd    # Web服务器软件包名
web_service: httpd    # Web服务名称
创建模板文件
{# roles/apache/templates/motd.j2 #}
hello guys!
Welcome to {{ ansible_fqdn }}!  {# 使用事实变量填充完全限定域名 #}
{# roles/apache/templates/azurewhisky.conf.j2 #}
# {{ ansible_managed }}  {# Ansible管理标记 #}
<VirtualHost *:80>
    ServerAdmin azurewhisky@{{ ansible_fqdn }}
    ServerName {{ ansible_fqdn }}
    ErrorLog logs/{{ ansible_hostname }}-error.log
    CustomLog logs/{{ ansible_hostname }}-common.log common
    DocumentRoot /var/www/html/{{ ansible_hostname }}/

    <Directory /var/www/html/{{ ansible_hostname }}/>
       Options +Indexes +FollowSymlinks +Includes
       Order allow,deny
       Allow from all
    </Directory>
</VirtualHost>
配置处理程序
# roles/apache/handlers/main.yml
---
# Apache角色处理程序
- name: 重启Web服务
  service:
    name: "{{ web_service }}"
    state: restarted
创建首页模板
{# roles/apache/templates/index.html.j2 #}
Welcome to {{ ansible_fqdn }} !
配置角色元数据
---
galaxy_info:
  author: azurewhisky
  description: azurewhisky的Web服务器角色
  company: azurewhisky世界
  license: GPLv2
  min_ansible_version: 2.4
  platforms:
  - name: Fedora
    versions:
    - all
    - 25
  galaxy_tags: [apache, web]  # 角色标签
dependencies: []  # 角色依赖项

调用角色

在Playbook中调用角色非常简单:

# 基本调用方式
---
- name: 部署Apache
  hosts: node1
  roles:
    - apache  # 直接引用角色名

# 带参数调用方式  
---
- name: 部署Apache
  hosts: node1
  roles:
    - role: apache        # 明确指定角色
      web_package: httpd  # 传递参数
      web_service: httpd
    - { role: apache, web_package: httpd, web_service: httpd }  # 简写格式

执行Playbook并验证结果:

# 验证motd配置
[azurewhisky@controller web]$ ssh root@node1
hello guys!
Welcome to node1.lab.example.com!

# 验证网站访问
[root@node1 ~]$ curl http://node1/
Welcome to node1.azurewhisky.top !

角色依赖关系

角色可以声明依赖其他角色,例如Web服务器角色可能依赖防火墙角色:

# roles/apache/meta/main.yml
dependencies:
- role: firewall
  service: http  # 传递参数给依赖角色

创建防火墙角色:

[azurewhisky@controller web]$ ansible-galaxy init firewall --init-path=./roles

配置防火墙角色任务:

# roles/firewall/tasks/main.yml
---
# 防火墙角色任务
- name: 安装firewalld
  yum:
    name: firewalld
    state: latest

- name: 启动并启用firewalld服务
  service:
    name: firewalld
    state: started
    enabled: true

- name: 配置防火墙服务
  firewalld:
    state: enabled        # 启用规则
    immediate: true       # 立即生效
    permanent: true       # 永久生效
    service: "{{ service }}"  # 使用变量指定服务

配置防火墙默认变量:

# roles/firewall/defaults/main.yml
---
# 防火墙默认变量
service: ssh  # 默认允许SSH服务

任务执行顺序

Ansible按照特定顺序执行任务:

  1. pre_tasks - 前置任务
  2. roles - 角色任务
  3. tasks - 普通任务
  4. post_tasks - 后置任务

注意:剧本中的书写顺序不影响实际执行顺序。

示例演示:

---
- name: 测试任务执行顺序
  hosts: node1
  gather_facts: false  # 禁用事实收集
  
  pre_tasks:
    - name: 前置任务
      shell: echo '这是前置任务'
  
  roles:
    - test_task_exec_order  # 调用测试角色
  
  tasks:
    - name: 普通任务
      shell: echo '这是普通任务'

  post_tasks:
    - name: 后置任务
      shell: echo '这是后置任务'

处理程序执行顺序

处理程序按照以下顺序执行:

  1. pre_tasks通知的处理程序
  2. roles任务
  3. roles通知的处理程序
  4. tasks任务
  5. tasks通知的处理程序
  6. post_tasks任务
  7. post_tasks通知的处理程序

重要:剧本中的处理程序具有全局作用域,可以被任何任务通知。

动态角色调用

使用include_roleimport_role在任务中动态调用角色:

---
- hosts: node1
  tasks:
    - shell: echo '第一个任务'
    - name: 在任务中调用角色
      import_role:  # 或使用include_role
        name: hello
      when: condition_met  # 条件判断

区别说明:

  • import_role:执行前解析角色,语法错误会立即终止
  • include_role:执行时解析角色,条件为false时不解析

Ansible角色的优势

  • 标准化:为系统类型(Web服务器、数据库等)定义标准配置
  • 并行开发:多个管理员可以同时开发不同角色
  • 代码复用:轻松共享和复用自动化代码
  • 易于管理:使大型项目更易于维护和组织

角色开发最佳实践

  1. 避免敏感信息:不要将密码或密钥存储在角色中,使用变量参数化
  2. 精简结构:使用ansible-galaxy init创建角色,删除不需要的目录
  3. 完善文档:维护README.md和meta/main.yml文件说明角色用途
  4. 功能专注:每个角色应专注于特定功能,避免过于复杂
  5. 代码重构:经常重用和重构角色,避免为边缘情况创建新角色
  6. 版本控制:使用版本控制系统管理角色演变

使用系统角色

系统角色介绍

RHEL从7.4开始提供预打包的系统角色,这些角色可以帮助标准化RHEL主机的配置。例如,使用timesync角色可以统一配置RHEL6和7的时间同步,无需关心底层是ntpd还是chronyd服务。

安装系统角色

[azurewhisky@controller ~]$ sudo yum install -y rhel-system-roles

# 系统角色安装在标准位置
[azurewhisky@controller ~]$ ls -1 /usr/share/ansible/roles/

# 文档位于
[azurewhisky@controller ~]$ ls /usr/share/doc/rhel-system-roles

时间同步角色示例

---
- name: 时间同步配置
  hosts: node1
  vars:
    timesync_ntp_servers:
      - hostname: classroom.example.com
        iburst: yes  # 启用快速初始同步
    timezone: "Asia/Shanghai"  # 设置时区
  roles:
    - rhel-system-roles.timesync  # 调用系统角色
  tasks:
    - name: 设置时区
      timezone:
        name: "{{ timezone }}"

SELinux角色示例

---
- name: SELinux配置
  hosts: node1
  vars:
    selinux_state: enforcing  # 设置强制模式
    selinux_booleans:
      - name: 'httpd_enable_homedirs'
        state: 'on'
        persistent: 'yes'  # 永久生效
    selinux_fcontexts:
      - target: '/srv/www(/.*)?'
        setype: 'httpd_sys_content_t'
        state: 'present'
  roles:
    - rhel-system-roles.selinux

处理需要重启的SELinux配置

---
- hosts: node1,node2
  vars:
    selinux_state: enforcing
  tasks:
    - block:  # 块错误处理
        - name: 应用SELinux角色
          include_role:
            name: rhel-system-roles.selinux
      rescue:  # 救援块
        - name: 检查是否需要重启以外的错误
          fail:
          when: not selinux_reboot_required
        - name: 重启受管主机
          reboot:
        - name: 重新应用SELinux角色
          include_role:
            name: rhel-system-roles.selinux

使用Ansible Galaxy部署角色

Ansible Galaxy介绍

Ansible Galaxy是一个由社区维护的角色仓库,包含大量可重用的角色,帮助用户快速实现自动化任务。

ansible-galaxy命令使用

# 查看已安装角色
[azurewhisky@controller web]$ ansible-galaxy list

# 搜索角色(需要网络连接)
[azurewhisky@controller ~]$ ansible-galaxy search --platforms=EL haproxy

# 查看角色详细信息
[azurewhisky@controller ~]$ ansible-galaxy info geerlingguy.docker

# 查看本地角色信息
[azurewhisky@controller web]$ ansible-galaxy info apache --offline

# 安装角色
[azurewhisky@controller ~]$ ansible-galaxy install geerlingguy.haproxy

批量安装角色

创建requirements.yml文件:

# requires.yml
- name: docker
  src: https://github.com/geerlingguy/ansible-role-docker/archive/2.7.0.tar.gz
- name: haproxy
  src: https://github.com/geerlingguy/ansible-role-haproxy/archive/1.1.2.tar.gz

批量安装:

[azurewhisky@controller ~]$ ansible-galaxy install -r requires.yml

其他管理命令

# 登录Galaxy
[azurewhisky@controller ~]$ ansible-galaxy login

# 删除角色
[azurewhisky@controller ~]$ ansible-galaxy remove role_name

# 登出
[azurewhisky@controller ~]$ ansible-galaxy logout

综合案例:部署Web集群

需求说明

  1. node3作为负载均衡器(HAProxy)
  2. node1和node2作为Web服务器

实施步骤

# 创建清单文件
[azurewhisky@controller web]$ cat > inventory <<EOF
[loadbalancers]
loadbalancer ansible_host=node3

[webservers]
node1
node2
EOF

# 安装所需角色
[azurewhisky@controller web]$ ansible-galaxy install geerlingguy.haproxy
[azurewhisky@controller web]$ ansible-galaxy install geerlingguy.apache

# 查看HAProxy角色文档了解配置参数
[azurewhisky@controller web]$ less roles/geerlingguy.haproxy/README.md

编写部署剧本

# deploy_web_cluster.yaml
---
- name: 部署负载均衡器
  hosts: loadbalancers
  vars:
    haproxy_backend_servers:  # 配置后端服务器
      - name: node1
        address: 10.1.8.11:80  # node1的IP和端口
      - name: node2
        address: 10.1.8.12:80  # node2的IP和端口
  roles:
    - geerlingguy.haproxy  # 调用HAProxy角色

- name: 部署Web服务器
  hosts: webservers
  roles:
    - geerlingguy.apache  # 调用Apache角色
  tasks:
    - name: 创建首页内容
      copy:
        content: "Welcome to {{ ansible_fqdn }}.\n"  # 动态生成内容
        dest: /var/www/html/index.html

执行部署并验证

# 运行部署剧本
[azurewhisky@controller web]$ ansible-playbook deploy_web_cluster.yaml

# 测试负载均衡效果
[azurewhisky@controller web]$ curl http://node3/
Welcome to node1.azurewhisky.top.
[azurewhisky@controller web]$ curl http://node3/
Welcome to node2.azurewhisky.top.

通过这个完整的指南,您应该对Ansible角色管理有了深入的理解,能够创建、使用和管理角色,以及利用Ansible Galaxy中的社区资源来加速自动化部署。


网站公告

今日签到

点亮在社区的每一天
去签到