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 流程图展示了从任务类型到模块选择的决策路径。
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,实现更复杂的自动化编排。