前言

在当今的IT运维中,面对成百上千台服务器,传统的人工手动操作方式不仅效率低下,而且极易出错。自动化运维工具的出现,正是为了解决这一痛点。在众多自动化工具中,Ansible 因其简单易用、功能强大且无需在被管理端安装代理(Agentless)的特性而备受青睐。本文将带您全面了解 Ansible,从其核心概念、运行机制到基础安装和常用模块操作,为您开启自动化运维的大门。


一、Ansible 概述和运行机制

1.1 Ansible 概述

Ansible 是一款使用 Python 语言编写的开源自动化运维工具,它实现了批量系统配置、批量程序部署、批量运行命令等功能,主要面向类 Unix 系统。

1.1.1 与其他工具的对比

与 Puppet、SaltStack、Chef 等同类工具相比,Ansible 具有显著优势:

  • Puppet:Ruby 语言编写,采用 C/S 架构,通过 HTTP 协议通信。
  • SaltStack:Python 编写,采用 C/S 架构,通过 SSH 或消息队列(MQ)通信。
  • Chef:同样采用 C/S 架构,通过 HTTP 协议通信。

而 Ansible 的优势在于:

  • 无代理(Agentless):无需在被管理节点上安装任何客户端,非常轻量。
  • 使用 SSH:直接通过 SSH 协议与远程节点进行通信和操作。
  • 易于上手:使用 YAML 语言编写剧本(Playbook),语法简洁易懂。

官方网站:https://www.ansible.com/

1.1.2 发展历程与特点

  • 行业事件:Ansible 公司成立于 2013 年,并在 2015 年 10 月被红帽(Red Hat)公司以约 1.5 亿美元收购。
  • 核心特点
    1. 部署简单,只需在管理端安装,被控端无需额外操作。
    2. 默认使用 SSH 协议管理设备,安全可靠。
    3. 支持集中化管理,功能强大,扩展性高。
    4. 通过 Playbook 剧本实现复杂的任务编排和状态管理。
    5. 对云计算和大数据平台有良好的支持。

1.2 Ansible 运行机制

Ansible 的核心工作模式是“推送”:管理节点将所需的模块或命令通过 SSH 推送到被管理节点上执行,执行完成后自动删除临时文件。

核心组件

  1. Ansible:核心引擎。
  2. Modules(模块):核心执行单元,包括内置模块和自定义模块。
  3. Plugins(插件):用于增强核心功能,如连接插件、邮件插件等。
  4. Playbooks(剧本):采用 YAML 格式,定义自动化任务流程。
  5. Inventory(主机清单):定义被管理的主机及其分组信息。

1.3 Ansible 角色(Role)

为了应对复杂环境并提高 Playbook 的可复用性和可维护性,Ansible 引入了“角色”的概念。角色允许用户将相关的任务、处理程序、文件、模板和变量等组织在一个独立的目录结构中,便于共享和重复使用。


二、实战:安装并配置 Ansible

2.1 环境准备

本示例环境包含三台主机:

角色 IP 地址
管理端 192.168.10.123
被管理端 1 192.168.10.124
被管理端 2 192.168.10.125

2.2 管理端安装 Ansible

在管理端服务器上执行以下命令进行安装:

# 安装 EPEL 扩展源
yum install -y epel-release
# 安装 Ansible
yum install -y ansible

安装完成后,主要配置文件目录为 /etc/ansible/,其结构如下:

/etc/ansible/
├── ansible.cfg    # Ansible 主配置文件
├── hosts          # 默认的主机清单文件
└── roles/         # 角色目录

2.3 配置主机清单 (Inventory)

编辑 /etc/ansible/hosts 文件,定义需要管理的主机。

[webservers] # 定义名为 webservers 的组
192.168.10.14 # 组内包含的主机 IP

[dbservers]  # 定义名为 dbservers 的组
192.168.10.15

2.4 配置 SSH 免密登录

为了让 Ansible 管理节点可以无缝通过 SSH 连接被管理节点,需要配置密钥认证。

管理端 生成 SSH 密钥对,并将公钥分发到所有被管理端:

# 生成密钥对,一路回车即可
ssh-keygen -t rsa

# 使用 sshpass 工具免交互拷贝公钥(需要先安装 sshpass: ‘yum install -y sshpass’)
sshpass -p '你的密码' ssh-copy-id root@192.168.10.14
sshpass -p '你的密码' ssh-copy-id root@192.168.10.15

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

