自动化运维利器Ansible

前言

在如今的IT环境中,服务器数量越来越多,业务流程也越来越复杂。如果还靠手工登录每台服务器操作,不仅效率低,还容易出错。这时候,自动化运维工具就成了运维工程师的"救星"。

Ansible作为其中的佼佼者,凭借简单易用、无需客户端、安全可靠的特点,成为了很多人的首选。它不用在被管理的服务器上安装额外软件,通过SSH就能实现集中管理,哪怕是新手也能快速上手。今天,我们就从基础到实战,一步步带你认识和使用Ansible。

一、Ansible 概述和运行机制

1.1 Ansible 概述

Ansible是一款面向类Unix系统的开源自动化工具,用Python语言编写。和SaltStack、Puppet这些同类工具比,它最大的优势就是"轻量级"------被管理的服务器(被控端)不需要安装任何客户端软件,只要能通过SSH访问就行。

它的核心特点特别好记:

  • 部署简单:只需要在一台管理机上安装Ansible,被控端不用做任何配置
  • 通信安全:基于SSH协议通信,不用额外开放端口,安全又可靠
  • 配置简单:用YAML格式编写任务,像写清单一样容易理解
  • 功能强大:能实现软件安装、用户管理、服务配置等各种运维操作,还支持云计算和大数据平台

这里有个小知识点:Ansible成立于2013年,2015年被红帽公司以1-1.5亿美元收购,背后有强大的技术支持。

1.2 Ansible 工作机制

Ansible的工作原理特别简单,就像"快递员送货":

  1. 管理员在管理端编写好要执行的任务(比如安装软件、创建用户)
  2. Ansible通过SSH协议,把对应的"操作模块"(相当于快递包裹)推送到每台被控端服务器
  3. 被控端执行完模块中的操作后,会把结果反馈给管理端
  4. 执行完成后,模块会自动删除,不会在被控端留下残留

整个过程不用人工干预,还能结合Git、SVN这些工具管理任务配置,方便团队协作。

1.3 Ansible 角色 (Role)

刚开始用Ansible时,任务少,配置文件也简单。但随着服务器增多、任务变复杂,配置文件会变得越来越臃肿,不好维护。这时候,"角色(Role)"就派上用场了。

Role相当于把复杂的任务拆分成一个个独立的"功能模块",比如把"安装Nginx""配置MySQL"分别做成独立的Role。这样做的好处是:

  • 结构清晰,方便管理和修改
  • 可以重复使用,比如在多个项目中都用到Nginx配置,直接调用现成的Role就行
  • 支持从外部加载任务和变量,灵活适配不同场景

每个Role都有固定的目录结构,按照规范组织文件,后续维护起来会省心很多。

二、Ansible 环境安装部署

2.1 环境规划

我们以三台虚拟机为例,搭建一个简单的Ansible环境,具体规划如下:

节点类型 IP地址 角色描述
管理端 192.168.10.23 安装Ansible,统一管理其他服务器
被管理端1 192.168.10.14 作为Web服务器,归为webservers组
被管理端2 192.168.10.15 作为数据库服务器,归为dbservers组

注意:所有服务器都需要安装CentOS/RHEL系统,并且能互相ping通。

2.2 安装步骤

Ansible只需要在管理端安装,步骤很简单:

  1. 首先安装EPEL源(因为Ansible不在CentOS默认的软件源里)

    bash 复制代码
    yum install -y epel-release
  2. 安装Ansible

    bash 复制代码
    yum install -y ansible
  3. 验证安装是否成功,输入以下命令查看版本:

    bash 复制代码
    ansible --version

    如果能显示Ansible的版本信息,就说明安装成功了。

安装完成后,Ansible会自动创建默认目录/etc/ansible/,里面有三个重要的东西:

  • ansible.cfg:主配置文件,默认不用修改
  • hosts:主机清单,用来记录被控端服务器的信息
  • roles/:存放Role的目录,后续复杂任务会用到

2.3 主机清单配置

主机清单就是Ansible的"服务器通讯录",告诉它要管理哪些服务器,以及这些服务器属于哪个组。

编辑主机清单文件:

bash 复制代码
vim /etc/ansible/hosts

在文件中添加以下内容,把被控端按功能分组:

