3、Ad-Hoc命令实战:Ad-Hoc命令格式、常用模块(command/shell/copy/file/yum/service)、模块帮助文档查看
好,咱们进入第三讲。说实话,很多新手学 Ansible 一上来就奔着 Playbook 去了,结果连 Ad-Hoc 都没玩明白。我个人觉得,Ad-Hoc 才是 Ansible 的「试金石」——你用它跑几个命令,就能立刻感受到 Ansible 的威力。
3.1 什么是 Ad-Hoc 命令?
Ad-Hoc 这个词听起来挺唬人,说白了就是「临时命令」。你不需要写剧本,直接在命令行里敲一条命令,Ansible 就帮你批量执行了。
它的格式很简单:
ansible <主机组> -m <模块名> -a <模块参数>
举个例子:
ansible web -m ping
这条命令的意思是:对 web 组里的所有机器执行 ping 模块。嗯,这里要注意,这个 ping 不是 ICMP 的 ping,而是 Ansible 自己的连通性测试。
我在项目中遇到过一位同事,他死活想不通为什么 ping 不通。后来发现他忘了装 Python……所以,被控端必须要有 Python 2.7+ 或 Python 3.5+,这是前提。
3.2 常用模块实战
Ad-Hoc 能用的模块很多,但日常运维中,真正高频使用的就那么几个。我按使用频率排个序,咱们一个一个过。
3.2.1 command 模块
这是默认模块。如果你不指定 -m,Ansible 默认就用 command。
ansible web -a "uptime"
等价于:
ansible web -m command -a "uptime"
command 模块有个限制:不支持 $HOME、管道、重定向等 shell 特性。为什么会这样?因为它不会通过 shell 去执行命令,而是直接调用系统调用。
cat /proc/cpuinfo | grep processor,结果报错了。后来才反应过来,管道是 shell 的特性,command 模块不认。所以,如果你需要管道、通配符、环境变量,请用 shell 模块。
3.2.2 shell 模块
shell 模块就灵活多了。它通过 /bin/sh 来执行命令,支持所有 shell 特性。
ansible web -m shell -a "free -m | grep Mem"
我个人习惯:能用 command 就用 command,实在不行再上 shell。因为 shell 模块会多一层进程开销,而且存在注入风险。你想想看,如果 -a 参数里拼接了用户输入,那可就危险了。
3.2.3 copy 模块
批量分发文件,这是运维的日常。copy 模块就是干这个的。
ansible web -m copy -a "src=/etc/hosts dest=/etc/hosts owner=root group=root mode=0644"
这里有几个参数要注意:
- src:源文件路径,可以是相对路径或绝对路径
- dest:目标路径,必须是绝对路径
- owner/group:文件属主和属组
- mode:权限,可以用 0644 这种数字格式
src=/tmp/config/ 只会复制 config 目录里的文件,而 src=/tmp/config 会连 config 目录一起复制过去。这个坑我踩过两次,印象特别深。
3.2.4 file 模块
file 模块用来管理文件属性、创建目录、创建软链接等。
创建目录:
ansible web -m file -a "path=/data/logs state=directory mode=0755"
创建软链接:
ansible web -m file -a "src=/usr/local/nginx/conf/nginx.conf dest=/etc/nginx/nginx.conf state=link"
删除文件:
ansible web -m file -a "path=/tmp/old.log state=absent"
state 参数有四个常用值:
| state 值 | 作用 |
|---|---|
| directory | 创建目录,如果父目录不存在也会创建 |
| file | 检查文件是否存在,不存在不会创建 |
| link | 创建软链接 |
| absent | 删除文件或目录 |
3.2.5 yum 模块
yum 模块用来管理 RHEL/CentOS 上的软件包。说实话,这个模块我用的频率非常高,因为新机器初始化时总要装一堆包。
ansible web -m yum -a "name=nginx state=present"
state 参数:
- present:安装(如果已安装则跳过)
- latest:安装或升级到最新版
- absent:卸载
批量安装多个包:
ansible web -m yum -a "name=nginx,php-fpm,mysql-server state=present"
3.2.6 service 模块
管理服务的启动、停止、重启、开机自启。
ansible web -m service -a "name=nginx state=started enabled=yes"
常用参数:
- name:服务名
- state:started、stopped、restarted、reloaded
- enabled:yes/no,设置开机自启
我记得有一次线上紧急更新配置,需要重启 Nginx。我直接一条 Ad-Hoc 搞定:
ansible web -m service -a "name=nginx state=restarted"
20 台机器,3 秒全部重启完成。这就是 Ansible 的魅力。
3.3 模块帮助文档查看
Ansible 的模块太多了,没人能全记住。我自己的做法是:记住常用的,其他的现查。
查看所有可用模块:
ansible-doc -l
查看某个模块的详细帮助:
ansible-doc copy
这会输出 copy 模块的完整文档,包括参数说明、示例、注意事项。我个人习惯用 ansible-doc -s copy 查看精简版:
ansible-doc -s copy
输出格式类似这样:
action: copy
backup (False) 备份目标文件
content (None) 直接写入内容,替代 src
dest (required) 目标路径
directory_mode (None) 目录权限
follow (False) 是否跟随软链接
force (True) 是否强制覆盖
group (None) 属组
mode (None) 权限
owner (None) 属主
src (None) 源路径
validate (None) 校验命令
ansible-doc -s,看看有哪些参数。这样用上几次就记住了。别指望一次性背下所有参数,那不现实。
3.4 综合实战:一条命令完成服务部署
咱们来一个综合案例。假设你要在 web 组的所有机器上部署 Nginx:
# 1. 安装 Nginx
ansible web -m yum -a "name=nginx state=present"
# 2. 分发配置文件
ansible web -m copy -a "src=./nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644"
# 3. 创建日志目录
ansible web -m file -a "path=/var/log/nginx state=directory mode=0755"
# 4. 启动服务并设置开机自启
ansible web -m service -a "name=nginx state=started enabled=yes"
# 5. 验证服务状态
ansible web -m shell -a "curl -s -o /dev/null -w '%{http_code}' http://localhost"
你看,5 条命令,一个完整的 Nginx 部署就完成了。这就是 Ad-Hoc 的威力——简单、直接、高效。
不过我也要提醒你:Ad-Hoc 适合临时任务和快速验证。如果这个部署流程你要反复执行,或者要分享给团队,那就应该写成 Playbook。下一章咱们就讲 Playbook,到时候你会看到,同样的功能,Playbook 写出来更清晰、更可复用。
好,这一章就到这里。记住我说的:多用 ansible-doc,少走弯路。下一章见。