Ansible入门与实战:从安装到模块应用全攻略
一、Ansible 简介:为什么选择它?
Ansible 是一款轻量级自动化运维工具,无需在被控节点安装代理(Agentless),基于 SSH 协议通信,支持批量配置管理、应用部署、任务编排等场景。相比 SaltStack、Puppet,它学习成本低、配置简单,适合中小团队快速落地自动化运维,也是 DevOps 流程中的核心工具之一。
二、Ansible 安装与环境配置(Linux 系统为主)
1. 前提条件
-
控制节点:建议 CentOS 7+/Ubuntu 18.04+,需安装 Python 2.7 或 3.5+(默认系统通常自带)
-
被控节点:支持 Linux、Windows(需额外配置),确保控制节点能通过 SSH 免密登录被控节点
-
网络要求:控制节点与被控节点网络互通,开放 22 端口(SSH 默认端口)
2. 安装步骤(CentOS 7 示例)
方法 1:YUM 仓库安装(推荐,稳定)
\# 安装EPEL源(CentOS默认无Ansible仓库)
yum install -y epel-release
\# 安装Ansible
yum install -y ansible
\# 验证安装(查看版本)
ansible --version
方法 2:pip 安装(适合需要最新版本)
\# 安装pip
yum install -y python-pip
\# 升级pip
pip install --upgrade pip
\# 安装Ansible
pip install ansible
\# 验证版本
ansible --version
3. 基础配置:免密 SSH 登录(关键步骤)
Ansible 依赖 SSH 通信,配置免密登录可避免每次执行任务输入密码:
\# 控制节点生成SSH密钥对(一路回车即可,无需设置密码)
ssh-keygen -t rsa
\# 复制公钥到被控节点(替换为被控节点IP)
ssh-copy-id root@192.168.1.100
\# 测试免密登录
ssh root@192.168.1.100
4. 配置文件路径(核心)
-
主配置文件:
/etc/ansible/ansible.cfg(全局配置) -
自定义配置:可在项目目录创建
ansible.cfg(优先级更高) -
常用配置项(修改 ansible.cfg):
\[defaults]
\# 默认远程用户
remote\_user = root
\# 超时时间(秒)
timeout = 10
\# 忽略SSH密钥检查(首次连接无需确认)
host\_key\_checking = False
三、Inventory 清单:管理被控节点
Inventory 是 Ansible 的节点管理文件,用于定义被控节点的 IP、分组、变量等信息,默认路径/etc/ansible/hosts。
1. 基础格式(按分组管理)
\# 分组1:web服务器(可自定义组名)
\[web\_servers]
192.168.1.101
192.168.1.102:2222 # 非默认SSH端口(端口后加冒号)
web03.example.com # 支持域名
\# 分组2:数据库服务器
\[db\_servers]
192.168.1.201
192.168.1.202
\# 分组3:嵌套分组(包含web和db组)
\[all\_servers:children]
web\_servers
db\_servers
2. 自定义变量(简化任务编写)
可在清单中为节点或分组设置变量,后续 Playbook 直接调用:
\[web\_servers]
192.168.1.101 http\_port=80 server\_name="www.example.com"
192.168.1.102 http\_port=8080 server\_name="blog.example.com"
\# 分组变量(所有web节点通用)
\[web\_servers:vars]
nginx\_version=1.20.1
3. 验证清单(关键命令)
\# 列出所有被控节点
ansible all --list-hosts
\# 测试节点连通性(ping模块,all表示所有节点)
ansible all -m ping
\# 测试指定分组(如web\_servers)
ansible web\_servers -m ping
四、Playbook 编写:自动化任务核心
Playbook 是 Ansible 的任务执行文件,采用 YAML 格式,用于批量执行一系列操作(如安装软件、配置文件、启动服务),比单条 ansible 命令更易维护、可复用。
1. 基本结构(三要素:主机、变量、任务)
一个简单的 Playbook(install_nginx.yml)示例:
\# Play1:给web服务器安装Nginx
\- name: 安装并启动Nginx服务 # Play名称(自定义,便于识别)
  hosts: web\_servers # 目标主机(对应Inventory分组)
  remote\_user: root # 远程执行用户(可覆盖配置文件)
  gather\_facts: yes # 收集主机信息(如系统版本,默认开启)
  
  \# 变量定义(也可在Inventory或单独变量文件中定义)
  vars:
  nginx\_conf\_path: /etc/nginx/nginx.conf
  nginx\_root: /usr/share/nginx/html
  
  \# 任务列表(按顺序执行,每个task对应一个模块)
  tasks:
  \# 任务1:安装EPEL源(CentOS默认无Nginx)
  \- name: 安装EPEL仓库
  yum:
  name: epel-release
  state: present # present表示安装,absent表示卸载
   
  \# 任务2:安装Nginx
  \- name: 安装Nginx软件
  yum:
  name: nginx-{{ nginx\_version }} # 引用Inventory中的分组变量
  state: present
   
  \# 任务3:复制自定义Nginx配置文件(本地→远程)
  \- name: 部署Nginx配置文件
  copy:
  src: ./nginx.conf # 本地配置文件路径(相对Playbook目录)
  dest: "{{ nginx\_conf\_path }}" # 远程路径(引用vars变量)
  mode: 0644 # 文件权限
   
  \# 任务4:启动Nginx并设置开机自启
  \- name: 启动Nginx服务
  service:
  name: nginx
  state: started
  enabled: yes # enabled=yes表示开机自启