3.1 命令格式

Ansible 的基本命令行使用格式如下:

ansible <主机或组名> -m <模块名> -a "<模块参数>"
  • <主机或组名>:来自主机清单,可以是 IP、组名或 all(代表所有主机)。
  • -m <模块名>:指定要使用的模块。
  • -a "<参数>":传递给模块的参数。

3.2 常用模块详解

3.2.1 command 模块

功能:用于在远程主机执行简单命令。注意:不支持管道符 |、重定向 (<, >) 等 Shell 特性。
示例

ansible-doc -s command # 查看模块帮助
ansible host1 -m command -a 'date' # 对 webservers 组执行 date 命令
ansible all -a 'ls /' # 省略 -m 参数时,默认使用 command 模块
  • chdir:在远程主机上运行命令前提前进入目录,类似cd
  • creates:判断指定文件是否存在,如果存在,不执行后面的操作
  • removes:判断指定文件是否存在,如果存在,执行后面的操作
参数 是否必选 默认值 说明 示例
cmd - 要执行的命令。 cmd="/usr/bin/wh"
_raw_params - cmd相同,通常省略。 直接写 "/usr/bin/wh"
chdir - 执行命令前,先切换到此目录。 chdir="/tmp"
creates - 如果此文件/目录存在,则不执行命令。 creates="/tmp/lockfile"
removes - 如果此文件/目录存在,则执行命令。 removes="/tmp/old.log"

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2 shell 模块

功能:用于执行复杂的 Shell 命令,支持管道、重定向等所有 Shell 特性。
示例

ansible host1 -m shell -a 'echo 123456 | passwd --stdin test' # 免交互修改用户密码
ansible host1 -m shell -a 'echo $(ifconfig ens33 | awk "NR==2 {print \$2}")' # 获取 IP 地址
参数 是否必选 默认值 说明 示例
cmd - 要执行的命令字符串。 cmd="ps aux | grep java"
_raw_params - cmd相同,通常是省略参数名直接写命令。 直接写 "ps aux | grep java"
chdir - 执行命令前,先切换到此目录。 chdir="/tmp"
creates - 如果此文件/目录存在,则不执行命令。 creates="/tmp/lockfile"
removes - 如果此文件/目录存在,则执行命令。 removes="/tmp/old.log"
executable /bin/sh 指定执行命令的 Shell。 executable="/bin/bash"

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