ini 复制代码
# Web服务器组,命名为webservers
[webservers]
192.168.10.14

# 数据库服务器组,命名为dbservers
[dbservers]
192.168.10.15

保存退出后,Ansible就知道要管理哪些服务器了。如果服务器的SSH端口不是默认的22,还可以在IP后面加:端口号,比如192.168.10.14:2222

2.4 SSH免密登录配置

因为Ansible通过SSH通信,为了避免每次执行任务都输入密码,需要配置管理端到被控端的免密登录:

  1. 在管理端生成SSH密钥对(一路按回车就行,不用输入额外信息)

    bash 复制代码
    ssh-keygen -t rsa
  2. 把公钥复制到两台被控端服务器(替换成你的被控端IP和密码,示例密码123456)

    bash 复制代码
    # 复制到webservers组的被控端
    sshpass -p '123456' ssh-copy-id root@192.168.10.14
    # 复制到dbservers组的被控端
    sshpass -p '123456' ssh-copy-id root@192.168.10.15
  3. 测试免密登录是否成功,比如登录到192.168.10.14:

    bash 复制代码
    ssh root@192.168.10.14

    如果不用输入密码就能登录,就说明配置成功了。

三、Ansible 基础命令及模块操作

3.1 基本命令格式

Ansible的命令格式很固定,记住这个公式就能灵活使用:

bash 复制代码
ansible <目标主机/组> -m <模块名> -a "<模块参数>"
  • <目标主机/组>:可以是单个IP(比如192.168.10.14)、组名(比如webservers),也可以用all表示所有被控端
  • -m <模块名>:指定要使用的模块(比如安装软件用yum模块),如果省略这个参数,默认使用command模块
  • -a "<模块参数>":模块的具体参数(比如要安装的软件名、要执行的命令)

另外,想查看某个模块的用法,可以用ansible-doc -s 模块名,比如ansible-doc -s yum就能查看yum模块的使用说明。

3.2 常用模块详解

Ansible有很多模块,每个模块对应不同的功能,下面介绍最常用的13个模块,每个模块都配了简单的示例,拿来就能用。

3.2.1 command 模块

功能:在被控端执行简单命令,不支持管道(|)、重定向(>) 这些Shell特性

示例:

bash 复制代码
# 查看webservers组所有服务器的当前时间
ansible webservers -m command -a 'date'
# 查看所有被控端的/目录下的文件(省略-m,默认用command模块)
ansible all -a 'ls /'
# 执行命令前先切换到/home目录
ansible all -m command -a 'chdir=/home ls ./'
3.2.2 shell 模块

功能:和command模块类似,但支持管道、重定向 等Shell特性,适合执行复杂命令

示例:

bash 复制代码
# 给dbservers组的test用户设置密码(123456)
ansible dbservers -m shell -a 'echo 123456 | passwd --stdin test'
# 获取被控端的IP地址(通过管道命令筛选)
ansible dbservers -m shell -a 'ifconfig ens33 | awk "NR==2 {print \$2}"'

注意:如果命令里有$符号,需要加\转义,否则会出错。

3.2.3 cron 模块

功能:管理被控端的计划任务(比如定时执行脚本、备份数据)

常用参数:

  • minute/hour/day/month/weekday:分/时/日/月/周(*/1表示每分钟,0 3 * * *表示每天凌晨3点)
  • job:要执行的任务命令
  • name:计划任务的名称(方便后续删除或修改)
  • statepresent(添加任务,默认)或absent(删除任务)
    示例:
bash 复制代码
# 给webservers组添加每分钟执行的任务(输出helloworld)
ansible webservers -m cron -a 'minute="*/1" job="/bin/echo helloworld" name="test_cron"'
# 查看webservers组的计划任务
ansible webservers -a 'crontab -l'
# 删除刚才添加的计划任务(通过名称匹配)
ansible webservers -m cron -a 'name="test_cron" state=absent'
3.2.4 user 模块

功能:管理被控端的系统用户(创建、删除、修改用户信息)

常用参数:

  • name:用户名(必填)
  • statepresent(创建用户)或absent(删除用户)
  • uid:用户ID
  • group:用户所属的基本组
    示例:
