Ansible Ad-hoc 命令 #
什么是 Ad-hoc 命令? #
Ad-hoc 命令是 Ansible 提供的一种快速执行临时任务的方式,无需编写 Playbook,直接在命令行执行单个任务。
text
┌─────────────────────────────────────────────────────────────┐
│ Ad-hoc vs Playbook │
├─────────────────────────────────────────────────────────────┤
│ │
│ Ad-hoc 命令 Playbook │
│ ──────────── ────────── │
│ 单行命令 YAML 文件 │
│ 临时任务 可重复任务 │
│ 快速执行 复杂编排 │
│ 无需保存 版本控制 │
│ 简单操作 复杂逻辑 │
│ │
└─────────────────────────────────────────────────────────────┘
基本语法 #
命令格式 #
bash
ansible <pattern> -m <module> -a "<arguments>" [options]
参数说明 #
| 参数 | 说明 |
|---|---|
| pattern | 主机模式,指定目标主机 |
| -m | 指定模块名称 |
| -a | 模块参数 |
| -i | 指定清单文件 |
| -u | 指定连接用户 |
| -b | 使用提权(become) |
| –become-user | 提权用户 |
| -v | 详细输出 |
| -f | 并发数 |
常用模块示例 #
ping 模块 #
测试主机连通性:
bash
# 测试所有主机
ansible all -m ping
# 测试特定组
ansible webservers -m ping
# 测试特定主机
ansible web1 -m ping
# 输出示例
web1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
command 模块 #
在远程主机执行命令(默认模块):
bash
# 执行简单命令
ansible all -a "uptime"
# 查看主机名
ansible all -a "hostname"
# 查看磁盘使用
ansible all -a "df -h"
# 查看内存使用
ansible all -a "free -m"
# 列出文件
ansible all -a "ls -la /tmp"
# 注意:command 模块不支持管道、重定向等 shell 特性
# 以下命令不会按预期工作
ansible all -a "cat /etc/passwd | grep root" # 错误
shell 模块 #
执行 shell 命令,支持管道、重定向等:
bash
# 使用管道
ansible all -m shell -a "cat /etc/passwd | grep root"
# 使用重定向
ansible all -m shell -a "echo 'hello' > /tmp/hello.txt"
# 使用环境变量
ansible all -m shell -a "echo $HOME"
# 使用子 shell
ansible all -m shell -a "for i in {1..5}; do echo $i; done"
# 查看服务状态
ansible all -m shell -a "systemctl status nginx"
# 查看进程
ansible all -m shell -a "ps aux | grep nginx"
copy 模块 #
复制文件到远程主机:
bash
# 复制文件
ansible all -m copy -a "src=/local/file.txt dest=/tmp/file.txt"
# 复制并设置权限
ansible all -m copy -a "src=file.txt dest=/tmp/file.txt mode=0644"
# 复制并设置所有者
ansible all -m copy -a "src=file.txt dest=/tmp/file.txt owner=root group=root"
# 直接写入内容
ansible all -m copy -a "content='Hello Ansible' dest=/tmp/hello.txt"
# 备份原文件
ansible all -m copy -a "src=file.txt dest=/tmp/file.txt backup=yes"
# 创建目录
ansible all -m copy -a "src=files/ dest=/tmp/files/"
file 模块 #
管理文件和目录:
bash
# 创建目录
ansible all -m file -a "path=/tmp/mydir state=directory"
# 创建文件
ansible all -m file -a "path=/tmp/myfile state=touch"
# 删除文件
ansible all -m file -a "path=/tmp/myfile state=absent"
# 删除目录
ansible all -m file -a "path=/tmp/mydir state=absent"
# 修改权限
ansible all -m file -a "path=/tmp/file mode=0755"
# 修改所有者
ansible all -m file -a "path=/tmp/file owner=root group=root"
# 创建符号链接
ansible all -m file -a "src=/tmp/file dest=/tmp/link state=link"
# 递归修改目录权限
ansible all -m file -a "path=/tmp/mydir mode=0755 recurse=yes"
apt 模块 #
管理 Debian/Ubuntu 软件包:
bash
# 更新缓存
ansible all -m apt -a "update_cache=yes" -b
# 安装软件包
ansible all -m apt -a "name=nginx state=present" -b
# 安装多个软件包
ansible all -m apt -a "name=nginx,git,curl state=present" -b
# 安装指定版本
ansible all -m apt -a "name=nginx=1.18.0 state=present" -b
# 卸载软件包
ansible all -m apt -a "name=nginx state=absent" -b
# 更新所有软件包
ansible all -m apt -a "upgrade=dist" -b
# 安装 deb 包
ansible all -m apt -a "deb=/tmp/package.deb" -b
yum 模块 #
管理 RHEL/CentOS 软件包:
bash
# 安装软件包
ansible all -m yum -a "name=nginx state=present" -b
# 安装多个软件包
ansible all -m yum -a "name=nginx,git,curl state=present" -b
# 安装指定版本
ansible all -m yum -a "name=nginx-1.18.0 state=present" -b
# 卸载软件包
ansible all -m yum -a "name=nginx state=absent" -b
# 更新所有软件包
ansible all -m yum -a "name=* state=latest" -b
# 从 URL 安装
ansible all -m yum -a "name=https://example.com/package.rpm state=present" -b
service 模块 #
管理服务:
bash
# 启动服务
ansible all -m service -a "name=nginx state=started" -b
# 停止服务
ansible all -m service -a "name=nginx state=stopped" -b
# 重启服务
ansible all -m service -a "name=nginx state=restarted" -b
# 重载配置
ansible all -m service -a "name=nginx state=reloaded" -b
# 开机启动
ansible all -m service -a "name=nginx enabled=yes" -b
# 禁用开机启动
ansible all -m service -a "name=nginx enabled=no" -b
# 启动并设置开机启动
ansible all -m service -a "name=nginx state=started enabled=yes" -b
user 模块 #
管理用户:
bash
# 创建用户
ansible all -m user -a "name=deploy" -b
# 创建用户并设置 shell
ansible all -m user -a "name=deploy shell=/bin/bash" -b
# 创建用户并设置密码
ansible all -m user -a "name=deploy password={{ 'mypassword' | password_hash('sha512') }}" -b
# 创建用户并添加到组
ansible all -m user -a "name=deploy groups=sudo append=yes" -b
# 创建系统用户
ansible all -m user -a "name=appuser system=yes" -b
# 创建用户并指定 home 目录
ansible all -m user -a "name=deploy home=/home/deploy create_home=yes" -b
# 删除用户
ansible all -m user -a "name=deploy state=absent" -b
# 删除用户及其 home 目录
ansible all -m user -a "name=deploy state=absent remove=yes" -b
# 生成 SSH 密钥
ansible all -m user -a "name=deploy generate_ssh_key=yes ssh_key_bits=2048" -b
group 模块 #
管理组:
bash
# 创建组
ansible all -m group -a "name=developers" -b
# 创建组并指定 GID
ansible all -m group -a "name=developers gid=1001" -b
# 创建系统组
ansible all -m group -a "name=appgroup system=yes" -b
# 删除组
ansible all -m group -a "name=developers state=absent" -b
git 模块 #
管理 Git 仓库:
bash
# 克隆仓库
ansible all -m git -a "repo=https://github.com/user/repo.git dest=/var/www/app"
# 克隆指定分支
ansible all -m git -a "repo=https://github.com/user/repo.git dest=/var/www/app version=develop"
# 克隆指定标签
ansible all -m git -a "repo=https://github.com/user/repo.git dest=/var/www/app version=v1.0.0"
# 更新仓库
ansible all -m git -a "repo=https://github.com/user/repo.git dest=/var/www/app update=yes"
# 强制更新
ansible all -m git -a "repo=https://github.com/user/repo.git dest=/var/www/app force=yes"
setup 模块 #
收集主机信息(Facts):
bash
# 收集所有 Facts
ansible all -m setup
# 过滤特定 Facts
ansible all -m setup -a "filter=ansible_eth*"
# 收集内存信息
ansible all -m setup -a "filter=ansible_mem*"
# 收集系统信息
ansible all -m setup -a "filter=ansible_distribution*"
# 收集网络信息
ansible all -m setup -a "filter=ansible_default_ipv4"
# 收集特定子集
ansible all -m setup -a "gather_subset=network"
ansible all -m setup -a "gather_subset=hardware"
ansible all -m setup -a "gather_subset=!all"
debug 模块 #
输出调试信息:
bash
# 输出消息
ansible localhost -m debug -a "msg='Hello Ansible'"
# 输出变量
ansible localhost -m debug -a "var=ansible_facts"
# 输出多个变量
ansible localhost -m debug -a "var=ansible_facts['hostname']"
命令选项 #
连接选项 #
bash
# 指定清单文件
ansible all -m ping -i inventory/hosts
# 指定用户
ansible all -m ping -u admin
# 指定端口
ansible all -m ping -e "ansible_port=2222"
# 指定私钥文件
ansible all -m ping --private-key=~/.ssh/id_rsa
# 指定密码(不推荐)
ansible all -m ping -k
提权选项 #
bash
# 使用 sudo
ansible all -m apt -a "name=nginx state=present" -b
# 指定提权用户
ansible all -m apt -a "name=nginx state=present" -b --become-user=root
# 指定提权方式
ansible all -m apt -a "name=nginx state=present" -b --become-method=sudo
# 交互式输入 sudo 密码
ansible all -m apt -a "name=nginx state=present" -b -K
执行选项 #
bash
# 并发数
ansible all -m ping -f 10
# 详细输出
ansible all -m ping -v
ansible all -m ping -vv
ansible all -m ping -vvv
ansible all -m ping -vvvv
# 检查模式(模拟执行)
ansible all -m copy -a "src=file dest=/tmp/file" --check
# 差异显示
ansible all -m copy -a "src=file dest=/tmp/file" --check --diff
# 超时设置
ansible all -m ping --timeout=30
主机选择 #
bash
# 所有主机
ansible all -m ping
# 特定组
ansible webservers -m ping
# 多个组
ansible webservers:databases -m ping
# 排除组
ansible all:!databases -m ping
# 组交集
ansible 'webservers:&production' -m ping
# 通配符
ansible 'web*' -m ping
# 正则表达式
ansible '~web[0-9]+' -m ping
# 特定主机
ansible web1 -m ping
# 多个主机
ansible web1,web2 -m ping
# 使用序号
ansible webservers[0] -m ping
实用场景 #
快速检查 #
bash
# 检查所有主机连通性
ansible all -m ping
# 检查磁盘空间
ansible all -a "df -h"
# 检查内存使用
ansible all -a "free -m"
# 检查系统负载
ansible all -a "uptime"
# 检查服务状态
ansible all -m shell -a "systemctl status nginx"
# 检查开放端口
ansible all -m shell -a "ss -tlnp"
批量操作 #
bash
# 批量创建目录
ansible all -m file -a "path=/tmp/mydir state=directory"
# 批量复制文件
ansible all -m copy -a "src=config.conf dest=/etc/app/config.conf"
# 批量安装软件
ansible webservers -m apt -a "name=nginx state=present" -b
# 批量重启服务
ansible webservers -m service -a "name=nginx state=restarted" -b
# 批量更新系统
ansible all -m apt -a "update_cache=yes upgrade=dist" -b
信息收集 #
bash
# 收集所有主机信息
ansible all -m setup > facts.json
# 收集特定信息
ansible all -m setup -a "filter=ansible_distribution*" --tree facts/
# 查看主机 IP
ansible all -m setup -a "filter=ansible_default_ipv4"
# 查看主机名
ansible all -m setup -a "filter=ansible_hostname"
# 查看内核版本
ansible all -m setup -a "filter=ansible_kernel"
故障排查 #
bash
# 查看日志
ansible all -m shell -a "tail -100 /var/log/syslog"
# 查看进程
ansible all -m shell -a "ps aux | grep nginx"
# 查看网络连接
ansible all -m shell -a "netstat -tlnp"
# 查看防火墙状态
ansible all -m shell -a "ufw status"
# 测试端口连通性
ansible all -m shell -a "nc -zv 192.168.1.100 80"
输出格式 #
默认输出 #
bash
ansible all -m ping
# 输出
web1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
web2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
JSON 输出 #
bash
ansible all -m ping -o
# 输出
web1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "ping": "pong"}
web2 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "ping": "pong"}
常见问题 #
问题一:命令执行失败 #
bash
# 错误信息
web1 | FAILED | rc=1 >>
/bin/sh: 1: command: not found
# 解决方案
# 检查命令是否存在
ansible web1 -a "which command"
问题二:权限不足 #
bash
# 错误信息
web1 | FAILED! => {
"msg": "Missing sudo password"
}
# 解决方案
# 添加 -b 选项
ansible all -m apt -a "name=nginx state=present" -b -K
问题三:Python 解释器未找到 #
bash
# 错误信息
web1 | FAILED! => {
"msg": "The module failed to execute correctly, you probably need to set the interpreter."
}
# 解决方案
# 指定 Python 解释器
ansible all -m ping -e "ansible_python_interpreter=/usr/bin/python3"
Ad-hoc vs Playbook 选择 #
text
┌─────────────────────────────────────────────────────────────┐
│ 使用场景对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 使用 Ad-hoc 命令 使用 Playbook │
│ ───────────────── ───────────────── │
│ 一次性任务 可重复任务 │
│ 简单操作 复杂逻辑 │
│ 快速检查 正式部署 │
│ 临时调试 生产环境 │
│ 紧急修复 版本控制 │
│ 信息收集 团队协作 │
│ │
└─────────────────────────────────────────────────────────────┘
下一步 #
现在你已经掌握了 Ad-hoc 命令的使用,接下来学习 Playbook 基础 了解如何编写可重复的自动化任务!
最后更新:2026-03-29