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 去执行命令,而是直接调用系统调用。

避坑指南:我曾经在线上用 command 模块执行 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 路径末尾加个斜杠。比如 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"
注意:yum 模块在 CentOS 8 之后被 dnf 模块取代了。如果你用的是 CentOS 8+,建议用 dnf 模块。不过 Ansible 2.8+ 已经做了兼容处理,yum 模块会自动调用 dnf。嗯,这里还是要确认一下你的 Ansible 版本。

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 时,我每用到一个新模块都会先跑一遍 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,少走弯路。下一章见。