Ansible架构与Inventory主机清单配置
Ansible是无代理自动化运维工具,通过SSH连接目标主机执行配置任务,不需要在目标机器安装客户端。核心架构包括控制节点(运行Ansible的机器)、Inventory(主机清单)和Playbook(任务编排文件)。
Inventory文件定义被管理主机的分组和连接参数。静态Inventory使用INI格式:
# /etc/ansible/hosts
[web_servers]
web1 ansible_host=192.168.1.11 ansible_user=root
web2 ansible_host=192.168.1.12 ansible_user=root
[db_servers]
db1 ansible_host=192.168.1.21 ansible_user=postgres ansible_port=2222
[prod:children]
web_servers
db_servers
方括号定义主机组,ansible_host指定IP,ansible_user指定SSH用户,ansible_port指定非默认SSH端口。[group:children]定义主机组嵌套,prod组包含web_servers和db_servers的所有主机。
动态Inventory适用于云环境,主机列表从云平台API动态获取:
#!/usr/bin/env python3
import json, requests
def get_inventory():
r = requests.get("http://consul:8500/v1/catalog/nodes")
hosts = {"web_servers": {"hosts": [], "vars": {}}, "db_servers": {"hosts": []}}
for node in r.json():
if "web" in node["Node"]:
hosts["web_servers"]["hosts"].append(node["Address"])
elif "db" in node["Node"]:
hosts["db_servers"]["hosts"].append(node["Address"])
return hosts
if __name__ == "__main__":
print(json.dumps(get_inventory(), indent=2))
使用动态Inventory时,ansible-inventory --list -i dynamic_inventory.py验证主机列表是否正确解析。
Playbook核心语法与模块使用
Playbook是YAML格式的任务编排文件,每个Play定义对哪些主机执行哪些任务。基础结构:
---
- name: 部署Nginx Web服务器
hosts: web_servers
become: yes
tasks:
- name: 安装Nginx
apt:
name: nginx
state: present
update_cache: yes
- name: 配置Nginx站点
copy:
src: files/nginx.conf
dest: /etc/nginx/sites-available/app.conf
mode: '0644'
notify: reload nginx
- name: 启用站点配置
file:
src: /etc/nginx/sites-available/app.conf
dest: /etc/nginx/sites-enabled/app.conf
state: link
- name: 确保Nginx运行
service:
name: nginx
state: started
enabled: yes
become: yes提权执行(等同于sudo),notify触发handler,service模块管理服务状态。常用模块包括:apt/yum(包管理)、copy/template(文件分发)、service/systemd(服务管理)、file(文件操作)、shell/command(命令执行)。
template模块支持Jinja2模板渲染,配置文件中可引用变量:
# templates/nginx.conf.j2
server {
listen {{ nginx_port }};
server_name {{ server_name }};
location / {
proxy_pass http://{{ backend_host }}:{{ backend_port }};
proxy_set_header Host $host;
}
}
变量管理:vars、register与facts机制
Ansible变量来源优先级从低到高:Inventory文件vars、Playbook中vars、命令行--extra-vars。在Playbook中定义变量:
- name: 配置数据库服务器
hosts: db_servers
vars:
postgres_version: "15"
max_connections: 200
shared_buffers: "4GB"
vars_files:
- vars/{{ ansible_os_family }}.yml
tasks:
- name: 安装PostgreSQL
apt:
name: "postgresql-{{ postgres_version }}"
state: present
vars_files按操作系统加载不同变量文件,ansible_os_family是Ansible自动收集的facts变量。setup模块收集目标主机信息:
# 查看所有facts
$ ansible db_servers -m setup
# 筛选特定facts
$ ansible db_servers -m setup -a "filter=ansible_memory*"
# 返回: "ansible_memory_mb": {"real": {"total": 32768, "used": 8192, "free": 24576}}
register捕获任务输出到变量,后续任务可引用:
tasks:
- name: 检查磁盘空间
shell: df -h / | tail -1 | awk '{print $5}' | tr -d '%'
register: disk_usage
changed_when: false
- name: 磁盘空间告警
debug:
msg: "磁盘使用率 {{ disk_usage.stdout }}%,超过阈值"
when: disk_usage.stdout | int > 80
changed_when: false标记该任务不改变系统状态(只读操作),避免Ansible报告变更。when条件判断基于register变量值决定是否执行后续任务。
Roles角色复用与目录结构规范
Role是Playbook的模块化封装,将变量、任务、模板、文件按固定目录组织,便于复用和分享。标准Role目录结构:
roles/nginx/
defaults/main.yml # 默认变量(优先级最低,可被覆盖)
vars/main.yml # 角色变量(优先级高于defaults)
tasks/main.yml # 主任务列表
handlers/main.yml # 触发器
templates/nginx.conf.j2 # Jinja2模板
files/nginx.repo # 静态文件
meta/main.yml # 角色元数据与依赖
在Playbook中引用Role:
- name: 部署Web集群
hosts: web_servers
become: yes
roles:
- role: nginx
vars:
nginx_port: 8080
- role: logrotate
tasks:
- name: 验证服务状态
uri:
url: "http://{{ ansible_host }}:8080/health"
status_code: 200
role关键字后跟角色名,vars为该Role传递参数覆盖defaults/main.yml中的默认值。Role执行顺序:meta依赖、defaults、tasks、handlers。用ansible-galaxy init nginx命令自动生成Role骨架。
Handlers触发机制与条件判断控制
Handler是被notify触发的任务,只在被通知时执行,且在Play中所有普通任务完成后统一执行。这一机制适用于服务重启场景——配置文件变更后才需要重启服务,避免每次执行都重启:
tasks:
- name: 修改Nginx配置
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: reload nginx
- name: 添加虚拟主机
template:
src: vhost.conf.j2
dest: /etc/nginx/conf.d/app.conf
notify: reload nginx
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
上述Playbook中两个任务都通知reload nginx,但handler只执行一次。Handler名称必须唯一,notify的名称与handlers中定义的name精确匹配。
when条件控制任务执行,支持Jinja2表达式:
tasks:
- name: Debian系安装
apt: name=nginx state=present
when: ansible_os_family == "Debian"
- name: RHEL系安装
yum: name=nginx state=present
when: ansible_os_family == "RedHat"
- name: 仅在主节点执行
shell: init_database.sh
when: inventory_hostname == groups['db_servers'][0]
loop循环处理批量操作,减少重复任务定义:
tasks:
- name: 创建多个用户
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
shell: /bin/bash
loop:
- { name: "deploy", groups: "www-data" }
- { name: "monitor", groups: "adm" }
- { name: "backup", groups: "backup" }
Ansible执行前用--check参数做dry-run预演,不实际修改系统:ansible-playbook deploy.yml --check。配合--diff参数可以查看将要变更的内容,在生产环境部署前验证Playbook影响范围。批量执行时用--forks控制并发数,默认5个主机并行,大规模集群可以调到20-50以加快执行速度,但需评估SSH连接和控制节点的负载承受能力。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/ansible-zi-dong-hua-yun-wei-shi-zhan-pi-liang-pei-zhi-guan/