Ansible模块2¶
一. copy模块¶
1. 功能¶
copy模块的功能是实现主控端向目标主机拷贝文件或目录,类似scp功能
2. copy模块的常用选项¶
backup: 在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
content: 用于替代"src",可以直接设定文件的值
dest: 必须项。要将源文件复制到的远程主机的绝对路径。如果源文件是一个目录,那么路径也必须是一个目录
directory_mode: 递归的设定目标的权限,默认为系统默认权限
force: 如果目标主机包含该文件但内容不同,设置为yes则强制覆盖;为no则只有当目标主机的目标位置不存在该文件时才复制。默认为yes
src: 要复制到远程主机的文件在本地的地址,可以是绝对路径也可以是相对路径。如果路径是一个目录它将递归复制。在这种情况下如果路径使用"/"结尾则只复制目录内的内容,如果没有使用"/"结尾则包含目录在内的整个内容全部复制,类似于rsync
3. copy模块的应用案例¶
案例1¶
使用src把ansible主机上的/etc/hosts文件复制到主机组中机器的/tmp目录下
[root@1 ~]# ansible -m copy -a 'src=/etc/hosts dest=/tmp/ owner=root group=root mode=640 backup=yes' web_servers*
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/tmp/hosts",
"gid": 0,
"group": "root",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"mode": "0640",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 158,
"src": "/root/.ansible/tmp/ansible-tmp-1786619098.3949304-5661-186575913094456/source",
"state": "file",
"uid": 0
}
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/tmp/hosts",
"gid": 0,
"group": "root",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"mode": "0640",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 158,
"src": "/root/.ansible/tmp/ansible-tmp-1786619098.5193756-5662-227957182486214/source",
"state": "file",
"uid": 0
}
说明:
#src: 主控端文件位置
#dest: 被控端目标位置
#owner: 文件复制过去后的所有者
#group: 文件复制过去后的所属组
#mode: 文件的权限设定
#backup=yes: 如果目标位置存在同名文件,则在覆盖之前将源文件备份
查看目标主机是否复制成功
[root@1 ~]# ansible -m shell -a 'ls -l /tmp/hosts' web_servers*
3 | CHANGED | rc=0 >>
-rw-r-----. 1 root root 158 8月 13 19:04 /tmp/hosts
2 | CHANGED | rc=0 >>
-rw-r-----. 1 root root 158 8月 13 19:04 /tmp/hosts
案例2¶
使用content
# 复制
[root@1 ~]# ansible -m copy -a 'content="Hello ansible\nyou are clever!\n" dest=/tmp/ansible.txt' web_servers2
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "09c5fccf782fcdb0cfce2f1e009df8c56975b550",
"dest": "/tmp/ansible.txt",
"gid": 0,
"group": "root",
"md5sum": "cebd32f6ad7c7bff107a3d213ab38ec8",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 30,
"src": "/root/.ansible/tmp/ansible-tmp-1786619568.4948137-5807-280842491652859/source",
"state": "file",
"uid": 0
}
# 查看验证
[root@1 ~]# ansible -m shell -a 'cat /tmp/ansible.txt' web_servers2
3 | CHANGED | rc=0 >>
Hello ansible
you are clever!
二. fetch模块¶
1. 简介¶
该模块与copy正好相反,从远程主机拉去文件到本地目录
2. 常见参数¶
dest: 设定目标文件的地址(强制选项)
flat: 允许拼接创建文件名
src: 设置源文件的地址(强制选项)
注意:
源文件与目标文件的格式最好保持一致
src为当前的版本,只允许抓群远程的单个文件
dest 支持的只能是本机的目录。抓取后的格式: "/dest/" + "目标主机/path/to/src"
3. 命令格式¶
fetch模块在ansible使用时,标准的写法为
ansible <目标主机> -m fetch -a '属性1=值1 属性2=值2 ... 属性n=值n'
4. 实践¶
1) 单文件拉取¶
# 先删除/tmp/的所有文件
[root@1 ~]# rm -rf /tmp/*
# 从2上拉取文件
[root@1 ~]# ansible -m fetch -a 'src=/tmp/hosts dest=/tmp/' web_servers1
2 | CHANGED => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/tmp/2/tmp/hosts",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"remote_md5sum": null
}
# 检查效果
[root@1 ~]# tree /tmp/
/tmp/
└── 2
└── tmp
└── hosts
2 directories, 1 file
2) 多文件拉取¶
fetch默认情况下只能拉取单文件,并且不支持通配符
[root@1 ~]# ansible -m fetch -a 'src=/var/log/*.log dest=/tmp/' web_servers1
2 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "the remote file does not exist, not transferring, ignored"
}
因为fetch属性原因,报错了。我们最好使用压缩包方式来实现多文件传输
# 先归档压缩
[root@1 ~]# ansible -m shell -a "tar cfz /tmp/log.tgz /var/log/*.log" web_servers1
2 | CHANGED | rc=0 >>
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”
# 再复制拉取到本地
[root@1 ~]# ansible -m fetch -a "src=/tmp/log.tgz dest=/tmp/" web_servers1
2 | CHANGED => {
"changed": true,
"checksum": "d3460cc635b6ef2374086814e706d00210208895",
"dest": "/tmp/2/tmp/log.tgz",
"md5sum": "58b271507ccfb4a06e5faeb9af91513c",
"remote_checksum": "d3460cc635b6ef2374086814e706d00210208895",
"remote_md5sum": null
}
# 查看验证
[root@1 ~]# tree /tmp/
/tmp/
└── 2
└── tmp
├── hosts
└── log.tgz
2 directories, 2 files
[root@1 ~]# tar tvf /tmp/2/tmp/log.tgz
-rw-r--r-- root/root 59604 2026-08-15 17:19 var/log/dnf.librepo.log
-rw-r--r-- root/root 206497 2026-08-15 17:19 var/log/dnf.log
-rw-r--r-- root/root 30634 2026-08-15 17:17 var/log/dnf.rpm.log
-rw-r--r-- root/root 1380 2026-08-15 17:17 var/log/hawkey.log
-rw------- root/root 217 2026-08-15 09:34 var/log/vmware-network.1.log
-rw------- root/root 217 2026-08-14 18:38 var/log/vmware-network.2.log
-rw------- root/root 217 2026-08-14 10:16 var/log/vmware-network.3.log
-rw------- root/root 217 2026-08-14 08:41 var/log/vmware-network.4.log
-rw------- root/root 217 2026-08-13 20:40 var/log/vmware-network.5.log
-rw------- root/root 217 2026-08-13 08:25 var/log/vmware-network.6.log
-rw------- root/root 217 2026-08-12 21:25 var/log/vmware-network.7.log
-rw------- root/root 217 2026-08-12 16:39 var/log/vmware-network.8.log
-rw------- root/root 217 2026-08-02 12:09 var/log/vmware-network.9.log
-rw------- root/root 217 2026-08-15 16:47 var/log/vmware-network.log
-rw------- root/root 51990 2026-08-15 16:47 var/log/vmware-vmsvc-root.log
-rw------- root/root 6875 2026-08-15 16:47 var/log/vmware-vmtoolsd-root.log
三. file模块¶
1. file模块一些概念¶
file模块主要是用于对远程主机上文件进行操作,如修改文件属性(权限、属主、属组)和创建文件、目录、符号链接等
2. 常见参数¶
force: 需要在两种情况下强制创建软连接,一种是源文件不存在但是之后会建立的情况下;另一种是目标软链接已经存在,需要先取消之前的软链接然后创建新的软链接。有两个选项: yes|no
group: 定义文件/目录的属组
mode: 定义文件/目录的属性
owner: 定义文件/目录的属主
path: 必选项,定义文件/目录的路径
recurse: 递归的设置文件属性,只对目录有效
src: 要被链接的源文件路径,只应用于
state=link的情况dest: 被连接到的路径,只应用于
state=link的情况state:
directory: 如果目录不存在则创建目录
file: 不是用于创建文件,而是检查文件是否存在。主要用于检查文件是否存在的应用场景
link: 创建软链接
hard: 创建硬链接
touch: 如果文件不存在则会创建一个新文件。如果文件或目录已存在,则更新其最后的修改时间
absent: 删除目录、文件或者取消链接文件
3. file模块应用案例¶
1) 修改权限¶
修改2,3两台主机上/tmp/hosts文件权限为777
[root@1 ~]# ansible -m file -a 'path=/tmp/hosts mode=777' web_servers*
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/hosts",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 158,
"state": "file",
"uid": 0
}
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/hosts",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 158,
"state": "file",
"uid": 0
}
查看文件权限
[root@1 ~]# ansible -a 'ls -l /tmp/hosts' web_servers*
3 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 158 8月 13 19:04 /tmp/hosts
2 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 158 8月 13 19:04 /tmp/hosts
2) 创建符号链接¶
将2,3上的/tmp/hosts文件创建符号链接到/opt目录下
[root@1 ~]# ansible -m file -a "src=/tmp/hosts dest=/opt/hosts state=link" web_servers*
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/opt/hosts",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 10,
"src": "/tmp/hosts",
"state": "link",
"uid": 0
}
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/opt/hosts",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 10,
"src": "/tmp/hosts",
"state": "link",
"uid": 0
}
查看验证
[root@1 ~]# ansible -i /etc/ansible/hosts -a 'ls -l /opt/hosts' web_servers*
2 | CHANGED | rc=0 >>
lrwxrwxrwx. 1 root root 10 8月 13 19:55 /opt/hosts -> /tmp/hosts
3 | CHANGED | rc=0 >>
lrwxrwxrwx. 1 root root 10 8月 13 19:55 /opt/hosts -> /tmp/hosts
3) 删除链接文件¶
[root@1 ~]# ansible -m file -a "path=/opt/hosts state=absent" web_servers*
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"path": "/opt/hosts",
"state": "absent"
}
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"path": "/opt/hosts",
"state": "absent"
}
查看验证
[root@1 ~]# ansible -m file -a "path=/opt/hosts state=file" web_servers*
3 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "file (/opt/hosts) is absent, cannot continue",
"path": "/opt/hosts",
"state": "absent"
}
2 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "file (/opt/hosts) is absent, cannot continue",
"path": "/opt/hosts",
"state": "absent"
}
此时报错,因为该文件删掉了
4) 创建文件或目录¶
创建目录,如果它不存在
[root@1 ~]# ansible -m file -a "path=/tmp/dir1 state=directory" web_servers*
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/dir1",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/dir1",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
touch创建空文件
[root@1 ~]# ansible -m file -a "path=/tmp/testfile1 state=touch" web_servers*
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/tmp/testfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/tmp/testfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
查看验证
[root@1 ~]# ansible -m shell -a "ls /tmp/*1" web_servers*
3 | CHANGED | rc=0 >>
/tmp/testfile1
/tmp/dir1:
2 | CHANGED | rc=0 >>
/tmp/testfile1
/tmp/dir1:
四. stat 模块¶
1. 简介¶
stat模块的主要作用场景时查看文件状态
2. 常见参数¶
path: 获取文件路径,强制选项
3. 命令格式¶
stat模块在ansible使用时,标准写法为
ansible <目标主机> -m stat -a 'path=文件路径 属性1=值1 ... 属性n=值n'
4. 实践¶
查看不存在文件的效果
[root@1 ~]# ansible -m stat -a "path=/tmp/1111111" web_servers1
2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"stat": {
"exists": false
}
}
查看指定存在文件的效果
[root@1 ~]# ansible -m stat -a "path=/tmp/hosts" web_servers1
2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"stat": {
...
五. ping模块¶
ping模块用于测试连接可通性,没有参数,通的话返回pong
[root@1 ~]# ansible -m ping web_servers*
2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
六. yum模块¶
1. 作用¶
yum模块可以帮助我们在远程主机上通过yum源管理软件包
2. yum / dnf / package 模块的关系(先看这里)¶
| 模块 | 适用系统 | 说明 |
|---|---|---|
yum 模块 |
RHEL/CentOS 7(Python2) | 老系统才用 |
dnf 模块 |
RHEL/Rocky 8/9(Python3) | Rocky9 推荐用它 |
package 模块 |
通用(自动识别 yum/dnf/apt) | 日常操作最省心 |
- yum 和 dnf 模块参数几乎一样(
name/state/update_cache),主要差异在平台适配:yum 基于 python2,Rocky9 没有 python2 可能报错,所以用 dnf 模块 - package 是通用"上位"模块,能覆盖大部分日常操作(安装/卸载/升级/查询),但不能完全替代 dnf/yum 的专属参数(如
enablerepo、disablerepo、exclude、installroot等) - 结论:Rocky9 上日常用
package最省心;要精细控制仓库/排除时用dnf模块
常用参数
name参数: 必须参数,用于指定需要管理的软件包,比如nginx
state参数: 用于指定软件包的状态,默认值为
present。标识确保软件包已经安装,除了present其他可用的值有installed,latest,absent,remove。其中installed与present等效,latest表示安装yum的最新版本,absent和remove等效,表示删除对应的软件包disable_gpg_check参数: 用于禁用对rpm包公钥gpg验证。默认值为no表示不禁用验证;设置为yes表示禁用验证。即不验证包直接安装
update_cache参数: 是否更新缓存,默认值为no
enablerepo参数: 用于指定安装软件包时临时启用的yum源。假如你想要从A源中安装软件,但是你不确定A源是否启用了,你可以按照软件包时将此参数的值设置为仓库ID。这样即使A源的设置是未启用,也可以在安装软件包时临时启用A源。
disablerepo参数: 用于指定安装软件包时临时禁用的yum源。某些场景下需要此参数。比如当多个yum源中同时存在要安装的软件包时,你可以使用此参数临时禁用某个值。这样设置后在安装软件包时则不会从对应的源中选择安装包
enablerepo参数和disablerepo参数可以同时使用
3. yum模块的应用案例¶
2和3两台主机安装httpd服务
[root@1 ~]# ansible -m dnf -a "name=httpd state=latest" web_servers*
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: mod_http2-2.0.26-6.el9_8.1.x86_64",
"Installed: mailcap-2.1.49-5.el9.0.2.noarch",
"Installed: apr-1.7.0-12.el9_3.x86_64",
"Installed: httpd-2.4.62-13.el9_8.5.x86_64",
"Installed: httpd-core-2.4.62-13.el9_8.5.x86_64",
"Installed: apr-util-1.6.1-23.el9.x86_64",
"Installed: mod_lua-2.4.62-13.el9_8.5.x86_64",
"Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
"Installed: rocky-logos-httpd-90.17-1.el9.noarch",
"Installed: httpd-filesystem-2.4.62-13.el9_8.5.noarch",
"Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
"Installed: httpd-tools-2.4.62-13.el9_8.5.x86_64"
]
}
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: mod_http2-2.0.26-6.el9_8.1.x86_64",
"Installed: mailcap-2.1.49-5.el9.0.2.noarch",
"Installed: apr-1.7.0-12.el9_3.x86_64",
"Installed: httpd-2.4.62-13.el9_8.5.x86_64",
"Installed: httpd-core-2.4.62-13.el9_8.5.x86_64",
"Installed: apr-util-1.6.1-23.el9.x86_64",
"Installed: mod_lua-2.4.62-13.el9_8.5.x86_64",
"Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
"Installed: rocky-logos-httpd-90.17-1.el9.noarch",
"Installed: httpd-filesystem-2.4.62-13.el9_8.5.noarch",
"Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
"Installed: httpd-tools-2.4.62-13.el9_8.5.x86_64"
]
}
验证
[root@1 ~]# ansible -m shell -a ' rpm -q httpd' web_servers*
2 | CHANGED | rc=0 >>
httpd-2.4.62-13.el9_8.5.x86_64
3 | CHANGED | rc=0 >>
httpd-2.4.62-13.el9_8.5.x86_64
七. get_url模块¶
1. 简介¶
用于将文件从http、https或ftp下载到被管理主机上
2. 常见参数¶
url: 下载文件的URL,支持HTTP,HTTPS和FTP协议
dest: 下载到目标路径(绝对路径)
force: 如果是yes且dest不是目录,则将每次都下载文件。如果是no,则只有当文件不存在时才会下载。
checksum: 对目标文件在下载前进行摘要计算。指定文件校验值(格式:
sha256:xxx或md5:xxx)。本地已有文件校验不过时才重新下载,比force=yes每次都盲目重下更高效timeout: 下载超时时间(秒),默认10秒
3. 实践¶
下载httpd文件
[root@1 ~]# ansible -m get_url -a 'url=https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2 dest=/tmp/ force=no checksum=sha256:68c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06' web_servers2
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum_dest": null,
"checksum_src": "2402a2e364f103389265587a9b599c16202f6771",
"dest": "/tmp/httpd-2.4.68.tar.bz2",
"elapsed": 65,
"gid": 0,
"group": "root",
"md5sum": "f2f3121e9f1fb4838d433dbd494543f9",
"mode": "0644",
"msg": "OK (7738512 bytes)",
"owner": "root",
"size": 7738512,
"src": "/root/.ansible/tmp/ansible-tmp-1786794001.2085521-1738-206966130583892/tmp4gxxiogn",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2"
}
查看效果
[root@1 ~]# ansible -m shell -a 'ls -l /tmp/httpd-2.4.68.tar.bz2' web_servers2
3 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 7738512 8月 15 19:41 /tmp/httpd-2.4.68.tar.bz2
我们修改校验值第一位,使其不匹配,再次尝试
[root@1 ~]# ansible -m get_url -a 'url=https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2 dest=/tmp/ force=no checksum=sha256:88c74d4df38c26bed4dfbdb
8f3baf1eb532f3872357becc1bba5d136f6b63c06' web_servers2
3 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"checksum_dest": "2402a2e364f103389265587a9b599c16202f6771",
"checksum_src": "2402a2e364f103389265587a9b599c16202f6771",
"dest": "/tmp/httpd-2.4.68.tar.bz2",
"elapsed": 8,
"msg": "The checksum for /tmp/httpd-2.4.68.tar.bz2 did not match 88c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06; it was 68c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06.",
"src": "/root/.ansible/tmp/ansible-tmp-1786794248.8448346-1779-280827685915311/tmpuf09inmq",
"url": "https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2"
}
可以看到 "msg": "The checksum for /tmp/httpd-2.4.68.tar.bz2 did not match这一行提示错误
八. archive模块¶
1. 简介¶
archive模块用于打包压缩保存在被管理的节点文件
2. 命令格式¶
archive模块再ansible使用时,标准写法是
ansible <目标主机> -m archive -a '属性1=值1 ... 属性n=值n'
3. 常见参数¶
path: 必选参数。要打包的源文件/目录。支持同时选择多个路径
dest: 归档文件的目标路径
format: 归档格式。分为gz(默认格式)、bz2、tar、xz、zip。不写时也会安装dest的拓展名自动判断
mode: 归档文件的权限,比如0755
owner/group: 归档文件的属主/属组
exclude_path: 排除的路径列表
remove: 归档成功后是否删除源文件。默认为no
force_archive: 单个文件时是否强制打包(否则单文件可能直接复制不压缩)。默认为no
follow: 是否跟随符号链接,默认为yes
exclusion_patterns: 归档压缩时排除内部文件
4. 实践¶
1) 准备临时文件¶
[root@1 ~]# ansible -m shell -a "mkdir -p /tmp/logs;cp /var/log/*.log /tmp/logs/" web_servers2
3 | CHANGED | rc=0 >>
[root@1 ~]# ansible -m shell -a "ls /tmp/logs" web_servers2
3 | CHANGED | rc=0 >>
dnf.librepo.log
dnf.log
dnf.rpm.log
hawkey.log
vmware-network.1.log
vmware-network.2.log
vmware-network.3.log
vmware-network.4.log
vmware-network.5.log
vmware-network.6.log
vmware-network.7.log
vmware-network.8.log
vmware-network.9.log
vmware-network.log
vmware-vmsvc-root.log
vmware-vmtoolsd-root.log
2) 将制定目录下的文件进行压缩打包。要求用户必须存在,而且也支持对应压缩格式,目录也必须存在¶
a. 打包
[root@1 ~]# ansible -m shell -a 'mkdir -p /data/' web_servers2
3 | CHANGED | rc=0 >>
[root@1 ~]# ansible -m archive -a "path=/tmp/logs/* dest=/data/logs.tgz format=gz mode=0755 owner=bin group=bin exclusion_patterns=dnf.log remove=yes" web_servers2
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"archived": [
"/tmp/logs/dnf.librepo.log",
"/tmp/logs/dnf.rpm.log",
"/tmp/logs/hawkey.log",
"/tmp/logs/vmware-network.1.log",
"/tmp/logs/vmware-network.2.log",
"/tmp/logs/vmware-network.3.log",
"/tmp/logs/vmware-network.4.log",
"/tmp/logs/vmware-network.5.log",
"/tmp/logs/vmware-network.6.log",
"/tmp/logs/vmware-network.7.log",
"/tmp/logs/vmware-network.8.log",
"/tmp/logs/vmware-network.9.log",
"/tmp/logs/vmware-network.log",
"/tmp/logs/vmware-vmsvc-root.log",
"/tmp/logs/vmware-vmtoolsd-root.log"
],
"arcroot": "/tmp/logs/",
"changed": true,
"dest": "/data/logs.tgz",
"dest_state": "archive",
"expanded_exclude_paths": [],
"expanded_paths": [
"/tmp/logs/dnf.librepo.log",
"/tmp/logs/dnf.log",
"/tmp/logs/dnf.rpm.log",
"/tmp/logs/hawkey.log",
"/tmp/logs/vmware-network.1.log",
"/tmp/logs/vmware-network.2.log",
"/tmp/logs/vmware-network.3.log",
"/tmp/logs/vmware-network.4.log",
"/tmp/logs/vmware-network.5.log",
"/tmp/logs/vmware-network.6.log",
"/tmp/logs/vmware-network.7.log",
"/tmp/logs/vmware-network.8.log",
"/tmp/logs/vmware-network.9.log",
"/tmp/logs/vmware-network.log",
"/tmp/logs/vmware-vmsvc-root.log",
"/tmp/logs/vmware-vmtoolsd-root.log"
],
"gid": 1,
"group": "bin",
"missing": [],
"mode": "0755",
"owner": "bin",
"size": 8606,
"state": "file",
"uid": 1
}
b. 查看验证
[root@1 ~]# ansible -m shell -a "ls -l /tmp/logs/;echo '----------';ls -l /data/;echo '----------';tar tvf /data/logs.tgz" web_servers2
3 | CHANGED | rc=0 >>
总用量 76
-rw-r--r-- 1 root root 74101 8月 16 11:53 dnf.log
----------
总用量 12
-rwxr-xr-x 1 bin bin 8606 8月 16 11:54 logs.tgz
----------
-rw-r--r-- root/root 32831 2026-08-16 11:53 dnf.librepo.log
-rw-r--r-- root/root 2397 2026-08-16 11:53 dnf.rpm.log
-rw-r--r-- root/root 60 2026-08-16 11:53 hawkey.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.1.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.2.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.3.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.4.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.5.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.6.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.7.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.8.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.9.log
-rw------- root/root 217 2026-08-16 11:53 vmware-network.log
-rw------- root/root 56214 2026-08-16 11:53 vmware-vmsvc-root.log
-rw------- root/root 7500 2026-08-16 11:53 vmware-vmtoolsd-root.log
可以看到/tmp/logs/目录中只还有dnf.log文件在,/data/logs.tgz文件权限是755正常,而且被排除的/data/logs.tgz归档压缩文件中也没有/data/logs.tgz被正常排除了。
九. unarchive模块¶
1. 简介¶
unarchive模块主要用于压缩包解压的功能
2. 常见参数¶
src: 源路径。可以是ansible主机上的路径也可以是远程主机上的路径
copy: 默认值为yes
当copy=yes时,拷贝的文件是从ansible主机复制到远程主机上
当copy=no时,会在远程主机上寻找src源文件
remote_src: 和copy功能相同且互相排斥。
当remote_src=yes时,会在远程主机寻找src源文件
当remote_ser=no时,拷贝的文件是从ansible主机复制到远程主机
dest: 远程主机上的目标路径
mode: 设置解压后的文件权限
注意: 有时候会因为ansible版本文件导致无法远程解压,可以用copy+shell模块解决
3. 命令格式¶
unarchive模块在ansible使用的时候,标准的写法为
ansible <目标主机> -m unarchive -a '属性1=值1 属性2=值2 ... 属性n=值n'
4. 实践¶
a. 准备工作目录
[root@1 ~]# tar zcf passwd.tar.gz /etc/passwd
tar: 从成员名中删除开头的“/”
[root@1 ~]# ansible -m shell -a "mkdir -p /data/passwd/etc" web_servers2
3 | CHANGED | rc=0 >>
b. 将本地目录文件解压到指定位置
[root@1 ~]# ansible -m unarchive -a "src=passwd.tar.gz remote_src=no dest=/data/passwd/etc/ mode=0642" web_servers2
3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/data/passwd/etc/",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/data/passwd/etc",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1786856169.7440853-2202-225484372245780/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "0755",
"owner": "root",
"size": 17,
"src": "/root/.ansible/tmp/ansible-tmp-1786856169.7440853-2202-225484372245780/source",
"state": "directory",
"uid": 0
}
c. 查看验证