bash 复制代码
# 给dbservers组创建test01用户
ansible dbservers -m user -a 'name="test01"'
# 查看是否创建成功(查看/etc/passwd文件末尾)
ansible dbservers -a 'tail /etc/passwd'
# 删除test01用户(不删除家目录)
ansible dbservers -m user -a 'name="test01" state=absent'
3.2.5 group 模块

功能:管理被控端的系统用户组(创建、删除用户组)

示例:

bash 复制代码
# 给dbservers组创建mysql用户组(GID=306)
ansible dbservers -m group -a 'name=mysql gid=306 system=yes'
# 把test01用户添加到mysql组
ansible dbservers -m user -a 'name=test01 group=mysql'
# 验证用户组配置
ansible dbservers -a 'id test01'
3.2.6 copy 模块

功能:把管理端的文件复制到被控端,或者直接在被控端创建文件并写入内容

常用参数:

  • src:管理端的文件路径(要复制的文件)
  • dest:被控端的目标路径(绝对路径)
  • content:直接写入被控端文件的内容(和src不能同时使用)
  • owner:目标文件的属主
  • mode:目标文件的权限(比如640、755)
    示例:
bash 复制代码
# 把管理端的/etc/fstab文件复制到dbservers组的/opt目录下,并重命名为fstab.bak
ansible dbservers -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
# 直接在webservers组的/opt目录下创建hello.txt文件,写入内容helloworld
ansible webservers -m copy -a 'content="helloworld" dest=/opt/hello.txt'
3.2.7 file 模块

功能:管理被控端的文件属性(修改属主、权限)、创建/删除文件、创建软链接等

示例:

bash 复制代码
# 修改/opt/fstab.bak的属主为test01,属组为mysql,权限为644
ansible dbservers -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'
# 给/opt/fstab.bak创建软链接/opt/fstab.link
ansible dbservers -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link'
# 在被控端创建abc.txt文件
ansible all -m file -a 'path=/opt/abc.txt state=touch'
# 删除abc.txt文件
ansible all -m file -a 'path=/opt/abc.txt state=absent'
3.2.8 hostname 模块

功能:修改被控端的主机名

示例:

bash 复制代码
# 把dbservers组的被控端主机名改为mysql01
ansible dbservers -m hostname -a 'name=mysql01'
# 验证主机名是否修改成功
ansible dbservers -a 'hostname'
3.2.9 ping 模块

功能:检测管理端和被控端的连通性(最常用的测试模块)

示例:

bash 复制代码
# 测试所有被控端的连通性
ansible all -m ping

如果输出ping: "pong",说明连通正常;如果报错,需要检查SSH配置或网络连接。

3.2.10 yum 模块

功能:管理被控端的RPM软件包(安装、卸载软件)

示例:

bash 复制代码
# 给webservers组安装Apache服务(httpd)
ansible webservers -m yum -a 'name=httpd'
# 卸载webservers组的httpd服务
ansible webservers -m yum -a 'name=httpd state=absent'
3.2.11 service/systemd 模块

功能:管理被控端的系统服务(启动、停止、重启、设置开机自启)

常用参数:

  • name:服务名称(比如httpd、mysql)
  • statestarted(启动)、stopped(停止)、restarted(重启)
  • enabledyes(开机自启)、no(不开机自启)
    示例:
bash 复制代码
# 启动webservers组的httpd服务,并设置开机自启
ansible webservers -m service -a 'name=httpd state=started enabled=yes'
# 查看httpd服务状态
ansible webservers -a 'systemctl status httpd'
# 重启httpd服务
ansible webservers -m service -a 'name=httpd state=restarted'
3.2.12 script 模块

功能:在所有被控端批量执行管理端的Shell脚本(不用把脚本传到被控端,Ansible会自动处理)

示例:

  1. 在管理端创建一个测试脚本test.sh

    bash 复制代码
    vim test.sh

    写入以下内容:

    bash 复制代码
    #!/bin/bash
    echo "hello ansible from script" > /opt/script.txt
  2. 给脚本添加执行权限

    bash 复制代码
    chmod +x test.sh
  3. 在webservers组的被控端执行这个脚本

    bash 复制代码
    ansible webservers -m script -a 'test.sh'
  4. 验证执行结果(查看被控端的/opt/script.txt文件)

    bash 复制代码
    ansible webservers -a 'cat /opt/script.txt'
