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
posted @ 2025-12-15 14:11  好汉技术  阅读(147)  评论(0)    收藏  举报