目录
一.Ansible简介
什么是Ansible?
-
ansible是新出现的自动化运维工具,基于python开发,集合了很多的运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
-
ansible是基于paramiko开发的,并且基于模块化工作,它本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架,ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。ansible目前已经被红帽官方收购,是自动化运维工具认可度最高的。
-
更加详细的资源参考官方文档,如右是Ansible的官方网站:Ansible Documentation
Ansible的特点
-
部署简单,只需要在主控端部署Ansible环境,被控端无需做任何操作;
-
默认使用SSH协议对设备进行管理;
-
有大量的常规运维操作模块,可实现日常绝大部分的操作;
-
配置简单、功能强大、扩展性强;
-
支持API以及自定义模块,可以通过Python轻松扩展;
-
通过Playbooks来定制强大的配置、状态管理;
-
轻量级、无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
-
提供一个功能强大、操作性强的web管理界面和REST API接口——AWX平台。
Ansible的架构
-
Ansible:Ansible的核心程序
-
HostInventory:记录有Ansible管理的主机信息,包括端口、密码、IP地址等
-
Playbooks:“剧本”YAML格式的文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
-
CoreModules:核心模块,主要操作是通过调用核心模块来完成管理任务
-
CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
-
ConnectionPlugins:连接插件,Ansible和Host通信使用
二、Ansible任务执行解析
-
ansible系统由控制主机被管节点的操作方式可以分为两类,即adhoc和playbook
-
ad-hoc模式(点对点模式)
使用单个模块,支持批量执行单条命令。
ad-hoc命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell
-
playbook模式(剧本模式)
剧本模式是Ansible的主要管理方式,也是Ansible功能强大的关键所在。
playbook通过多个task(任务)集合完成一类功能,比如web服务的安装部署、数据库服务的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件
ansible执行流程
-
简单理解就是Ansible在运行时,首先读取ansible.cfg中的配置,根据规则获取Inventory中的管理主机列表,并行的在这些主机中执行配置的任务,最后等待执行返回结果。
ansible命令执行过程(背会)
-
加载自己的配置文件,默认为/etc/ansible/ansible.cfg;
-
查找对应的主机配置文件,找到要执行的主机或者组;
-
加载自己对应的模块文件,如command;
-
通过ansible将模块或者命令生成对应的py文件(python脚本),并且将该文件传输到远程服务器;
-
对应执行用户的家目录.ansible/tmp/xxx/xxx.py文件;
-
给文件添加执行权限;
-
执行并且返回结果;
-
删除临时的py文件, sleep 0退出;
三、Ansible配置解析
ansible的安装方式
-
ansible安装常用两种方式,yum安装和pip程序安装。
使用pip(python的包管理模块)安装
-
首先,我们需要安装python-pip包,安装完成之后,则直接使用pip命令来安装我们的包,具体操作过程如下:
-
适用于所有的操作系统
yum install python-pip
pip install ansible
使用yum安装
-
yum安装是我们比较熟悉的安装方式。我们需要先安装一个epel-release包,然后再安装ansible即可。
yum install epel-release -y
yum install ansible -y
ansible的程序结构(yum安装为例)
-
配置文件目录:/etc/ansible/
-
执行文件目录:/usr/bin/
-
Lib库依赖目录:/usr/lib/pyhtonX.X/site-packages/ansible/
-
Help文档目录:/usr/share/doc/ansible-X.X.X/
-
Man文档目录:/usr/share/man/man1/
ansible的配置文件查找顺序(背会)
-
ansible与我们其他的服务在这一点上又很大的不同,这里的配置文件查找是从多个地方找的,顺序如下:
1、检查环境变量 ANSIBLE_CONFIG 指向的路径文件(export ANSIBLE_CONFIG=/etc/ansible/ansible.cfg);
2、~/.ansible.cfg,检查当前目录下的ansible.cfg配置文件;
3、/etc/ansible.cfg检查etc目录的配置文件。
ansible的配置文件
ansible的配置文件路径是/etc/ansible/ansible.cfg
打开ansible文件将里面ansible-config init --disabled -t all > ansible.cfg复制到终端,生成一个完整的ansible文档
[root@anisble ansible]# ansible-config init --disabled -t all > ansible.cfg
inventory = /etc/ansible/hoste #这个参数表示资源清单inventory文件的位置
library = /usr/share/ansible #指向存放ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就行。
fbrks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户 ,2.14版本中是:become_user=root
remote_port = 22 #指定连接被管理节点的端口,默认为22端口,为安全考虑,建议修改
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False,关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.cfg #指定一个存储ansible日志的文件(默认不记录日志)
ansible的主机清单
-
在配置文件中,我们提到了资源清单,这个清单就是主机清单,里面保存的是一些ansible需要连接管理的主机列表。
-
如下是ansible主机清单的定义方式:
1.直接指明主机地址或者主机名:
#green.example.com#
#bule.example.com#
# 192.168.115.101
# 192.168.115.102
2.定义一个主机组(组名)把地址或者主机名加进去
[mysql_test]
192.168.115.101
192.168.115.102
192.168.115.103
-
需要注意的是,这里的组成员可以使用通配符来匹配,这样对于一些标准化管理就比较方便。我们可以根据实际情况来配置我们的主机列表,具体的操作如下:
vim /etc/ansible/hosts
[webs]
192.168.80.168
192.168.80.169
四、Ansible常用命令
五、部署ansible管理集群
环境部署
主机名 | IP地址 | 安装包 |
ansible | 192.168.80.153 | epel-release、ansible |
node1 | 192.168.80.168 | - |
node2 | 192.168.80.169 | - |
实验步骤
1、安装ansible
[root@localhost ~]# hostnamectl set-hostname ansible
[root@localhost ~]# bash
[root@ansible ~]# yum install epel-release -y
[root@ansible ~]# yum install ansible -y
2、添加主机清单
[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ls
ansible.cfg hosts roles
[root@ansible ansible]# vi hosts
[webs] ##添加到最后一行
192.168.80.168
192.168.80.169
3、配置公私钥
[root@anisble ansible]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:0PhSCo0j4dlL4fQRv8//JUqUaab5DUr2hbzpO5tCMhw root@anisble
The key's randomart image is:
+---[RSA 3072]----+
| . o o. |
| . * = = |
| + B = + |
| o + =E. o |
| . o.S. * |
| .+o.B . |
| +B = o .|
| o.*.O o |
| .o%=o |
+----[SHA256]-----+
###将密钥拷给另外的两台主机
[root@anisble ansible]# ssh-copy-id 192.168.80.168
[root@anisble ansible]# ssh-copy-id 192.168.80.169
六、Ansible常用模块
一、系统工具模块
1、ping主机连通性测试
-
使用下列命令对主机清单中的资源进行连通性测试,出现下列信息说明主机处于连通状态
#ansible 主机清单组名 -m(指定模块名字)
[root@anisble ansible]# ansible webs -m ping
192.168.80.169 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.80.168 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
二、系统管理模块
1、hostname模块 管理主机名
[root@anisble ~]# ansible webs -m hostname -a 'name=web1'
2、user模块
1. 核心参数说明
参数 | 说明 | 示例值 |
---|---|---|
name | 必填:指定用户名 | name=nginx |
state | 用户状态 | present (创建/更新,默认)、absent (删除) |
comment | 用户描述信息(GECOS字段) | comment="Nginx Service Account" |
createhome | 是否创建家目录 | yes (默认)、no |
force | 删除用户时强制删除(类似 userdel --force ) | yes 或 no (默认) |
group | 指定基本组(主组) | group=www-data |
groups | 指定附加组(需用逗号分隔) | groups="docker,nginx" |
home | 指定家目录路径 | home=/var/nginx |
move_home | 移动家目录到新位置(需配合 home= 使用) | move_home=yes |
non_unique | 允许修改非唯一 UID(谨慎使用) | yes 或 no (默认) |
password | 设置用户密码(需密文格式) openssl passwd -1 “密码” | `password="{{ 'password' |
remove | 删除用户时同时删除家目录和邮件池(类似 userdel --remove ) | yes 或 no (默认) |
shell | 指定默认 Shell | shell=/sbin/nologin |
system | 创建系统用户(UID < 1000) | yes 或 no (默认) |
uid | 指定用户 UID | uid=1001 |
2、案例
2.1、添加用户 “user” name= password
先生成一个MD5的密文密码,添加用户然后指定密码
[root@anisble ~]# openssl passwd -1 '123'
$1$0cru1o0O$5ZfPxdBucJ3VrJV66LNDT0
[root@anisble ~]# ansible webs -m user -a 'name=hou password=$1$0cru1o0O$5ZfPxdBucJ3VrJV66LNDT0'
######查看用户是否创建成功
[root@anisble ~]# ansible webs -m shell -a 'ls -l /home'
192.168.80.169 | CHANGED | rc=0 >>
总用量 4
drwx------. 3 hou hou 78 7月 27 11:43 hou
drwx------. 15 user user 4096 5月 11 01:01 user
192.168.80.168 | CHANGED | rc=0 >>
总用量 4
drwx------. 3 hou hou 78 7月 27 11:43 hou
drwx------. 15 user user 4096 5月 11 01:01 user
[root@anisble ~]# ansible webs -m shell -a 'cat /etc/passwd | grep hou'
192.168.80.168 | CHANGED | rc=0 >>
hou:x:1001:1001::/home/hou:/bin/bash
192.168.80.169 | CHANGED | rc=0 >>
hou:x:1001:1001::/home/hou:/bin/bash
2.2、删除用户 state=absent 保留家目录和邮件
[root@anisble ~]# ansible webs -m user -a 'name=hou state=absent'
[root@anisble ~]# ansible webs -m shell -a 'cat /etc/passwd | grep hou'
192.168.80.169 | FAILED | rc=1 >>
non-zero return code
192.168.80.168 | FAILED | rc=1 >>
non-zero return code
彻底删除用户hou
[root@anisble ~]# ansible webs -m user -a 'name=hou state=absent remove=yes force=yes'
2.3、创建一个系统用户nginx,不创建家目录
ansible webs -m user -a 'name=nginx system=yes createhome=no'
2.4、创建一个名为hou的用户,指定基本组合附加组为user,并指定shell为/bin/bash
nasible webs -m hou -a 'name=hou group=user groups=user shell=/bin/bash'
2.5、将用户alice 家目录迁移到/data/alice
ansible wbes -m user -a 'name=alice home=/data/alice move_home=yes'
总结
场景 | 推荐参数组合 |
---|---|
创建普通用户 | name=用户名 state=present comment="描述" createhome=yes shell=/sbin/nologin |
创建系统用户 | name=用户名 system=yes shell=/sbin/nologin state=present |
添加附加组 | name=用户名 groups="组1,组2" append=yes state=present |
删除用户 | name=用户名 state=absent remove=yes |
设置密码 | `name=用户名 password="{{ '密码' |
3、group模块
- group模块主要用于添加或者删除组,常用选项如下所示:
gid= 设置组的GID号
- name= 指定组的名称
- state= 指定组的状态,默认为创建,设置值为absent为删除
- system= 设置值为yes,表示创建为系统组
###[root@anisble ~]# ansible webs -m group -a 'name=hou gid=3333'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 3333,
"name": "hou",
"state": "present",
"system": false
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 3333,
"name": "hou",
"state": "present",
"system": false
}#创建组
####查看组
[root@anisble ~]# ansible webs -m shell -a 'cat /etc/group | grep 3333'
192.168.80.169 | CHANGED | rc=0 >>
hou:x:3333:
192.168.80.168 | CHANGED | rc=0 >>
hou:x:3333:
####删除组
[root@anisble ~]# ansible webs -m group -a 'name=hou state=absent'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "hou",
"state": "absent"
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "hou",
"state": "absent"
4、cron模块
cron模块用于管理crontab计划性任务的,它的语法和crontab中的语法一致
1、主要参数说明
参数 | 说明 | 示例 |
---|---|---|
day | 指定任务在每月的哪几天运行(1-31,* 表示每天,*/2 表示每两天) | day=1 (每月1号) |
hour | 指定任务在每天的哪些小时运行(0-23,* 表示每小时) | hour=2 (凌晨2点) |
minute | 指定任务在每小时的哪些分钟运行(0-59,* 表示每分钟) | minute=30 (每小时的30分) |
month | 指定任务在每年的哪些月份运行(1-12,* 表示每月) | month=1 (1月) |
weekday | 指定任务在一周的哪些天运行(0-6,0 表示周日,* 表示每天) | weekday=0 (每周日) |
job | 要执行的命令或脚本 | job="/path/to/script.sh" |
name | 定时任务的描述(用于标识任务,删除时需匹配此名称) | name="Backup Database" |
reboot | 任务在系统重启时运行(不推荐使用,建议用 special_time 替代) | reboot=yes |
special_time | 特殊时间范围,支持预定义的时间点 | special_time=daily (每天运行) |
state | 指定任务状态 | state=present (添加任务,默认值)state=absent (删除任务) |
user | 以哪个用户的身份执行任务 | user=root |
2、 特殊时间范围 (special_time
)
special_time
提供了一组预定义的时间点,比直接使用 day
、hour
等参数更简洁:
参数值 | 含义 |
---|---|
reboot | 系统重启时运行(不推荐,建议用 systemd 服务替代) |
annually | 每年运行一次(相当于 0 0 1 1 * ) |
monthly | 每月运行一次(相当于 0 0 1 * * ) |
weekly | 每周运行一次(相当于 0 0 * * 0 ) |
daily | 每天运行一次(相当于 0 0 * * * ) |
hourly | 每小时运行一次(相当于 0 * * * * ) |
3、案例
3.1、设置一个每 5 分钟就运行一次ifconfig
命令的定时任务
[root@anisble ~]# ansible webs -m cron -a 'name="ifconfig every 5 min" minute=*/5 job="/sbin/ifconfig"'
查看添加的定时任务
[root@anisble ~]# ansible webs -m shell -a 'crontab -l'
192.168.80.168 | CHANGED | rc=0 >>
#Ansible: ifconfig every 5 min
*/5 * * * * /sbin/ifconfig
192.168.80.169 | CHANGED | rc=0 >>
#Ansible: ifconfig every 5 min
*/5 * * * * /sbin/ifconfig
3.2、添加一个在每周日晚上 10 点进行数据备份的任务
[root@anisble ~]# ansible webs -m cron -a 'name="weekly data backup" weekday=0 hour=22 job="/scripts/backup.sh"'
3.3、删除计划性任务
删除之前先查看一下,已有的计划任务
[root@anisble ~]# ansible webs -m shell -a 'crontab -l'
192.168.80.169 | CHANGED | rc=0 >>
#Ansible: ifconfig every 5 min
*/5 * * * * /sbin/ifconfig
#Ansible: weekly data backup
* 22 * * 0 /scripts/backup.sh
192.168.80.168 | CHANGED | rc=0 >>
#Ansible: ifconfig every 5 min
*/5 * * * * /sbin/ifconfig
#Ansible: weekly data backup
* 22 * * 0 /scripts/backup.sh
######准备删除计划性任务
[root@anisble ~]# ansible webs -m cron -a 'name="weekly data backup" weekday=0 hour=22 job="/scripts/backup.sh" state=absent'
[root@anisble ~]# ansible webs -m cron -a 'name="ifconfig every 5 min" minute=*/5 job="/sbin/ifconfig" state=absent'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
######查看定时任务
[root@anisble ~]# ansible webs -m shell -a 'crontab -l'
192.168.80.169 | CHANGED | rc=0 >>
192.168.80.168 | CHANGED | rc=0 >>
3.4、采用特殊时间设置
使用special_time参数可以简化常见时间间隔的设置
[root@anisble ~]# ansible webs -m cron -a 'name="hourly log cleanup" special_time=hourly job="/scripts/clean_logs.sh"'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"hourly log cleanup"
]
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"hourly log cleanup"
]
}
3.5、以特定用户身份执行任务
# 以nginx用户的身份,每15分钟检查一次服务状态
[root@anisble ~]# ansible webs -m cron -a 'name="check nginx status" minute=*/15 user=nginx job="systemctl status nginx"'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"check nginx status"
]
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"check nginx status"
]
}
3.6、设置多个时间值
每月1日早上8点和晚上20.00查看firewalld状态
[root@anisble ~]# ansible webs -m cron -a 'name="firewalld status" hour="8,20" month=1 job="systemctl status firewalld"'192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"hourly log cleanup",
"firewalld status"
]
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"hourly log cleanup",
"firewalld status"
]
}
注意要点
路径问题:要保证job
中命令的路径是完整的,或者在执行前先设定好环境变量
输出处理:建议将命令的输出重定向,防止邮件堆积
job="/scripts/backup.sh >/dev/null 2>&1"
任务唯一性:name参数在同一用户的 crontab 中必须是唯一的,不然可能会覆盖已有的任务
5、reboot模块 重启主机
-
reboot_timeout: 等待计算机重新启动并响应测试命令的最长秒数,默认为600S
ansible webs -m reboot -a 'reboot_timeout=180'
-
test_command: 重启后测试命令,默认为“whoami”
ansible webs -m reboot -a 'test_command="systemctl status nginx"'
-
msg:重启前提示用户的消息,默认为“Reboot initiated by Ansible”
ansible webs -m reboot -a 'msg="系统将在5分钟后重启,请做好准备!"'
6、service模块
-
name(required): 设置启停服务名称
-
enabled: 设置服务是否开机自启动,可选项yes/no;如果参数不指定,原有服务开机自启动状态进行保留
-
sleep: 如果执行了restarted,则在stop和start之间沉睡几秒钟
-
state: 需要对当前服务执行的动作,可选项reloaded(平滑重启),restarted(重启),started(启动),stopped(停止)
1、启动并启用命令
# 启动 nginx 并设置为开机自启
ansible webs -m service -a 'name=nginx state=started enabled=yes'
2、停止并禁用命令
# 关闭 firewalld 并设置为开机关闭
ansible all -b -m service -a 'name=firewalld state=stoped enabled=no'
3、重启或重载服务
# 重启 nginx(适用于配置变更后)
ansible web -b -m service -a 'name=nginx state=restarted'
# 平滑重启 nginx(不中断现有连接)
ansible web -b -m service -a 'name=nginx state=reloaded'
4、带延迟的重启
# 重启 mysql 并在停止和启动之间等待 5 秒
ansible db -b -m service -a 'name=mysqld state=restarted sleep=5'
三、执行命令模块
1、command模块
1、command模块可以直接在远程主机上执行命令,并且结果返回打印出来,举例如下:
[root@anisble ansible]# ansible webs -m command -a 'date'
192.168.80.168 | CHANGED | rc=0 >>
2025年 07月 26日 星期六 11:36:00 CST
192.168.80.169 | CHANGED | rc=0 >>
2025年 07月 26日 星期六 11:36:00 CST
2、命令模块接受命令名称,后面是空格分隔的列表参数。给定的命令将在所有选定的节点上执行,它不会通过shell进行处理,比如$HOME和操作如“<”,">"," | ", " ; " ," & " (需要使用 shell模块实现这些功能)。注意,command模块不支持 | 管道命令
3、command常用命令
-
chdir:在执行命令之前,先切换到该目录
###使用chdir切换到/home/目录
在远程主机的 /home 目录下执行 ls -l 命令
[root@anisble ansible]# ansible webs -m command -a 'chdir=/home/ ls -l'
192.168.80.169 | CHANGED | rc=0 >>
总用量 4
drwx------. 15 user user 4096 5月 11 01:01 user
192.168.80.168 | CHANGED | rc=0 >>
总用量 4
drwx------. 15 user user 4096 5月 11 01:01 user
-
execurable:切换shell来执行命令,需要使用命令的绝对路径
#####使用 /bin/bash 执行 echo $SHELL 命令,可以获取远程主机的默认 shell
[root@anisble ansible]# ansible all -m command -a "executable=/bin/bash echo $SHELL"
[WARNING]: As of Ansible 2.4, the parameter 'executable' is no longer supported
with the 'command' module. Not using '/bin/bash'.
192.168.80.168 | CHANGED | rc=0 >>
/bin/bash
192.168.80.169 | CHANGED | rc=0 >>
/bin/bash
[root@anisble ansible]# ansible all -m command -a "executable=/bin/bash date"
[WARNING]: As of Ansible 2.4, the parameter 'executable' is no longer supported
with the 'command' module. Not using '/bin/bash'.
192.168.80.168 | CHANGED | rc=0 >>
2025年 07月 26日 星期六 12:23:38 CST
192.168.80.169 | CHANGED | rc=0 >>
2025年 07月 26日 星期六 12:23:38 CST
-
free_form:要执行的Linux指令,一般使用Ansible的-a参数代替
[root@anisble ansible]# ansible all -m command -a 'uptime'
192.168.80.169 | CHANGED | rc=0 >>
12:25:53 up 3:57, 4 users, load average: 0.00, 0.01, 0.05
192.168.80.168 | CHANGED | rc=0 >>
12:25:53 up 3:11, 4 users, load average: 0.01, 0.02, 0.05
-
creates:一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
[root@anisble ansible]# ansible all -m command -a 'creates=/root/1.txt cat /root/1.txt'
192.168.80.168 | SUCCESS | rc=0 >>
skipped, since /root/1.txt existsDid not run command since '/root/1.txt' exists
192.168.80.169 | SUCCESS | rc=0 >>
skipped, since /root/1.txt existsDid not run command since '/root/1.txt' exists
命令被跳过:
Ansible 在目标主机 192.168.80.168 和 192.168.80.169 上检测到 /root/1.txt 文件已存在。
由于 creates=/root/1.txt 参数的存在,Ansible 跳过了 cat /root/1.txt 命令的执行(因为文件已存在,无需执行)。
返回状态:
SUCCESS:表示 Ansible 任务执行成功(虽然命令被跳过,但这是预期的行为)。
rc=0:返回码为 0,表示没有错误(跳过命令也是成功的一种状态)
-
removes:一个文件名,这个文件不存在,则该命令不执行
##使用removes,如果/root/1.txt存在,就执行cat /root/1.txt
[root@anisble ansible]# ansible all -m command -a 'removes=/root/1.txt cat /root/1.txt'
192.168.80.169 | SUCCESS | rc=0 >>
skipped, since /root/1.txt does not existDid not run command since '/root/1.txt' does not exist
192.168.80.168 | CHANGED | rc=0 >>
123456
2、shell模块
-
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等
-
只要是shell命令都可以在通过这个模块在远程主机里面运行
[root@anisble ansible]# ansible webs -m shell -a 'cat /root/2.txt | grep "^a"'
192.168.80.169 | CHANGED | rc=0 >>
aa
ag
192.168.80.168 | CHANGED | rc=0 >>
aa
ag
3、script模块
script
模块用于在远程主机上执行本地(控制节点)上的脚本文件,无需将脚本预先上传到远程主机。它会自动将脚本传输到远程主机并执行,执行完成后自动删除脚本文件(类似 cat script | ssh host bash
的效果)
1.1、在服务主机上 创建一个脚本,一定要给脚本赋权
[root@anisble ~]# cat disk.sh
#!/bin/bash
df -Th
[root@anisble ~]# chmod +x disk.sh
2.2、运行这个脚本于被管理端
[root@anisble ~]# ansible webs -m script -a '/root/disk.sh'
192.168.80.169 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.80.169 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.80.169 closed."
],
"stdout": "文件系统 类型 容量 已用 可用 已用% 挂载点\r\ndevtmpfs devtmpfs 894M 0 894M 0% /dev\r\ntmpfs tmpfs 910M 0 910M 0% /dev/shm\r\ntmpfs tmpfs 910M 11M 900M 2% /run\r\ntmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup\r\n/dev/mapper/centos-root xfs 39G 5.3G 33G 14% /\r\n/dev/sda1 xfs 1014M 185M 830M 19% /boot\r\n/dev/mapper/centos-home xfs 19G 38M 19G 1% /home\r\ntmpfs tmpfs 182M 36K 182M 1% /run/user/0\r\n",
"stdout_lines": [
"文件系统 类型 容量 已用 可用 已用% 挂载点",
"devtmpfs devtmpfs 894M 0 894M 0% /dev",
"tmpfs tmpfs 910M 0 910M 0% /dev/shm",
"tmpfs tmpfs 910M 11M 900M 2% /run",
"tmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup",
"/dev/mapper/centos-root xfs 39G 5.3G 33G 14% /",
"/dev/sda1 xfs 1014M 185M 830M 19% /boot",
"/dev/mapper/centos-home xfs 19G 38M 19G 1% /home",
"tmpfs tmpfs 182M 36K 182M 1% /run/user/0"
]
}
192.168.80.168 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.80.168 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.80.168 closed."
],
"stdout": "文件系统 类型 容量 已用 可用 已用% 挂载点\r\ndevtmpfs devtmpfs 894M 0 894M 0% /dev\r\ntmpfs tmpfs 910M 0 910M 0% /dev/shm\r\ntmpfs tmpfs 910M 11M 900M 2% /run\r\ntmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup\r\n/dev/mapper/centos-root xfs 39G 5.3G 33G 14% /\r\n/dev/sda1 xfs 1014M 185M 830M 19% /boot\r\n/dev/mapper/centos-home xfs 19G 38M 19G 1% /home\r\ntmpfs tmpfs 182M 36K 182M 1% /run/user/0\r\n",
"stdout_lines": [
"文件系统 类型 容量 已用 可用 已用% 挂载点",
"devtmpfs devtmpfs 894M 0 894M 0% /dev",
"tmpfs tmpfs 910M 0 910M 0% /dev/shm",
"tmpfs tmpfs 910M 11M 900M 2% /run",
"tmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup",
"/dev/mapper/centos-root xfs 39G 5.3G 33G 14% /",
"/dev/sda1 xfs 1014M 185M 830M 19% /boot",
"/dev/mapper/centos-home xfs 19G 38M 19G 1% /home",
"tmpfs tmpfs 182M 36K 182M 1% /run/user/0"
]
}
四、文件操作模块
1、file模块
一、命令
1、file模块主要用于设置文件的属性,比如创建文件、创建连接文件、删除文件等,如下为常见的命令:
-
force:需要两种情况下强制创建软连接,一种是源文件不存在,但是之后会建立的情况下;另外一种是目标软链接已存在,需要取消之前的软链接,然后创建新的,有两个选项:yes|no。
-
path:指定创建路径
2、group:定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限。
3、owner:定义文件/目录的属主,后面必须加上path:定义文件/目录的路径。
4、recurse:递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
5、dest:被链接到的路径,只应用于state=link的情况
6、mode:指定权限。
7、state:状态,有如下选项:
-
directory:如果目录不存在,就创建目录
-
file:即使文件不存在,也不会被创建;已经存在的文件可以修改文件的属性。
-
link:创建软链接
-
hard:创建硬链接
-
touch:如果文件不存在,则会创建一个新的文件,如果文件或者目录已经存在,则更新其最后修改时间
-
absent:删除目录、文件或者取消链接文件
二、案例
1、创建目录:ansible webs -m file -a 'path=/root/d1 state=directory'
[root@anisble ~]# ansible webs -m file -a 'path=/root/d1 state=directory'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/d1",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/d1",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/'
192.168.80.168 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x. 2 root root 6 7月 26 15:53 d1
192.168.80.169 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x. 2 root root 6 7月 26 15:53 d1
2、创建空文件 state=touch
[root@anisble ~]# ansible all -m file -a 'path=/root/d1/f1 state=touch mode=0644'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
3、创建软连接
[root@anisble ~]# ansible all -m file -a 'path=/root/d1/f2 src=/root/3.txt state=link'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f2",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 11,
"src": "/root/3.txt",
"state": "link",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f2",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 11,
"src": "/root/3.txt",
"state": "link",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/d1/'
192.168.80.168 | CHANGED | rc=0 >>
总用量 0
-rw-r--r--. 1 root root 0 7月 26 16:29 f1
lrwxrwxrwx. 1 root root 11 7月 26 16:45 f2 -> /root/3.txt
192.168.80.169 | CHANGED | rc=0 >>
总用量 0
-rw-r--r--. 1 root root 0 7月 26 16:29 f1
lrwxrwxrwx. 1 root root 11 7月 26 16:45 f2 -> /root/3.txt
强制创建软连接 force=yes
强制创建软链接,即使源文件不存在或目标软链接已存在
[root@anisble ~]# ansible all -m file -a 'path=/root/d1/f1 src=/root/3.txt state=link force=yes'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f1",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 11,
"src": "/root/3.txt",
"state": "link",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f1",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 11,
"src": "/root/3.txt",
"state": "link",
"uid": 0
}
创建硬链接
- 硬链接与源文件共享 inode,删除源文件不会影响硬链接
- 要求源文件和目标路径必须在同一文件系统
[root@anisble ~]# ansible all -m file -a 'path=/root/d1/f3 src=/root/2.txt state=hard'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f3",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 218,
"src": "/root/2.txt",
"state": "hard",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f3",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 109,
"src": "/root/2.txt",
"state": "hard",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/d1/'
192.168.80.169 | CHANGED | rc=0 >>
总用量 4
lrwxrwxrwx. 1 root root 11 7月 26 16:52 f1 -> /root/3.txt
lrwxrwxrwx. 1 root root 11 7月 26 16:53 f2 -> /root/3.txt
-rw-r--r--. 2 root root 109 7月 26 14:17 f3
192.168.80.168 | CHANGED | rc=0 >>
总用量 4
lrwxrwxrwx. 1 root root 11 7月 26 16:52 f1 -> /root/3.txt
lrwxrwxrwx. 1 root root 11 7月 26 16:53 f2 -> /root/3.txt
-rw-r--r--. 2 root root 218 7月 26 14:37 f3
4、删除文件 state=absent
删除远程主机上的 /root/d1
目录及其内容
- 递归删除目录及其所有内容(类似
rm -rf
) - 也可用于删除单个文件
[root@anisble ~]# ansible all -m file -a 'path=/root/d1/f2 state=absent'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/root/d1/f2",
"state": "absent"
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/root/d1/f2",
"state": "absent"
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/d1/'
192.168.80.168 | CHANGED | rc=0 >>
总用量 0
-rw-r--r--. 1 root root 0 7月 26 16:29 f1
192.168.80.169 | CHANGED | rc=0 >>
总用量 0
-rw-r--r--. 1 root root 0 7月 26 16:29 f1
5、更新文件时间戳 state=touch
更新最后修改的时间(如果文件不存在则创建)
[root@anisble ~]# ansible webs -m file -a 'path=/root/d1/f3 state=touch'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f3",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 218,
"state": "hard",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/d1/f3",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 109,
"state": "hard",
"uid": 0
}
6、递归设置目录属性 recurse=yes
[root@anisble ~]# ansible webs -m file -a "path=/root/d2 state=directory recurse=yes owner=user group=user mode=644"
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/'
drw-r--r--. 2 user user 6 7月 26 17:08 d2
三、总结
需求 | 关键参数 | 示例 |
---|---|---|
创建目录 | state=directory , mode , owner | path=/tmp/dir mode=0755 owner=root |
创建空文件 | state=file , mode | path=/tmp/file mode=0644 |
创建软链接 | state=link , src , dest | src=/tmp/file dest=/tmp/link |
强制创建软链接 | force=yes | src=/tmp/file dest=/tmp/link force=yes |
创建硬链接 | state=hard , src , dest | src=/tmp/file dest=/tmp/hardlink |
删除文件/目录 | state=absent | path=/tmp/file |
更新时间戳 | state=touch | path=/tmp/file |
递归设置属性 | recurse=yes | path=/tmp/dir recurse=yes |
2、copy模块
这个模块用于将文件复制到远程主机上,同时支持给定的内容生成文件和修改权限等
copy模块的相关选项如下:
1、src:被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于“rsync”
将本机上的/root目录下的3.txt,复制到两台主机的/root目录
[root@anisble ~]# ansible webs -m copy -a 'src=/root/3.txt dest=/root/'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1753511046.4245057-30551-249516453564482/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1753511046.4429803-30552-131816824168726/source",
"state": "file",
"uid": 0
}
2、content:用于替换“src”,可以直接指定文件的值。
直接指定文件内容(无需本地文件)
直接在命令中定义文件内容,而非从本地文件复制
[root@anisble ~]# ansible webs -m copy -a 'content="hello" dest=/root/3.txt'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "5d41402abc4b2a76b9719d911017c592",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1753511858.0483968-32304-46404553395369/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "5d41402abc4b2a76b9719d911017c592",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1753511858.0534246-32305-17091836345056/source",
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'cat /root/3.txt'
192.168.80.168 | CHANGED | rc=0 >>
hello
192.168.80.169 | CHANGED | rc=0 >>
hello
3、dest:必选项,将源文件复制到远程主机的绝对路径
4、backup:当文件内容发生改变之后,在覆盖之前,把源文件备份,备份文件包含时间信息
创建新的内容覆盖原文件,并且备份
备份的文件会有一个时间戳 3.txt.79128.2025-07-26@14:53:56~
[root@anisble ~]# ansible webs -m copy -a 'content="welcome home" backup=yes dest=/root/3.txt mode=777'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/root/3.txt.75319.2025-07-26@14:53:56~",
"changed": true,
"checksum": "1b960841f3032dc23395fbea1de2a5ffbeb9eed3",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "0c23e8bdb5deeb5de02ab6d2512a7466",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1753512835.9570413-34542-148904457470458/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/root/3.txt.79128.2025-07-26@14:53:56~",
"changed": true,
"checksum": "1b960841f3032dc23395fbea1de2a5ffbeb9eed3",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "0c23e8bdb5deeb5de02ab6d2512a7466",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1753512835.9574084-34543-7949904556553/source",
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/3.txt'
192.168.80.169 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 12 7月 26 14:53 /root/3.txt
192.168.80.168 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 12 7月 26 14:53 /root/3.txt
####查看被控主机的文件状态
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/'
192.168.80.168 | CHANGED | rc=0 >>
总用量 20
-rw-r--r--. 1 root root 7 7月 26 13:19 1.txt
-rw-r--r--. 1 root root 218 7月 26 14:37 2.txt
-rwxrwxrwx. 1 root root 12 7月 26 14:53 3.txt
-rwxrwxrwx. 1 root root 0 7月 26 14:48 3.txt.75319.2025-07-26@14:53:56~
-rw-------. 1 root root 1673 5月 11 08:19 anaconda-ks.cfg
192.168.80.169 | CHANGED | rc=0 >>
总用量 20
-rw-r--r--. 1 root root 9 7月 26 13:22 1.txt
-rw-r--r--. 1 root root 109 7月 26 14:17 2.txt
-rwxrwxrwx. 1 root root 12 7月 26 14:53 3.txt
-rwxrwxrwx. 1 root root 0 7月 26 14:48 3.txt.79128.2025-07-26@14:53:56~
5、directory_mode:递归设定目录的权限,默认为系统默认权限。
[root@anisble ~]# ansible webs -m shell -a 'mkdir -p /tmp/test.txt/'
192.168.80.169 | CHANGED | rc=0 >>
192.168.80.168 | CHANGED | rc=0 >>
[root@anisble ~]# ansible webs -m copy -a 'src=/tmp/test.txt/ dest=/tmp/test.txt directory_mode=644'
192.168.80.168 | SUCCESS => {
"changed": false,
"dest": "/tmp/test.txt/",
"src": "/tmp/test.txt/"
}
192.168.80.169 | SUCCESS => {
"changed": false,
"dest": "/tmp/test.txt/",
"src": "/tmp/test.txt/"
}
####查看远程主机的目录权限
[root@anisble tmp]# ansible webs -m shell -a 'ls -l /tmp/'
192.168.80.169 | CHANGED | rc=0 >>
总用量 408
drwxr-xr-x. 2 root root 6 7月 26 15:05 test.txt
192.168.80.168 | CHANGED | rc=0 >>
drwxr-xr-x. 2 root root 6 7月 26 15:05 test.txt
6、force:当目标主机包含该文件,但是内容不同时,设定为“yes”,表示强制覆盖;设定为“no”表示目标主机的目标位置不存在该文件才复制。默认为“yes”
当文件内容不同,强行覆盖
[root@anisble ~]# ansible webs -m copy -a 'src=/root/3.txt dest=/root/3.txt force=yes'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "b1ffb6b5d22cd9f210fbc8b7fdaf0e19",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1753514841.4208858-39141-70717974715224/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "b1ffb6b5d22cd9f210fbc8b7fdaf0e19",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1753514841.4280627-39142-161692169684949/source",
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'cat /root/3.txt'
192.168.80.169 | CHANGED | rc=0 >>
aaaaaa
192.168.80.168 | CHANGED | rc=0 >>
aaaaaa
仅当远程目标文件不存在时才复制
###先将远程目标的文件删除
[root@anisble ~]# ansible webs -m shell -a 'rm /root/3.txt'
192.168.80.169 | CHANGED | rc=0 >>
192.168.80.168 | CHANGED | rc=0 >>
当远程目标不存在时,会复制
[root@anisble ~]# ansible webs -m copy -a 'src=/root/3.txt dest=/root/3.txt force=no'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "b1ffb6b5d22cd9f210fbc8b7fdaf0e19",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1753515051.9466014-39670-255176655044102/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "b1ffb6b5d22cd9f210fbc8b7fdaf0e19",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1753515051.9489474-39671-120548018012389/source",
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'cat /root/3.txt'
192.168.80.169 | CHANGED | rc=0 >>
aaaaaa
192.168.80.168 | CHANGED | rc=0 >>
aaaaaa
7、others:所有的file模块中的选项可以在这里使用
owner
和 group
是 file
模块的选项,通过 others
参数传递
复制文件时同时设置所有者(owner)和组(group)
[root@anisble ~]# ansible webs -m copy -a 'src=/root/3.txt dest=/root/3.txt owner=user group=user'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 1000,
"group": "user",
"mode": "0644",
"owner": "user",
"path": "/root/3.txt",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"state": "file",
"uid": 1000
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f93a0ac260e933140907dc694df5e3bc0bbafeae",
"dest": "/root/3.txt",
"gid": 1000,
"group": "user",
"mode": "0644",
"owner": "user",
"path": "/root/3.txt",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 7,
"state": "file",
"uid": 1000
}
8、 mode:设置文件权限
设置文件权限为777
[root@anisble ~]# ansible webs -m copy -a 'src=/root/3.txt dest=/root/3.txt mode=777'
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1753512488.8755085-33673-255658764112420/source",
"state": "file",
"uid": 0
}
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/3.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0777",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1753512488.8767612-33674-102815642349368/source",
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/3.txt'
192.168.80.168 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 0 7月 26 14:48 /root/3.txt
192.168.80.169 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 0 7月 26 14:48 /root/3.txt
3、template模块
-
backup: yes/no,建立个包括timestamp在内的文件备份,以备不时之需
-
dest: 必选项,远程节点上的绝对路径,用于放置template文件
-
group: 设置远程节点上的的template文件的所属用户组
-
mode: 设置远程节点上的template文件权限。类似Linux中chmod的用法
-
owner: 置远程节点上的template文件所属用户
-
src: 必选项,本地Jinjia2模版的template文件位置
渲染一个 Nginx 配置模板到远程服务器
ansible web -b -m template -a 'src=templates/nginx.conf.j2 dest=/etc/nginx/conf.d/site.conf owner=root group=root mode=0644 backup=yes'
4、lineinfile模块 修改文件中特定的行
ansible <目标主机/组> -b -m lineinfile -a 'path=<文件路径> regexp="<正则表达式>" line="<替换行内容>" [其他参数]'
-
path/dest: 目标文件绝对路径+文件名,必须参数
-
line: 替换/插入的内容
-
regexp: 待匹配内容
-
insertbefore: 匹配行前面插入
-
insertafter: 匹配行后面插入
-
state: 删除匹配行,需要将值设为absent,默认值present。
-
backup: 是否在修改文件之前对文件进行备份。 yes/no
-
create: 当要操作的文件并不存在时,是否创建对应的文件。yes/no
-
backrefs:yes/no,backrefs为no时,如果没有匹配,则添加一行line。如果匹配了,则把匹配内容替被换为line内容;backrefs为yes时,如果没有匹配,则文件保持不变。如果匹配了,把匹配内容替被换为line内容
5、blockinfile模块 在文件中插入/替换块内容
-
path: required,指定要操作的文件。
-
block: 指定要操作的”一段文本”,此参数有一个别名叫”content”,使用content或block的作用是相同的。
-
marker: 在指定文件中插入一段文本,ansible会自动为这段文本添加两个标记,一个开始标记,一个结束标记,默认情况下,开始标记为# BEGIN ANSIBLE MANAGED BLOCK,结束标记为# END ANSIBLE MANAGED BLOCK,使用marker参数自定义”标记”。比如,marker=#{mark}test ,这样设置以后,开始标记变成了# BEGIN test,结束标记变成了# END test。
-
state: state参数有两个可选值,present与absent,插入和删除对应标记的段落。
-
insertafter: 在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的后面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的后面。如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为EOF,表示将文本插入到文档末尾。
-
insertbefore: 在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的前面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的前面。如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为BOF,表示将文本插入到文档开头。
-
backup: 是否在修改文件之前对文件进行备份。
-
create: 当要操作的文件并不存在时,是否创建对应的文件
在/etc/host中加一段自定义配置
ansible web -b -m blockinfile -a 'path=/etc/hosts block="192.168.80.10 web1.example.com\n192.168.80.11 web2.example.com" marker="# {mark} WEBSERVERS"'
执行后会出现
# BEGIN WEBSERVERS
192.168.1.10 web1.example.com
192.168.1.11 web2.example.com
# END WEBSERVERS
6、fetch模块 从远程主机拉去文件到本机
fetch模块用于从远程某个主机获取(复制)文件到本地来
-
dest:用来存储文件的目录。
-
src:在远程拉取的文件,并且是一个file,不能是目录
案例
[root@anisble ~]# ansible webs -m fetch -a 'src=/root/d1/f1 dest=/root/'
7、make模块 编译和安装软件
-
chdir: 在执行tast之前,需要切换的目录路径—必须
-
file: 标准
Makefile
的路径 -
params: 一些额外的需要传给
make
命令的参数 -
target: make要执行的操作可以写
:
install/test/
all
install
-
make.params.PREFIX: 编译之后的文件存放位置。适用于不是
root
用户执行的脚本
编译并安装一个软件
###编译
ansible servers -b -m make -a 'chdir=/path/to/software target=all'
# 等同于在终端执行:make all
###安装
ansible servers -b -m make -a 'chdir=/path/to/software target=install'
# 等同于在终端执行:make install
###测试
ansible servers -b -m make -a 'chdir=/path/to/software target=test'
# 等同于在终端执行:make test
###清理编译文件
ansible servers -b -m make -a 'chdir=/path/to/software target=clean'
# 等同于在终端执行:make clean
设置编译安装后的路径
ansible servers -b -m make -a 'chdir=/path/to/source target=install params="PREFIX=/opt/custom"'
8、archive模块 压缩文件
-
path: 远程主机上需要被打包/压缩的源文件(可以是文件列表,支持glob模式)
-
dest: 打包/压缩后的包文件路径(包文件的父目录必须存在);如果包文件已存在,则会被覆盖。
-
format: 指定压缩类型,包括:bz2、gz(默认)、tar、xz、zip
-
owner: 指定属主
-
group: 指定属组
-
mode: 指定权限
-
remove: yes|no,默认为no,在打包/压缩后,不删除源文件
将/root/1.txt目录压缩为/root/d1(默认格式为 gz)
[root@anisble ~]# ansible webs -m archive -a 'path=/root/1.txt dest=/root/d1/1.txt.tar.gz'
192.168.80.169 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"archived": [
"/root/1.txt"
],
"arcroot": "/root/",
"changed": true,
"dest": "/root/d1/1.txt.tar.gz",
"dest_state": "compress",
"expanded_exclude_paths": [],
"expanded_paths": [
"/root/1.txt"
],
"gid": 0,
"group": "root",
"missing": [],
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 34,
"state": "file",
"uid": 0
}
192.168.80.168 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"archived": [
"/root/1.txt"
],
"arcroot": "/root/",
"changed": true,
"dest": "/root/d1/1.txt.tar.gz",
"dest_state": "compress",
"expanded_exclude_paths": [],
"expanded_paths": [
"/root/1.txt"
],
"gid": 0,
"group": "root",
"missing": [],
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 37,
"state": "file",
"uid": 0
}
[root@anisble ~]# ansible webs -m shell -a 'ls -l /root/d1'
192.168.80.169 | CHANGED | rc=0 >>
总用量 8
-rw-r--r--. 1 root root 34 7月 27 17:37 1.txt.tar.gz
lrwxrwxrwx. 1 root root 11 7月 26 16:52 f1 -> /root/3.txt
lrwxrwxrwx. 1 root root 11 7月 26 16:53 f2 -> /root/3.txt
-rw-r--r--. 2 root root 109 7月 26 17:00 f3
192.168.80.168 | CHANGED | rc=0 >>
总用量 8
-rw-r--r--. 1 root root 37 7月 27 17:37 1.txt.tar.gz
drwxr-xr-x. 2 root root 6 7月 26 17:20 d2
lrwxrwxrwx. 1 root root 11 7月 26 16:52 f1 -> /root/3.txt
lrwxrwxrwx. 1 root root 11 7月 26 16:53 f2 -> /root/3.txt
-rw-r--r--. 2 root root 218 7月 26 17:00 f3
-rw-r--r--. 1 root root 0 7月 26 17:16 f4
将多个日志文件打包并压缩为 bz2 格式
ansible webs -m archive -a 'path="/var/log/messages /var/log/secure" dest=/tmp/system-logs.tar.bz2 format=bz2'
指定压缩格式
*.log压缩目录下所有log文件
###创建 tar 包(不压缩)
ansible webs -m archive -a 'path=/data/backup dest=/tmp/backup.tar format=tar'
###使用 xz 格式压缩(更高压缩率)
ansible webs -m archive -a 'path=/var/www/html dest=/tmp/html.tar.xz format=xz'
压缩并设置属主和属组,赋权600 并删除原文件
ansible webs -m archive -a 'path=/data/app dest=/tmp/app.tar.gz owner=appuser group=appgroup mode=600 remove=yes'
9、unarchive模块 解压文件
-
creates: 如果指定的绝对路径(文件或目录)已存在,则不会运行此步骤。。
-
copy: 默认为yes,拷贝的文件从ansible主机复制到远程主机,如果没有可复制对象,在远程主机上寻找,no在远程主机上寻找src源文件解压
-
src: tar源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需设置copy=no
-
dest: 远程主机上的目标绝对路径
-
mode: 设置解压缩后的文件权限
-
exec: 列出需要排除的目录和文件
-
remote_src: 设置remote_src=yes为解包目标上已经存在的档案。对于Windows目标,改用win_unzip模块。
-
owner: 解压后文件或目录的属主
-
group: 解压后的目录或文件的属组
-
exclude: 列出要从unarchive操作中排除的目录和文件条目。
-
extra_opts:通过传入数组指定其他选项
-
keep_newer:不要替换比归档文件更新的现有文件
五、软件包管理模块
1、yum模块
1. 核心参数说明
参数 | 说明 | 示例值 |
---|---|---|
name | 指定要操作的软件包名称(支持通配符 * ) | name=httpd 或 name="nginx*" |
state | 定义软件包状态 | present (安装)、latest (最新版)、absent (卸载) |
update_cache | 强制更新 yum 缓存(类似 yum makecache ) | yes 或 no (默认 no ) |
conf_file | 指定自定义的 yum 配置文件路径 (安装本地已有的包) | conf_file=/path/to/custom.repo |
disable_gpg_check | 是否跳过 GPG 验证(不安全,慎用) 只用于present 或者 latest | yes 或 no (默认 no ) |
disablerepo | 临时禁用指定的 yum 仓库 只用于安装或者更新时 | disablerepo="epel" |
enablerepo | 临时启用指定的 yum 仓库 只用于安装或者更新时 | enablerepo="remi-php74" |
2、案例
2.1、安装httpd软件包 state=present
[root@anisble ~]# ansible webs -m yum -a 'name=httpd state=present'
2.2、检查是否安装成功
[root@anisble ~]# ansible webs -m shell -a 'rpm -q httpd'
192.168.80.169 | CHANGED | rc=0 >>
httpd-2.4.6-99.el7.centos.1.x86_64
192.168.80.168 | CHANGED | rc=0 >>
httpd-2.4.6-99.el7.centos.1.x86_64
2.3、安装最新版本的nginx state=latest
[root@anisble ~]# ansible webs -m yum -a 'name=nginx state=latest'
2.4、批量安装多个软件包
[root@anisble ~]# ansible webs -m yum -a 'name=httpd,php,php-mysql state=present'
2.5、卸载httpd包 state=absent
[root@anisble ~]# ansible webs -m yum -a 'name=httpd state=absent'
2.6、卸载软件包及其依赖项
[root@anisble ~]# ansible web -m yum -a 'name=httpd state=absent autoremove=yes'
2.7、 更新 yum 缓存
[root@anisble ~]# ansible webs -m yum -a 'update_cache=yes'
总结
场景 | 推荐参数组合 |
---|---|
安装软件包 | name=包名 state=present |
安装最新版 | name=包名 state=latest |
卸载软件包 | name=包名 state=absent |
强制更新缓存 | update_cache=yes |
使用特定仓库 | enablerepo=仓库名 name=包名 |
跳过 GPG 验证 | disable_gpg_check=yes (慎用) |
2、package模块 通用软件包管理
ansible webs -m package -a "name=nginx state=latest"
-
name: 指定要安装的软件包名
-
state: present/absent;present 安装 absent 卸载
# 自动选择包管理器安装 nginx(适用于所有系统)
ansible webs -m package -a 'name=nginx state=present'
# 自动选择包管理器卸载 httpd
ansible webs -m package -a 'name=httpd state=absent'
# 一次性安装多个软件包
ansible webs -m package -a 'name=python3,python3-pip,vim state=present'
3、package_facts模块 获取以安装软件包的信息
ansible host -m package_facts -a "manager=yum"
-
manager: auto/rpm/apt/portage/pkg/pacman/apk,默认auto;表示系统使用的包管理器,auto表示自动判断包管理器类型
-
strategy:first/all,默认first;如何查询系统上的程序包管理器。 first意味着它将仅返回有关第一个受支持的程序包管理器的信息。 all 将返回系统上所有受支持的可用软件包管理器的信息。
[root@anisble ~]# ansible webs -m package_facts -a 'manager=rpm strategy=first'
六、存储管理模块
1、mount模块 管理挂载模块
-
src: 定义挂载内容
-
path: 设备挂载至本地的路径,必须指定
-
fstype: 挂载的文件系统类型,xfs、nfs...,必须指定
-
opts: 挂载的参数,defaults、ro...
-
state: 挂载的状态,absent/mounted/unmounted;
-
mounted进行挂载,修改/etc/fstab信息,
-
unmounted临时卸载,不修改/etc/fstab信息,
-
absent永久性卸载,并修改 /etc/fstab信息
# 挂载 /dev/sdb1 到 /mnt/data,文件系统为 xfs
ansible swbs -m mount -a 'src=/dev/sdb1 path=/mnt/data fstype=xfs state=mounted'
2、filesystem模块 创建文件系统
ansible host -m filesystem -a "fstype=ext4 dev=/dev/sdb1"
-
fstype: 文件系统的类型(Choices: btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat,swap) 必选
-
dev: 预备检查的硬盘分区 必选
-
force: yes/no,默认为no;强制格式化文件系统,在已经格式化文件系统的基础上重新格式化文件系统需要把参数配成yes 可选
-
opts: 其他mkfs命令的参数 可选
创建文件系统
# 将 /dev/sdb1 格式化为 ext4
ansible webs -m filesystem -a 'fstype=ext4 dev=/dev/sdb1'
# 格式化为XFS并设置卷标
ansible webs -m filesystem -a 'fstype=xfs dev=/dev/sdc1 opts="-L data"'
# 将 /dev/sdd1 初始化为swap空间
ansible webs -m filesystem -a 'fstype=swap dev=/dev/sdd1'
# 强制将 /dev/sdb1 格式化为 ext4(覆盖现有数据)
ansible webs -m filesystem -a 'fstype=ext4 dev=/dev/sdb1 force=yes'
3、lvg模块
参数 | 作用 |
---|---|
vg | 必选,卷组名称(如vg_data 、vg_system )。 |
pvs | 必选(创建时),加入卷组的物理卷列表(如/dev/sdb1 、/dev/sdc )。 |
pesize | 物理扩展(PE)大小(默认 4M,支持 K、M、G 单位),仅创建卷组时有效。 |
state | 卷组状态: - present (默认):创建或确保卷组存在;- absent :删除卷组(需先删除逻辑卷)。 |
创建卷组
# 将物理卷 /dev/sdb1 加入卷组 vg_data(默认PE大小4M)
ansible webs -m lvg -a 'vg=vg_data pvs=/dev/sdb1 state=present'
创建卷组并指定PE大小
# 用 /dev/sdc1、/dev/sdd1 创建卷组 vg_app,PE大小设为16M
ansible webs -m lvg -a 'vg=vg_app pvs="/dev/sdc1 /dev/sdd1" pesize=16M state=present'
向现有卷组添加物理卷
# 给已存在的 vg_data 新增物理卷 /dev/sde1
ansible webs -m lvg -a 'vg=vg_data pvs="/dev/sdb1 /dev/sde1" state=present'
删除卷组(先要清理逻辑卷)
# 注意:删除卷组前必须先删除其上的所有逻辑卷(LV)
ansible webs -m lvg -a 'vg=vg_old state=absent'
4、lovl模块 逻辑卷
参数 | 作用 |
---|---|
vg | 必选,指定逻辑卷所在的卷组(Volume Group)名称。 |
lv | 必选,指定逻辑卷名称。 |
size | 必选,指定逻辑卷大小,默认单位为 MB(支持 K、M、G、T 后缀)。 |
pvs | 指定物理卷(Physical Volume)列表,用于创建卷组(仅在state=present 且卷组不存在时需要)。 |
force | 是否强制执行危险操作(如缩小或删除已挂载的逻辑卷),默认no 。 |
state | 逻辑卷状态: - present (默认):确保逻辑卷存在。- absent :删除逻辑卷。 |
active | 是否激活逻辑卷(默认yes )。设为no 时,逻辑卷将被停用(需要先卸载)。 |
创建新的逻辑卷
# 在卷组 vg_data 上创建 5GB 的逻辑卷 lv_app
ansible webs -m lvol -a 'vg=vg_data lv=lv_app size=5G'
创建卷组并添加逻辑卷
# 在物理卷 /dev/sdb1 上创建卷组 vg_data,并创建 10GB 的逻辑卷 lv_backup
ansible webs -m lvol -a 'vg=vg_data lv=lv_backup size=10G pvs=/dev/sdb1'
删除逻辑卷
# 先卸载并停用逻辑卷
ansible webs -m mount -a 'path=/data state=absent'
ansible webs -m lvol -a 'vg=vg_data lv=lv_data active=no'
# 强制删除逻辑卷
ansible wens -m lvol -a 'vg=vg_data lv=lv_data state=absent force=yes'
七、系统信息模块
1、setup模块
-
setup模块主要用于收集信息,是通过调用facts组件来实现的,facts组件时Ansible用于采集被管理机器设备信息的一个功能。我们可以使用setup模块查看机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据文件中,ansible_facts是最上层的值。
-
facts就是变量,内建变量。每个主机的各种信息,cpu个数,内存的大小等。会存在facts中的某个变量中,调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。比如redhat系列用yum安装,而debian系列用apt安装软件
1、查看被管理的主机内存
[root@anisble ~]# ansible webs -m setup -a 'filter="*mem*"'
192.168.80.169 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 220,
"ansible_memory_mb": {
"nocache": {
"free": 765,
"used": 1054
},
"real": {
"free": 220,
"total": 1819,
"used": 1599
},
"swap": {
"cached": 1,
"free": 2027,
"total": 2047,
"used": 20
}
},
"ansible_memtotal_mb": 1819,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
192.168.80.168 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 198,
"ansible_memory_mb": {
"nocache": {
"free": 739,
"used": 1080
},
"real": {
"free": 198,
"total": 1819,
"used": 1621
},
"swap": {
"cached": 4,
"free": 2017,
"total": 2047,
"used": 30
}
},
"ansible_memtotal_mb": 1819,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@anisble ~]# ansible webs -m setup -a 'filter="*cpu*"'
192.168.80.168 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 6,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
192.168.80.169 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 6,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
2、setup模块还有一个很好的功能就是保存我们筛选出来的信息到我们的主机上,同时,文件名是被管理主机的IP地址,方便检测那台主机出现问题
[root@anisble ~]# ansible webs -m setup -a 'filter="*mem*"' --tree /tmp/facts
192.168.80.169 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 224,
"ansible_memory_mb": {
"nocache": {
"free": 769,
"used": 1050
},
"real": {
"free": 224,
"total": 1819,
"used": 1595
},
"swap": {
"cached": 1,
"free": 2027,
"total": 2047,
"used": 20
}
},
"ansible_memtotal_mb": 1819,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
192.168.80.168 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 200,
"ansible_memory_mb": {
"nocache": {
"free": 741,
"used": 1078
},
"real": {
"free": 200,
"total": 1819,
"used": 1619
},
"swap": {
"cached": 4,
"free": 2017,
"total": 2047,
"used": 30
}
},
"ansible_memtotal_mb": 1819,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@anisble ~]# cd /tmp/facts/
[root@anisble facts]# ls
192.168.80.168 192.168.80.169
[root@anisble facts]# cat 192.168.80.168
{"ansible_facts": {"ansible_memfree_mb": 200, "ansible_memory_mb": {"nocache": {"free": 741, "used": 1078}, "real": {"free": 200, "total": 1819, "used": 1619}, "swap": {"cached": 4, "free": 2017, "total": 2047, "used": 30}}, "ansible_memtotal_mb": 1819, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false}