3.2.13 setup 模块

功能:收集被控端的系统信息(比如IP地址、内存大小、磁盘信息等)

示例:

bash 复制代码
# 收集所有被控端的详细信息
ansible all -m setup
# 只收集被控端的IP地址信息(通过filter筛选)
ansible all -m setup -a 'filter=*ipv4'
# 只收集被控端的内存信息
ansible all -m setup -a 'filter=ansible_memory_mb'

四、Inventory 主机清单与变量配置

4.1 主机分组管理

Inventory支持灵活的主机分组,除了前面提到的固定IP分组,还可以用"范围匹配"的方式批量添加主机,适合服务器数量多的场景。

示例:

ini 复制代码
# Web服务器组,包含192.168.10.12、192.168.10.13、192.168.10.14、192.168.10.15
[webservers]
192.168.10.1[2:5]
# 数据库服务器组,包含db-a.example.org到db-f.example.org
[dbservers]
db-[a:f].example.org

这样就不用一个个写IP或主机名,大大减少了配置量。

4.2 Inventory变量配置

有时候,不同的被控端可能有不同的SSH配置(比如端口、用户名、密码),这时候可以通过变量来设置,不用每次执行命令都指定参数。

4.2.1 主机变量配置

直接在主机后面添加变量,只对该主机生效:

ini 复制代码
[webservers]
# 该主机的SSH端口是2222,用户名root,密码123456
192.168.10.14 ansible_port=2222 ansible_user=root ansible_password=123456
4.2.2 组变量配置

给整个组设置变量,组内所有主机都生效:

ini 复制代码
[webservers]
192.168.10.14
192.168.10.15

# webservers组的所有主机共用这些变量
[webservers:vars]
ansible_user=root
ansible_password=123456

# 所有组的主机共用的变量(全局变量)
[all:vars]
ansible_port=22
4.2.3 组嵌套配置

如果有多个小组,想把它们归为一个大组统一管理,可以用组嵌套(通过children关键字实现):

ini 复制代码
# 定义两个小组:nginx组和apache组
[nginx]
192.168.10.20
192.168.10.21

[apache]
192.168.10.30
192.168.10.31

# 把nginx和apache组嵌套成webs大组
[webs:children]
nginx
apache

之后执行命令时,用webs作为目标组,就能管理所有nginx和apache组的主机了:

bash 复制代码
# 查看webs大组所有主机的时间
ansible webs -a 'date'

总结

Ansible作为一款简单强大的自动化运维工具,能帮我们解决重复的运维工作,提高效率、减少错误。通过本文的介绍,你应该已经掌握了Ansible的核心概念、环境搭建、常用模块和主机清单配置。

它的优势很明显:不用装客户端、配置简单、基于SSH安全可靠,哪怕是新手也能快速上手。而且它的模块非常丰富,几乎能覆盖所有日常运维场景,从软件安装、用户管理到服务配置、任务调度,都能轻松实现。

相关推荐
代码游侠2 小时前
学习笔记——线程控制 - 互斥与同步
linux·运维·笔记·学习·算法
AALoveTouch2 小时前
n8n 2.0 中文汉化版一键部署教程 | 解除Execute Command限制
人工智能·自动化
Bruce_Liuxiaowei2 小时前
SSH主机密钥验证失败(Host key verification failed)深度解析与解决方案
运维·网络·ssh
core5122 小时前
Nginx 实战:如何通过代理转发下载中文文件并保留原文件名
运维·nginx·代理·下载·转发
OliverH-yishuihan3 小时前
在 Windows 上安装 Linux
linux·运维·windows
zclinux_3 小时前
【Linux】虚拟化的内存气泡
linux·运维·服务器
松涛和鸣3 小时前
DAY33 Linux Thread Synchronization and Mutual Exclusion
linux·运维·服务器·前端·数据结构·哈希算法
慧都小项3 小时前
Parasoft Jtest 如何用 JSON 文件驱动Java 测试自动化
java·自动化·json
蜘蛛小助理3 小时前
研发团队效率神器:手把手教你用蜘蛛表格构建自动化任务管理中枢
数据库·自动化·任务管理·多维表格·蜘蛛表格