正常在主机输入awk是应该是echo $(ifconfig ens33 | awk 'NR==2 {print $2}'),但是使用ansible远程时'echo $(ifconfig ens33 | awk "NR==2 {print \$2}")'被要求包裹在单引号内,当双引号时使用$()会被识别为从本机给的变量,因此$(ifconfig ens33 | awk "NR==2 {print $2)此时awk只能跟双引号,但双引号内的内容会被转义,$2会被识别成一个参数,所以需要在双引号内进行转义$2

3.2.3 cron 模块

功能:管理远程主机的计划任务(crontab)。
示例

# 添加一个每 1 分钟执行一次的计划任务
ansible host1 -m cron -a 'minute="*/1" job="/bin/echo helloworld" name="123"'
# 查看计划任务
ansible host1 -a 'crontab -l'
# 移除指定的计划任务
ansible host1 -m cron -a 'name="123" state=absent' #假如任务没有名字,name=None即可
  • 在远程主机定义任务计划。其中有两种状态(state):present表示添加(可以省略),absent表示移除。
  • minute/hour/day/month/weekday:分/时/日/月/周
  • job:任务计划要执行的命令
  • name:任务计划的名称
参数 是否必选 默认值 说明 示例
name - 计划任务的唯一标识符(注释)。用于查找和删除任务。 name="Backup Job"
job - 要执行的命令或脚本。 job="/path/to/backup.sh"
state present 任务状态。 present:添加或更新。 absent:移除。 state=absent
minute * 分钟 (0-59)。 minute="5" minute="*/10"
hour * 小时 (0-23)。 hour="1"
day * 日 (1-31)。 day="1"
month * 月 (1-12)。 month="*/3"
weekday * 周几 (0-6, 周日=0 或 7)。 weekday="0" weekday="1-5"
user root 在哪个用户的 crontab 中修改。 user="nginx"
disabled - 是否禁用该任务(在行首添加 #)。 disabled=yes

在这里插入图片描述
在这里插入图片描述

也可以在远程主机的/var/log/cron中查看是否运行成功

3.2.4 user 模块 与 group 模块

功能:用于管理远程主机的用户和用户组。
示例

# 创建 mysql 组
ansible host1 -m group -a 'name=mysql gid=306 system=yes'
# 创建用户 test01 并加入 mysql 组
ansible host1 -m user -a 'name=test01 uid=306 system=yes group=mysql'
ansible host1 -m command -a 'tail /etc/passwd'
# 删除用户
ansible host1 -m user -a 'name="test01" state=absent'

常用的参数

  • name:用户名,必选参数
  • state=present|absent:创建账号或者删除账号,present表示创建,absent表示删除
  • system=yes|no:是否为系统账号,默认为yes
  • uid:用户uid
  • group:用户基本组
  • shell:默认使用的shell
  • move_home=yse|no:如果设置的家目录已经存在,是否将已-经存在的家目录进行移动
  • password:用户的密码,建议使用加密后的字符串
  • comment:用户的注释信息
  • remove=yes|no:当state=absent时,是否删除用户的家目录

user 模块具体参数一览表

参数 是否必选 默认值 说明 示例
name - 要创建、修改或删除的用户名。 name='testuser'
state present 用户状态。
present:创建用户(如果不存在)。
absent:删除用户(如果存在)。
state=present
state=absent
uid - 用户的 UID(数字)。 uid=1005
group 与用户名相同的主组 用户的主要组(GID 或组名)。 group='developers'
group=1001
groups - 用户所属的附加组列表。用逗号分隔。注意groupsgroup 不同,group 是主组,groups 是附加组。 groups='wheel,nginx'
append no 是否将 groups 中指定的组追加到用户的现有附加组中。如果为 no(默认),则用户将属于 groups 列表中的组,其他现有附加组将被移除。 append=yes
home /home/username 用户的家目录路径。 home='/opt/home/testuser'
shell /bin/bash 用户的默认登录 shell。 shell='/bin/zsh'
comment - 用户的描述信息(通常是 GECOS 或全名字段)。 comment='Test User'
password - 设置用户密码。必须使用加密后的哈希值,明文密码无效。 password='$6$salt$encrypted'
generate_ssh_key no 是否为用户生成 SSH 密钥对。
yes:生成。
no:不生成。
generate_ssh_key=yes
ssh_key_bits 2048 generate_ssh_key=yes 一起使用,指定 SSH 密钥的位数。 ssh_key_bits=4096
create_home yes 是否创建家目录。 create_home=no
system no 是否创建为系统用户(通常 UID < 1000)。 system=yes
remove no state=absent 一起使用,是否同时删除用户的家目录和邮件池。 state=absent remove=yes
move_home no 如果设置为 yes 并且 home 指向一个新位置,则将家目录移动到新位置。 move_home=yes

group 模块具体参数一览表

参数 是否必选 默认值 说明 示例
name - 要创建、修改或删除的组名。 name='developers'
state present 组状态。
present:创建组(如果不存在)。
absent:删除组(如果存在)。
state=present
state=absent
gid - 组的 GID(数字)。 gid=1005
system no 是否创建为系统组(通常 GID < 1000)。 system=yes

在这里插入图片描述

始终优先使用Ansible的专用模块(如 user, copy, yum, service)而不是裸的shell命令。​​ 这是发挥Ansible自动化威力和可靠性的关键。command或 shell模块应作为处理那些没有专用模块的特殊情况的“最后手段”。

3.2.5 copy 模块

功能:将管理节点上的文件或内容复制到远程主机。
示例

# 复制文件并设置权限
ansible host1 -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
# 直接将内容写入远程文件
ansible host1 -m copy -a 'content="helloworld" dest=/opt/hello.txt'

在这里插入图片描述
在这里插入图片描述

常用参数:

  • dest:指出复制文件的目标及位置,使用绝对路径,如果是源目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容
  • src:指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录,如果源是目录则目标也要是目录
  • mode:指出复制时,目标文件的权限
  • owner:指出复制时,目标文件的属主
  • group:指出复制时,目标文件的属组
  • content:指出复制到目标主机上的内容,不能与src一起使用

具体参数一览:

参数 是否必选 默认值 说明 示例
src 条件必选 - 本地源文件路径。与 content二选一。 src="/app/config.yml"
dest - 远程主机上的目标路径。 dest="/etc/app/config.yml"
content 条件必选 - 直接用字符串内容创建文件。与 src二选一。 content="Hello World"
owner - 目标文件属主。 owner="nginx"
group - 目标文件属组。 group="nginx"
mode - 目标文件权限。 mode="0644" mode="u+rw"
backup no 覆盖前是否备份原文件。 backup=yes
force yes 如果目标存在且不同,是否覆盖。 force=no
validate - 复制前执行验证命令(常用于配置文件)。 validate="/usr/sbin/nginx -t %s"

3.2.6 file 模块

功能:设置文件属性,如权限、属主、创建链接文件等。
示例

# 修改文件属性
ansible host1 -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'
# 创建软链接,path的文件存在时会报错
ansible host1 -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link'
# 创建空文件
ansible host1 -m file -a "path=/opt/abc.txt state=touch"
#删除一个文件
ansible dbservers -m file -a "path=/opt/abc.txt state=absent"			

在这里插入图片描述
在这里插入图片描述

具体参数一览:

参数 是否必选 默认值 说明 示例
path - 文件/目录/链接的路径。 path="/etc/foo.conf"
state file 对象类型。 file:文件。 directory:目录。 link:软链接。 hard:硬链接。 absent:删除。 state=directory state=absent
src - state=linkhard时,指定源路径。 src="/etc/foo.conf"
owner - 属主。 owner="root"
group - 属组。 group="root"
mode - 权限。 mode="0755"
recurse no 递归设置目录下的文件属性(需与 owner/group/mode配合)。 recurse=yes

3.2.7 hostname 模块

功能:管理远程主机的主机名。
示例

ansible host1 -m hostname -a "name=mysql01"

具体参数一览:

参数 是否必选 默认值 说明 示例
name - 要设置的主机名。 name="web-server-01"
use 取决于系统 使用哪个工具修改主机名(通常自动选择)。 use="systemd"

在这里插入图片描述

3.2.8 ping 模块

功能:检测与管理节点的 SSH 连通性。
示例

ansible all -m ping

在这里插入图片描述

3.2.9 yum 模块

功能:使用 yum 包管理器来安装或卸载软件包。
示例

# 安装 httpd 服务
ansible host1 -m yum -a 'name=httpd'
# 卸载 httpd 服务
ansible host1 -m yum -a 'name=httpd state=absent'

在这里插入图片描述
在这里插入图片描述

具体参数一览:

参数 是否必选 默认值 说明 示例
name - 包名。可以是 name@version格式,或用列表。 name="httpd" name="httpd,php"
state present 包状态。 present:安装最新版。 installed:同 present。 latest:升级到最新。 absent:卸载。 state=latest state=absent
disable_gpg_check no 是否禁用 GPG 签名检查。 disable_gpg_check=yes
enablerepo - 临时启用指定的仓库。 enablerepo="epel"
disablerepo - 临时禁用指定的仓库。 disablerepo="*"

3.2.10 service/systemd 模块

功能:管理远程主机的服务状态,如启动、停止、设置开机自启等。
示例

# 启动 httpd 服务并设置为开机自启
ansible host1 -m service -a 'enabled=true name=httpd state=started'

具体参数一览:

参数 是否必选 默认值 说明 示例
name - 服务名称。 name="nginx"
state - 服务运行状态。 started:启动。 stopped:停止。 restarted:重启。 reloaded:重载配置。 state=started
enabled - 服务开机自启状态。 yes:启用。 no:禁用。 enabled=yes
daemon_reload no 在执行操作前是否运行 daemon-reload(常用于修改服务文件后)。 daemon_reload=yes
sleep - restartedstopped后,等待几秒再执行下一个操作。 sleep=5

在这里插入图片描述
在这里插入图片描述

3.2.11 script 模块

功能:将管理节点本地的脚本在远程主机上执行。
示例

# 编写本地脚本 test.sh
ansible webservers -m script -a 'test.sh' # 在远程主机执行本地脚本

在这里插入图片描述

具体参数一览:

参数 是否必选 默认值 说明 示例
cmd - 本地脚本的路径。 cmd="/opt/scripts/deploy.sh"
_raw_params - cmd相同,通常省略。 直接写 "/opt/scripts/deploy.sh"
chdir - 在远程主机执行脚本前,先切换到此目录。 chdir="/tmp"
creates - 如果此文件/目录存在,则不执行脚本。 creates="/tmp/lockfile"
removes - 如果此文件/目录存在,则执行脚本。 removes="/tmp/old.log"

3.2.12 setup 模块

功能:收集远程主机的详细信息(Facts),如 IP、内存、磁盘等。
示例

ansible host1 -m setup # 收集所有信息
ansible dbservers -m setup -a 'filter=*ipv4*' # 使用过滤器只收集 IP 相关信息

facts 组件是用来收集被管理节点信息的,使用 setup 模块可以获取这些信息

# 内存信息
ansible all -m setup -a "filter=ansible_memory_mb*"

# 具体内存信息
ansible all -m setup -a "filter=ansible_memory_mb"
ansible all -m setup -a 'filter=ansible_memtotal_mb'
ansible all -m setup -a "filter=ansible_swaptotal_mb"
# 磁盘信息
ansible all -m setup -a "filter=ansible_devices*"
ansible all -m setup -a "filter=ansible_mounts*"

# 具体磁盘信息
ansible all -m setup -a "filter=ansible_devices"
ansible all -m setup -a "filter=ansible_mounts"
ansible all -m setup -a "filter=ansible_device_links"

# IPv4信息
ansible all -m setup -a 'filter=ansible_all_ipv4_addresses'
# 查看cpu信息
ansible all -m setup -a "filter=ansible_processor*"

在这里插入图片描述

具体参数一览:

参数 是否必选 默认值 说明 示例
filter - 过滤条件,只显示匹配特定模式的信息。 filter="*ipv4*" filter="ansible_distribution*"
gather_subset all 收集信息的子集,可提高效率。 all:所有。 min:最小集。 network:网络相关。 gather_subset="min" gather_subset="!all"(排除所有)
fact_path /etc/ansible/facts.d 自定义 Facts 脚本 (.fact) 的路径。 fact_path="/opt/app_facts"

四、Inventory 主机清单进阶配置

主机清单 (/etc/ansible/hosts) 支持更灵活的配置。
Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。

4.1 定义主机范围与端口

如果是名称类似的主机,可以使用列表的方式标识各个主机。

[webservers]
192.168.10.14:2222 # 指定非标准 SSH 端口
192.168.10.1[2:5] # 表示 192.168.10.12 到 192.168.10.15

[dbservers]
db-[a:f].example.org # 支持匹配主机名

4.2 设置变量

常用Inventory变量

变量名 含义
ansible_host 节点 IP
ansible_port SSH 端口,默认 22
ansible_user SSH 用户
ansible_password SSH 密码(未使用密钥时)
ansible_ssh_private_key_file 私钥文件
ansible_become 提升权限
ansible_become_method 提升方式(sudo/su/runas)
ansible_become_user 提升为指定用户
ansible_become_password 提升密码

4.2.1 主机变量

直接在主机后定义变量。

[webservers]
192.168.10.124 ansible_port=22 ansible_user=root ansible_password=root123

4.2.2 组变量

使用 :vars 为整个组设置变量。

[webservers:vars]
ansible_user=root
ansible_password=root123

[all:vars] # 为所有组设置变量
ansible_port=22

4.2.3 组嵌套

使用 :children 将多个组合并为一个新的组。

[nginx]
192.168.10.20
192.168.10.21

[apache]
192.168.10.30
192.168.10.31

[webs:children] # webs 组包含 nginx 和 apache 组的所有主机,只能识别组不能识别IP
nginx
apache
192.168.10.55 # 无效添加

总结

通过本文的学习,我们对 Ansible 有了一个全面的认识。从它的基本概念和优势,到如何一步步安装配置并建立 SSH 信任关系;从最基础的 ansible 命令和核心模块(如 command, shell, copy, yum 等)的使用,到如何灵活配置主机清单(Inventory)来管理复杂的主机分组和变量。

Ansible 的真正强大之处在于其 简单性幂等性(一个操作多次执行的结果与一次执行的结果一致)。作为自动化运维的利器,它极大地提升了运维工作的效率和可靠性。本文介绍的内容是 Ansible 的核心基础,掌握了这些,您就已经具备了使用 Ansible 完成日常批量管理任务的能力。下一步,可以深入学习 Playbook 的编写,从而解锁更复杂、更强大的自动化场景。
最后,希望大家多多实践、多多探究、聚沙成塔、与君共勉之!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