2. Playbook 执行命令
\# 基本执行(-i指定清单路径,默认/etc/ansible/hosts可省略)
ansible-playbook -i /etc/ansible/hosts install\_nginx.yml
\# 测试执行(不实际修改,仅检查语法和执行逻辑)
ansible-playbook --check install\_nginx.yml
\# 详细输出(查看执行过程中的变量、返回信息,排障用)
ansible-playbook -v install\_nginx.yml
\# 针对单个节点执行
ansible-playbook -l 192.168.1.101 install\_nginx.yml
3. 核心语法规则(避坑重点)
-
YAML 对缩进敏感:统一用 2 个空格缩进,不能用 Tab
-
键值对格式:
key: value(冒号后必须加空格) -
列表项:用
-开头(横杠后加空格),如 tasks 下的每个任务 -
变量引用:
{{ variable_name }}(双大括号前后可加空格,增强可读性)
五、Ansible 核心模块使用(实战高频)
Ansible 内置上千个模块,覆盖系统管理、软件部署、文件操作等场景,无需编写 Shell 脚本,直接调用模块即可完成任务。以下是最常用的模块实战示例:
1. 文件操作模块(copy/file)
- copy:本地文件复制到远程
\- name: 复制网站首页到远程
  copy:
  src: ./index.html
  dest: /usr/share/nginx/html/
  owner: root
  group: root
  mode: 0644
- file:创建文件 / 目录、修改权限
\- name: 创建Nginx日志目录
  file:
  path: /var/log/nginx/blog
  state: directory # state=directory表示创建目录,file表示文件
  owner: nginx
  group: nginx
2. 包管理模块(yum/apt)
- yum:CentOS/RHEL 系统安装软件
\- name: 安装MySQL
  yum:
  name: mysql-server
  state: present
- apt:Ubuntu/Debian 系统安装软件(需先更新仓库)
\- name: 更新apt仓库并安装Docker
  apt:
  name: docker.io
  state: present
  update\_cache: yes # 等同于apt update
3. 服务管理模块(service/systemd)
- service:兼容 SysVinit 和 Systemd
\- name: 重启MySQL服务
  service:
  name: mysqld
  state: restarted # state=restarted重启,stopped停止,reloaded重载
- systemd:专门用于 Systemd 系统(CentOS 7+/Ubuntu 16.04+)
\- name: 重载Docker并设置开机自启
  systemd:
  name: docker
  state: reloaded
  enabled: yes
  daemon\_reload: yes # 当配置文件修改后需重载daemon
4. 命令执行模块(command/shell)
- command:执行简单命令(不支持管道、变量替换)
\- name: 查看Nginx版本
  command: nginx -v
  register: nginx\_version\_result # 保存执行结果到变量
\# 打印结果(debug模块用于输出信息)
\- name: 输出Nginx版本
  debug:
  msg: "{{ nginx\_version\_result.stderr }}" # command模块的输出在stderr中
- shell:支持 bash 语法(管道、重定向、变量)
\- name: 统计Nginx访问日志行数
  shell: grep "200 OK" /var/log/nginx/access.log | wc -l
  register: access\_count
\- name: 输出访问量
  debug:
  msg: "成功访问次数:{{ access\_count.stdout }}"
5. 其他常用模块
- user:创建 / 删除用户
\- name: 创建运维用户ops
  user:
  name: ops
  groups: wheel # 加入wheel组(sudo权限)
  shell: /bin/bash
  create\_home: yes # 创建家目录
- cron:添加定时任务
\- name: 每天凌晨3点备份MySQL
  cron:
  name: "MySQL backup"
  minute: "0"
  hour: "3"
  job: "mysqldump -u root -p123456 test > /backup/test\_\$(date +%Y%m%d).sql"
六、实战案例:批量部署 Web 服务
需求
-
被控节点:web_servers 分组(2 台 CentOS 7)
-
任务:安装 Nginx、部署静态网站、配置防火墙开放 80 端口
完整 Playbook(deploy_web.yml)
\- name: 批量部署Web服务
  hosts: web\_servers
  remote\_user: root
  gather\_facts: yes
  vars:
  web\_root: /usr/share/nginx/html
  firewall\_port: 80
  tasks:
  \# 1. 安装EPEL源
  \- name: 安装EPEL仓库
  yum:
  name: epel-release
  state: present
  \# 2. 安装Nginx和firewalld
  \- name: 安装依赖软件
  yum:
  name:
  \- nginx
  \- firewalld
  state: present
  \# 3. 部署静态网站文件(本地./website目录下的所有文件)
  \- name: 部署网站代码
  copy:
  src: ./website/
  dest: "{{ web\_root }}"
  owner: nginx
  group: nginx
  mode: 0644
  \# 4. 配置防火墙开放80端口
  \- name: 启动firewalld并开放80端口
  firewalld:
  service: http # 等同于端口80,也可直接用port=80/tcp
  permanent: yes # 永久生效
  state: enabled
  immediate: yes # 立即生效(无需重启firewalld)
  \# 5. 启动Nginx并设置开机自启
  \- name: 启动Nginx服务
  service:
  name: nginx
  state: started
  enabled: yes
  \# 6. 验证Nginx状态
  \- name: 检查Nginx是否运行
  command: systemctl is-active nginx
  register: nginx\_status
  failed\_when: nginx\_status.stdout != "active" # 非active则任务失败
  \- name: 输出Nginx运行状态
  debug:
  msg: "Nginx服务状态:{{ nginx\_status.stdout }}"
执行与验证
\# 执行Playbook
ansible-playbook deploy\_web.yml
\# 验证结果(访问任意web节点IP)
curl http://192.168.1.101
浙公网安备 33010602011771号