4. Ansible Ad-Hoc 命令:格式、常用模块与实战

Ad-Hoc 命令是 Ansible 的“即时执行”模式,无需编写完整的 Playbook,即可在命令行中直接对目标主机执行单个任务。它适用于快速巡检、批量重启服务、分发配置文件等临时性操作。本章将深入解析 Ad-Hoc 命令的标准格式,并通过 7 个核心模块的实战演练,帮助你掌握自动化运维的“瑞士军刀”。

核心原则:Ad-Hoc 命令适用于执行一次或少数几次的任务。如果某个操作需要重复执行、包含条件判断或涉及多个步骤,应优先考虑编写 Playbook。

4.1 Ad-Hoc 命令格式解析

标准的 Ad-Hoc 命令遵循以下语法结构:

ansible <主机模式> -m <模块名> -a <模块参数> [选项]
组成部分 说明 示例
<主机模式> 指定目标主机,可以是主机名、组名、通配符或特殊关键字 webservers, all, 192.168.1.*
-m <模块名> 指定要执行的 Ansible 模块 -m ping, -m shell
-a <模块参数> 传递给模块的参数,通常为键值对或命令字符串 -a "src=/etc/hosts dest=/tmp/"
[选项] 控制执行行为的额外参数,如用户、密码、并发数等 -u root -k -f 10
常用选项速查:
-u:指定远程用户;-k:提示输入 SSH 密码;-b:使用 become 提权;--become-user=root:提权为 root;-f:指定并行进程数(默认 5)。

4.2 核心模块实战

以下 7 个模块覆盖了日常运维中 90% 以上的临时操作场景。我们将通过具体命令和输出示例,展示每个模块的典型用法。

4.2.1 ping 模块:连通性测试

用于验证 Ansible 控制节点与目标主机的 SSH 连接和 Python 环境是否正常。

# 测试所有主机连通性
ansible all -m ping

# 输出示例(成功):
# 192.168.1.10 | SUCCESS => {
#     "ansible_facts": {
#         "discovered_interpreter_python": "/usr/bin/python3"
#     },
#     "changed": false,
#     "ping": "pong"
# }

4.2.2 command 模块:执行系统命令(默认)

在远程主机上执行系统命令,不支持 shell 变量、管道、重定向等特殊符号。它是 Ansible 的默认模块,即 -m command 可省略。

# 查看远程主机 uptime(省略 -m 时默认使用 command)
ansible dbservers -a "uptime"

# 查看内核版本
ansible all -m command -a "uname -r"

4.2.3 shell 模块:执行 Shell 命令

与 command 模块类似,但支持 shell 环境特性,如管道、变量、通配符等。适用于需要复杂 shell 解析的场景。

# 使用管道统计进程数
ansible webservers -m shell -a "ps aux | grep nginx | wc -l"

# 使用变量和重定向
ansible all -m shell -a "echo $HOSTNAME > /tmp/hostname.txt"
安全提示:shell 模块会通过远程主机的 /bin/sh 执行命令,存在注入风险。如果命令不需要 shell 特性,应优先使用 command 模块。

4.2.4 copy 模块:文件分发

将控制节点上的文件或目录复制到远程主机。支持设置文件权限、所有者和备份。

# 复制本地配置文件到远程主机,并设置权限
ansible all -m copy -a "src=/etc/ansible/nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644 backup=yes"

4.2.5 file 模块:文件属性管理

管理远程主机上的文件、目录和链接的属性,包括创建、删除、修改权限等。

# 创建目录
ansible all -m file -a "path=/data/logs state=directory mode=0755"

# 创建软链接
ansible all -m file -a "src=/usr/local/nginx/conf/nginx.conf dest=/etc/nginx/nginx.conf state=link"

# 删除文件
ansible all -m file -a "path=/tmp/old_config.conf state=absent"

4.2.6 yum 模块:软件包管理(Red Hat 系)

管理基于 RPM 的 Linux 发行版(如 CentOS、RHEL、Fedora)上的软件包。

# 安装 nginx 最新版
ansible webservers -m yum -a "name=nginx state=latest"

# 安装指定版本
ansible webservers -m yum -a "name=nginx-1.20.1 state=present"

# 卸载软件包
ansible webservers -m yum -a "name=nginx state=absent"

4.2.7 service 模块:服务管理

管理系统服务的启动、停止、重启、重载和开机自启状态。

# 启动 nginx 并设置开机自启
ansible webservers -m service -a "name=nginx state=started enabled=yes"

# 重启服务
ansible webservers -m service -a "name=nginx state=restarted"

# 停止服务
ansible webservers -m service -a "name=nginx state=stopped"

4.3 模块选择决策流程

面对一个临时任务,如何快速选择正确的模块?以下 SVG 流程图展示了从任务类型到模块选择的决策路径。

Ad-Hoc 模块选择决策流程 临时任务需求 需要 Shell 特性? 是 shell 模块 否 文件操作? 是 复制/属性? 复制 copy 属性 file 模块 否 软件包管理? 是 yum 否 服务管理? 是 service 否 command 模块(默认)

4.4 综合实战:一键环境基线核验

将多个 Ad-Hoc 命令组合使用,可以快速完成环境一致性基线核验。以下是一个典型的核验脚本示例:

#!/bin/bash
# 环境基线核验脚本

echo "=== 1. 连通性测试 ==="
ansible all -m ping

echo "=== 2. 操作系统版本 ==="
ansible all -m command -a "cat /etc/redhat-release"

echo "=== 3. 内核参数 ==="
ansible all -m command -a "sysctl vm.swappiness"

echo "=== 4. 关键服务状态 ==="
ansible all -m service -a "name=sshd state=started enabled=yes"

echo "=== 5. 配置文件一致性 ==="
ansible all -m shell -a "md5sum /etc/ssh/sshd_config | awk '{print \$1}'"

echo "=== 6. 磁盘使用率 ==="
ansible all -m shell -a "df -h / | tail -1 | awk '{print \$5}'"

echo "=== 7. 安装的软件包版本 ==="
ansible all -m yum -a "list=installed" | grep -E "nginx|redis|mysql"
实战建议:将上述核验命令保存为 check_baseline.sh,配合 Ansible 的 --limit 参数可以针对特定主机组执行,实现环境一致性基线核验的自动化。

4.5 常见错误与避坑指南

错误场景 错误命令 正确做法
使用 command 执行管道 ansible all -a "ps aux | grep nginx" 改用 shell 模块:ansible all -m shell -a "ps aux | grep nginx"
copy 模块源路径不存在 ansible all -m copy -a "src=./noexist.conf dest=/tmp/" 确保源文件存在,或使用 content 参数直接写入内容
yum 模块包名拼写错误 ansible all -m yum -a "name=ngnix state=latest" 使用 yum list nginx 确认正确包名
service 模块服务名错误 ansible all -m service -a "name=mysqld state=started" 使用 systemctl list-units --type=service 确认服务名

掌握 Ad-Hoc 命令和这 7 个核心模块,你已经可以应对绝大多数日常运维的临时操作需求。下一阶段,我们将把这些命令组合成可复用的 Playbook,实现更复杂的自动化编排。