Ansible 临时命令与常用模块实操指南
Ansible 临时命令与常用模块使用
Ansible 临时命令(Ad-hoc 模式)通过调用不同模块执行单条任务,适用于临时性操作。以下是模块查询方法、核心模块语法及实操案例,覆盖用户管理、文件操作、软件部署等常见场景。
一、模块查询基础
1. 查看系统已安装的所有模块
ansible-doc -l
2. 查看指定模块的帮助文档(以 ping
为例)
# 查看模块参数、用法及示例
[root@master ~]# ansible-doc ping
> ANSIBLE.BUILTIN.PING (/usr/lib/python3.9/site-packages/ansible/modules/ping.p>A trivial test module, this module always returns `pong' onsuccessful contact. It does not make sense in playbooks, butit is useful from `/usr/bin/ansible' to verify the ability tologin and that a usable Python is configured. This is NOT ICMPping, this is just a trivial test module that requires Pythonon the remote-node. For Windows targets, use the[ansible.windows.win_ping] module instead. For Networktargets, use the [ansible.netcommon.net_ping] module instead.ADDED IN: historicalOPTIONS (= is mandatory):- dataData to return for the `ping' return value.If this parameter is set to `crash', the module will cause an/EXA #查看示例EXAMPLES:
# Test we can logon to 'webservers' and execute python with json lib.
# ansible webservers -m ansible.builtin.ping- name: Example from an Ansible Playbookansible.builtin.ping:- name: Induce an exception to see what happensansible.builtin.ping:data: crashRETURN VALUES:
- pingValue provided with the data parameter.returned: success
二、临时命令语法格式
ansible <主机/分组> -m <模块名> -a '<模块参数>'# <主机/分组>:Inventory 中定义的主机名或分组名(如 node1、all)
# -m <模块名>:指定要调用的模块(如 user、copy)
# -a '<模块参数>':模块的具体配置(键值对格式,空格分隔)
执行结果状态说明
- 绿色:执行成功,目标主机无变更;
- 黄色:执行成功,目标主机产生变更(如新建用户、修改文件);
- 红色:执行失败(如参数错误、权限不足)。
三、常用模块实操案例
(一)用户管理模块:user
用于添加、删除、修改用户账户及属性。
参数 | 功能说明 |
---|---|
name | 必选,指定用户名(如 name=newbie ) |
uid | 指定用户的 UID(如 uid=400 ),需确保唯一性 |
state | 指定用户状态:present (创建 / 保留用户,默认)、absent (删除用户) |
password | 设置用户密码,需传入加密后的密码(如 openssl passwd -1 生成的密文) |
update_password | 密码更新策略:always (始终更新)、on_create (仅创建时设置,默认) |
create_home | 是否创建用户家目录:yes (默认)、no |
shell | 指定用户登录 Shell(如 shell=/bin/bash ,默认随系统配置) |
group | 指定用户的主组(如 group=zhang3 ) |
在 node1
上创建用户 newbie
,指定 UID=400:
[student@master ansible]$ ansible node1 -m user -a 'name=newbie uid=400 state=present'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"comment": "","create_home": true,"group": 1001,"home": "/home/newbie","name": "newbie","shell": "/bin/bash","state": "present","stderr": "useradd warning: newbie's uid 400 outside of the UID_MIN 1000 and UID_MAX 60000 range.\n","stderr_lines": ["useradd warning: newbie's uid 400 outside of the UID_MIN 1000 and UID_MAX 60000 range."],"system": false,"uid": 400
}
创建用户 zhang3
,指定密码(若用户存在则仅更改密码):
# 需要使用加密密码
[student@master ansible]$ openssl passwd -1 123
$1$NjRojGFn$y4oEdLR3M8PQvnPLqX2al1[student@master ansible]$ ansible node1 -m user -a 'name=zhang3 state=present password="$1$NjRojGFn$y4oEdLR3M8PQvnPLqX2al1" update_password=always'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"comment": "","create_home": true,"group": 1002,"home": "/home/zhang3","name": "zhang3","password": "NOT_LOGGING_PASSWORD","shell": "/bin/bash","state": "present","system": false,"uid": 1001
}
创建用户 zhang3
,指定密码(若用户存在不对密码做更改)
[student@master ansible]$ openssl passwd -1 555
$1$qfOdfqaN$.cPyVgM/72j/uDUCvAj270
[student@master ansible]$ ansible node1 -m user -a 'name=zhang3 password="$1$qfOdfqaN$.cPyVgM/72j/uDUCvAj270" update_password=on_create'
node1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"append": false,"changed": false,"comment": "","group": 1002,"home": "/home/zhang3","move_home": false,"name": "zhang3","password": "NOT_LOGGING_PASSWORD","shell": "/bin/bash","state": "present","uid": 1001
}
(二)命令执行模块:shell
执行远程主机的 Shell 命令(支持管道、重定向等复杂语法)。
参数 | 功能说明 |
---|---|
args / 直接跟命令 | 必选,指定要执行的 Shell 命令(如 a='userdel -r newbie' ,删除用户及家目录) |
chdir | 执行命令前切换到指定目录(如 chdir=/tmp ) |
creates | 若指定文件存在,则不执行命令(避免重复操作,如 creates=/aaa/file1 ) |
removes | 若指定文件不存在,则不执行命令(如 removes=/aaa/file1 ) |
在 node1
上删除用户 newbie
(含家目录);
[student@master ansible]$ ansible node1 -m shell -a 'userdel -r newbie'
node1 | CHANGED | rc=0 >>
(三)文件复制模块:copy
将本地文件复制到远程主机,并可指定权限、所有者。
参数 | 功能说明 |
---|---|
src | 必选,本地文件路径(如 src=/etc/fstab ) |
dest | 必选,远程主机目标路径(如 dest=/var/tmp/fstab ) |
owner | 指定远程文件的所有者(如 owner=zhang3 ) |
group | 指定远程文件的所属组(如 group=root ) |
mode | 指定远程文件的权限(如 mode=0644 ,八进制格式,需加前导 0) |
backup | 复制前是否备份远程已有文件:yes (备份为 dest.xxx~ )、no (默认) |
content | 直接写入内容到远程文件(替代 src ,如 content="hello" 生成含 hello 的文件) |
将本地 /etc/fstab
复制到远程 用户node2的 /var/tmp/fstab
:
[student@master ansible]$ ansible node2 -m copy -a 'src=/etc/fstab dest=/var/tmp/fstab'
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/var/tmp/fstab","gid": 0,"group": "root","md5sum": "4ab05d98a2058dd0703b9e57993802e8","mode": "0644","owner": "root","secontext": "unconfined_u:object_r:user_home_t:s0","size": 579,"src": "/home/student/.ansible/tmp/ansible-tmp-1756266300.572999-1419-214666091543219/source","state": "file","uid": 0
}
复制文件到node1并指定所有者为 zhang3
、所属组为 zhang3
:
[student@master ansible]$ ansible node1 -m copy -a 'src=/etc/fstab dest=/var/tmp/fstab owner=zhang3 group=zhang3'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/var/tmp/fstab","gid": 1002,"group": "zhang3","md5sum": "4ab05d98a2058dd0703b9e57993802e8","mode": "0644","owner": "zhang3","secontext": "unconfined_u:object_r:user_home_t:s0","size": 579,"src": "/home/student/.ansible/tmp/ansible-tmp-1756266706.9290698-1517-277259149331136/source","state": "file","uid": 1001
}查看权限
[student@master ansible]$ ansible node1 -m shell -a 'ls -l /var/tmp/fstab'
node1 | CHANGED | rc=0 >>
-rw-r--r--. 1 zhang3 zhang3 579 Aug 27 11:51 /var/tmp/fstab
(四)文件属性模块:file
设置文件/目录的权限、所有者、类型(如创建文件、目录、链接)。
参数 | 功能说明 |
---|---|
path /dest | 必选,指定远程文件 / 目录路径(如 path=/var/tmp/fstab ) |
state | 指定资源类型 / 状态: - file (确保为文件,默认) - directory (创建目录) - link (创建软链接) - hard (创建硬链接) - touch (创建空文件) - absent (删除文件 / 目录) |
mode | 设置权限(如 mode=g+w 给组加写权限,或 mode=0644 ) |
owner | 指定所有者(如 owner=root ) |
group | 指定所属组(如 group=root ) |
src | 仅用于链接:软链接 / 硬链接的源路径(如 src=/aaa/file1 state=link ) |
修改node1的 /var/tmp/fstab
的权限(组可写、其他可写),所有者、所属组为root
:
[student@master ansible]$ ansible node1 -m file -a 'path=/var/tmp/fstab mode=g+w mode=o+w owner=root group=root '
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"gid": 0,"group": "root","mode": "0646","owner": "root","path": "/var/tmp/fstab","secontext": "unconfined_u:object_r:user_home_t:s0","size": 579,"state": "file","uid": 0
}
在远程创建目录 /aaa
,指定所有者为zhang3,所属组为root
[student@master ansible]$ ansible node1 -m file -a 'path=/aaa owner=zhang3 group=root state=directory'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"gid": 0,"group": "root","mode": "0755","owner": "zhang3","path": "/aaa","secontext": "unconfined_u:object_r:default_t:s0","size": 6,"state": "directory","uid": 1001
}
在远程创建空文件 /aaa/file1
,权限为0644:
[student@master ansible]$ ansible node1 -m file -a 'path=/aaa/file1 mode=0644 state=touch'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"dest": "/aaa/file1","gid": 0,"group": "root","mode": "0644","owner": "root","secontext": "unconfined_u:object_r:default_t:s0","size": 0,"state": "file","uid": 0
}
创建软链接:/aaa/abc
指向 /aaa/file1
:
[student@master ansible]$ ansible node1 -m file -a 'dest=/aaa/abc src=/aaa/file1 state=link'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"dest": "/aaa/abc","gid": 0,"group": "root","mode": "0777","owner": "root","secontext": "unconfined_u:object_r:default_t:s0","size": 10,"src": "/aaa/file1","state": "link","uid": 0
}创建硬链接同上,仅需将state=link改为state=hard
删除远程 /aaa/file1
(文件/目录均适用):
[student@master ansible]$ ansible node1 -m file -a 'path=/aaa/file1 state=absent'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"path": "/aaa/file1","state": "absent"
}
(五)YUM 仓库配置模块:yum_repository
在远程主机配置 YUM 仓库(生成 .repo
文件)。
参数 | 功能说明 |
---|---|
file | 必选,生成的 .repo 文件名(如 file=server 对应 /etc/yum.repos.d/server.repo ) |
name | 必选,仓库 ID(.repo 文件中 [NAME] 部分,如 name=BASE ) |
description | 仓库描述(如 description="software base" ) |
baseurl | 必选,仓库源地址(如 baseurl=http://ansible.example.com/rhel9/BaseOS ) |
enabled | 是否启用仓库:yes (默认)、no |
gpgcheck | 是否校验 GPG 签名:yes (默认)、no |
gpgkey | GPG 密钥文件地址(如 gpgkey=http://xxx/RPM-GPG-KEY-redhat-release ) |
为所有主机配置 BASE
仓库(指向远程源):
[student@master ansible]$ ansible all -m yum_repository -a 'file=server name=BASE description="software base" baseurl=http://ansible.example.com/rhel9/BaseOS enabled=yes gpgcheck=yes gpgkey=http://ansible.example.com/rhel9/RPM-GPG-KEY-redhat-release'
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "BASE","state": "present"
}
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "BASE","state": "present"
}
node3 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "BASE","state": "present"
}
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "BASE","state": "present"
}
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "BASE","state": "present"
}
为所有主机配置 STREAM
仓库;
[student@master ansible]$ ansible all -m yum_repository -a 'file=server name=STREAM description="software stream" baseurl=http://ansible.example.com/rhel9/AppStream enabled=yes gpgcheck=yes gpgkey=http://ansible.example.com/rhel9/RPM-GPG-KEY-redhat-release'
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "STREAM","state": "present"
}
node3 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "STREAM","state": "present"
}
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "STREAM","state": "present"
}
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"repo": "STREAM","state": "present"
}
(六)软件安装模块:yum
通过 YUM 管理器安装/卸载软件包(适用于 RHEL/CentOS 系统)。
参数 | 功能说明 |
---|---|
name | 必选,软件包名(单个包如 name=httpd ,多个包如 name=httpd,nginx ) |
state | 软件状态: - installed /present (安装软件,默认) - removed /absent (卸载软件) - latest (升级到最新版本) |
update_cache | 安装前是否更新 YUM 缓存:yes 、no (默认) |
disable_gpg_check | 禁用 GPG 校验:yes 、no (默认) |
所有主机安装 httpd
:
[student@master ansible]$ ansible all -m yum -a 'name=httpd state=installed'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Installed: httpd-filesystem-2.4.53-7.el9.noarch","Installed: mod_http2-1.15.19-2.el9.x86_64","Installed: httpd-tools-2.4.53-7.el9.x86_64","Installed: apr-util-openssl-1.6.1-20.el9.x86_64","Installed: mod_lua-2.4.53-7.el9.x86_64","Installed: httpd-2.4.53-7.el9.x86_64","Installed: redhat-logos-httpd-90.4-1.el9.noarch","Installed: mailcap-2.1.49-5.el9.noarch","Installed: apr-1.7.0-11.el9.x86_64","Installed: apr-util-1.6.1-20.el9.x86_64","Installed: apr-util-bdb-1.6.1-20.el9.x86_64","Installed: httpd-core-2.4.53-7.el9.x86_64"]
}
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Installed: httpd-filesystem-2.4.53-7.el9.noarch","Installed: mod_http2-1.15.19-2.el9.x86_64","Installed: httpd-tools-2.4.53-7.el9.x86_64","Installed: apr-util-openssl-1.6.1-20.el9.x86_64","Installed: mod_lua-2.4.53-7.el9.x86_64","Installed: httpd-2.4.53-7.el9.x86_64","Installed: redhat-logos-httpd-90.4-1.el9.noarch","Installed: mailcap-2.1.49-5.el9.noarch","Installed: apr-1.7.0-11.el9.x86_64","Installed: apr-util-1.6.1-20.el9.x86_64","Installed: apr-util-bdb-1.6.1-20.el9.x86_64","Installed: httpd-core-2.4.53-7.el9.x86_64"]
}
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Installed: httpd-filesystem-2.4.53-7.el9.noarch","Installed: mod_http2-1.15.19-2.el9.x86_64","Installed: httpd-tools-2.4.53-7.el9.x86_64","Installed: apr-util-openssl-1.6.1-20.el9.x86_64","Installed: mod_lua-2.4.53-7.el9.x86_64","Installed: httpd-2.4.53-7.el9.x86_64","Installed: redhat-logos-httpd-90.4-1.el9.noarch","Installed: mailcap-2.1.49-5.el9.noarch","Installed: apr-1.7.0-11.el9.x86_64","Installed: apr-util-1.6.1-20.el9.x86_64","Installed: apr-util-bdb-1.6.1-20.el9.x86_64","Installed: httpd-core-2.4.53-7.el9.x86_64"]
}
node3 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Installed: httpd-filesystem-2.4.53-7.el9.noarch","Installed: mod_http2-1.15.19-2.el9.x86_64","Installed: httpd-tools-2.4.53-7.el9.x86_64","Installed: apr-util-openssl-1.6.1-20.el9.x86_64","Installed: mod_lua-2.4.53-7.el9.x86_64","Installed: httpd-2.4.53-7.el9.x86_64","Installed: redhat-logos-httpd-90.4-1.el9.noarch","Installed: mailcap-2.1.49-5.el9.noarch","Installed: apr-1.7.0-11.el9.x86_64","Installed: apr-util-1.6.1-20.el9.x86_64","Installed: apr-util-bdb-1.6.1-20.el9.x86_64","Installed: httpd-core-2.4.53-7.el9.x86_64"]
}
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Installed: httpd-filesystem-2.4.53-7.el9.noarch","Installed: mod_http2-1.15.19-2.el9.x86_64","Installed: httpd-tools-2.4.53-7.el9.x86_64","Installed: apr-util-openssl-1.6.1-20.el9.x86_64","Installed: mod_lua-2.4.53-7.el9.x86_64","Installed: httpd-2.4.53-7.el9.x86_64","Installed: redhat-logos-httpd-90.4-1.el9.noarch","Installed: mailcap-2.1.49-5.el9.noarch","Installed: apr-1.7.0-11.el9.x86_64","Installed: apr-util-1.6.1-20.el9.x86_64","Installed: apr-util-bdb-1.6.1-20.el9.x86_64","Installed: httpd-core-2.4.53-7.el9.x86_64"]
}
[student@master ansible]$ ansible node4 -m yum -a 'name=httpd state=removed'
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Removed: httpd-2.4.53-7.el9.x86_64"]
}
卸载 软件httpd
:
state=absent也能够卸载软件
[student@master ansible]$ ansible node4 -m yum -a 'name=httpd state=removed'
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "","rc": 0,"results": ["Removed: httpd-2.4.53-7.el9.x86_64"]
}
(七)服务管理模块:service
启动、停止、重启服务,并设置开机自启/禁用。
参数 | 功能说明 |
---|---|
name | 必选,服务名(如 name=httpd ,需与系统服务名一致) |
state | 服务运行状态: - started (启动服务) - stopped (停止服务) - restarted (重启服务) - reloaded (重载配置) |
enabled | 是否开机自启:yes (启用)、no (禁用)、masked (屏蔽服务) |
daemon_reload | 重新加载 systemd 配置(如服务文件修改后,daemon_reload=yes ) |
设置node1启动 httpd
服务,并设置开机自启:
[student@master ansible]$ ansible node1 -m service -a 'name=httpd state=started enabled=yes'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"enabled": true,"name": "httpd","state": "started","status": {"AccessSELinuxContext": "system_u:object_r:httpd_unit_file_t:s0","ActiveEnterTimestampMonotonic": "0","ActiveExitTimestampMonotonic": "0",********省略*********"UnitFileState": "disabled","UtmpMode": "init","Wants": "httpd-init.service","WatchdogSignal": "6","WatchdogTimestampMonotonic": "0","WatchdogUSec": "infinity"}
}
重启 httpd
服务;
[student@master ansible]$ ansible node1 -m service -a 'name=httpd state=restarted'node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"name": "httpd","state": "started","status": {"AccessSELinuxContext": "system_u:object_r:httpd_unit_file_t:s0","ActiveEnterTimestamp": "Wed 2025-08-27 12:31:39 CST","ActiveEnterTimestampMonotonic": "6241006629","ActiveExitTimestampMonotonic": "0",*******省略*******"WatchdogSignal": "6","WatchdogTimestampMonotonic": "0","WatchdogUSec": "0"}
}
(八)文件拉取模块:fetch
从远程主机拉取文件到本地(仅支持文件,不支持目录;本地存储以主机名分目录)。
参数 | 功能说明 |
---|---|
src | 必选,远程文件路径(如 src=/etc/fstab ,必须是文件,不能是目录) |
dest | 必选,本地存储路径(如 dest=/tmp/ ,拉取后默认生成 dest/主机名/src路径 结构) |
flat | 是否取消 “主机名目录” 层级:yes (直接存为 dest/文件名 ,如 dest=/tmp/fstab )、no (默认) |
validate_checksum | 校验文件完整性:yes (默认)、no |
拉取所有远程主机的 /etc/fstab
到本地 /tmp
(本地路径:/tmp/<主机名>/etc/fstab
):
[student@master ansible]$ ansible all -m fetch -a 'src=/etc/fstab dest=/tmp/'
node4 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/node4/etc/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}
node1 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/node1/etc/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}
node3 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/node3/etc/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}
node2 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/node2/etc/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}
node5 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/node5/etc/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}[student@master ansible]$ ls /tmp/
node1
node2
node3
node4
node5
[student@master etc]$ ls
fstab
[student@master etc]$ pwd
/tmp/node1/etc
拉取 node1
的 /etc/fstab
到本地 /tmp/fstab
(不创建主机名目录):
[student@master ansible]$ ansible node1 -m fetch -a 'src=/etc/fstab dest=/tmp/ flat=yes'
node1 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/fstab","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}[student@master ansible]$ ls /tmp/
fstab
node1
node2
node3
node4
node5
拉取所有node2的 /etc/fstab
到本地,文件名含主机名(如 /tmp/fstab-node1
):
[student@master ansible]$ ansible node2 -m fetch -a 'src=/etc/fstab dest=/tmp/fstab-{{inventory_hostname}} flat=yes'
node2 | CHANGED => {"changed": true,"checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","dest": "/tmp/fstab-node2","md5sum": "4ab05d98a2058dd0703b9e57993802e8","remote_checksum": "741593a3c559105fd9a9af53e25a3684ce00a57e","remote_md5sum": null
}
[student@master ansible]$ ls /tmp/
fstab
fstab-node2
node1
node2
node3
node4
node5
(九)防火墙配置模块:firewalld
管理 firewalld 防火墙规则(端口、服务、富规则)。
参数 | 功能说明 |
---|---|
service | 允许的服务名(如 service=http ,需 firewalld 预定义服务) |
port | 允许的端口(如 port=80/tcp ,格式 端口/协议 ) |
rich_rule | 富规则(复杂规则,如 rich_rule="rule family=ipv4 source address=192.168.122.0/24 service name=http accept" ) |
zone | 防火墙区域(如 zone=public ,默认 public) |
state | 规则状态:enabled (启用规则)、disabled (禁用规则) |
permanent | 是否永久生效:yes (重启 firewalld 后保留)、no (临时生效,默认) |
immediate | 是否立即加载规则(配合 permanent=yes 使用,immediate=yes 实现 “永久 + 即时生效”) |
所有主机允许 http
服务流量(永久生效,立即加载):
[student@master ansible]$ ansible all -m firewalld -a 'service=http permanent=yes state=enabled immediate=yes'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
node3 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
允许 192.168.122.0/24
网段访问 http
服务(永久生效):
[student@master ansible]$ ansible all -m firewalld -a 'zone=public rich_rule="rule family=ipv4 source address=192.168.122.0/24 service name=http accept" permanent=yes state=enabled immediate=yes'
node2 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed rich_rule rule family=ipv4 source address=192.168.122.0/24 service name=http accept to enabled"
}
node3 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed rich_rule rule family=ipv4 source address=192.168.122.0/24 service name=http accept to enabled"
}
node4 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed rich_rule rule family=ipv4 source address=192.168.122.0/24 service name=http accept to enabled"
}
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed rich_rule rule family=ipv4 source address=192.168.122.0/24 service name=http accept to enabled"
}
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "Permanent and Non-Permanent(immediate) operation, Changed rich_rule rule family=ipv4 source address=192.168.122.0/24 service name=http accept to enabled"
}
(十)文件内容替换模块:replace
参数 | 功能说明 |
---|---|
path | 必选,目标文件路径(如 path=/aaa/file11 ) |
regexp | 必选,匹配内容的正则表达式(如 regexp="aa" 匹配所有 “aa”) |
replace | 必选,替换后的内容(如 replace="zz" 将 “aa” 替换为 “zz”) |
backup | 是否备份原文件:yes (备份为 path.xxx~ )、no (默认) |
before | 仅替换 “指定行之前” 的内容(如 before="abc" 替换 abc 之前的匹配项) |
after | 仅替换 “指定行之后” 的内容(如 after="abc" 替换 abc 之后的匹配项) |
通过正则表达式替换文件中的字符串(支持备份)。
创建一个文件:
[student@master ansible]$ ansible node1 -m shell -a 'echo aa bb abc aa asd qwe aa > /aaa/file11'
node1 | CHANGED | rc=0 >>[student@master ansible]$ ansible node1 -m shell -a 'cat /aaa/file11'
node1 | CHANGED | rc=0 >>
aa bb abc aa asd qwe aa
将node1中 /aaa/file11
中的 aa
替换为 zz
:
[student@master ansible]$ ansible node1 -m replace -a 'path=/aaa/file11 regexp="aa" replace="zz"'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": "3 replacements made","rc": 0
}[student@master ansible]$ ansible node1 -m shell -a 'cat /aaa/file11'
node1 | CHANGED | rc=0 >>
zz bb abc zz asd qwe zz
替换字符串并备份原文件(备份文件后缀为 .bak
):
[student@master ansible]$ ansible node1 -m replace -a 'path=/aaa/file11 regexp="zz" replace="kk" backup=yes'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"backup_file": "/aaa/file11.16916.2025-08-27@12:58:34~","changed": true,"msg": "3 replacements made","rc": 0
}
[student@master ansible]$ ansible node1 -m shell -a 'cat /aaa/file11'
node1 | CHANGED | rc=0 >>
kk bb abc kk asd qwe kk
[student@master ansible]$ ansible node1 -m shell -a 'ls /aaa/'
node1 | CHANGED | rc=0 >>
file11
file11.16916.2025-08-27@12:58:34~
[student@master ansible]$ ansible node1 -m shell -a 'cat /aaa/file11.16916.2025-08-27@12:58:34~'
node1 | CHANGED | rc=0 >>
zz bb abc zz asd qwe zz
(十一)磁盘分区模块:parted
管理磁盘分区(新建、删除分区)。
参数 | 功能说明 |
---|---|
device | 必选,磁盘设备路径(如 device=/dev/vdb ) |
number | 必选,分区编号(如 number=1 表示第一个分区) |
state | 分区状态:present (创建分区)、absent (删除分区) |
part_type | 分区类型:primary (主分区)、extended (扩展分区)、logical (逻辑分区) |
part_start | 分区起始点 |
part_end | 分区结束点 |
在 node5
的 /dev/vdb
上新建扩展分区(编号 1,起始 1GiB,结束 20GiB):
[student@master ansible]$ ansible node5 -m parted -a 'device=/dev/vdb number=1 part_type=extended part_start=1GiB part_end=20GiB state=present'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"disk": {"dev": "/dev/vdb","logical_block": 512,"model": "Virtio Block Device","physical_block": 512,"size": 52428800.0,"table": "msdos","unit": "kib"},"partitions": [{"begin": 1048576.0,"end": 20971520.0,"flags": ["lba"],"fstype": "","name": "","num": 1,"size": 19922944.0,"unit": "kib"}],"script": "unit KiB mklabel msdos mkpart extended 1GiB 20GiB"
}
[student@master ansible]$ ansible node5 -m shell -a 'lsblk /dev/vdb'
node5 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vdb 252:16 0 50G 0 disk
└─vdb1 252:17 0 1K 0 part
在扩展分区内新建逻辑分区(编号 ,起始 1.1GiB,结束 10GiB):
[student@master ansible]$ ansible node5 -m parted -a 'device=/dev/vdb number=5 part_type=logical part_start=1.1GiB part_end=10GiB state=present'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"disk": {"dev": "/dev/vdb","logical_block": 512,"model": "Virtio Block Device","physical_block": 512,"size": 52428800.0,"table": "msdos","unit": "kib"},"partitions": [{"begin": 1048576.0,"end": 20971520.0,"flags": ["lba"],"fstype": "","name": "","num": 1,"size": 19922944.0,"unit": "kib"},{"begin": 1153434.0,"end": 10485760.0,"flags": [],"fstype": "","name": "","num": 5,"size": 9332327.0,"unit": "kib"}],"script": "unit KiB mkpart logical 1.1GiB 10GiB"
}
(十二)文件系统模块:filesystem
为分区创建文件系统如 XFS、EXT4(格式化为XFS.EXT4类型)。
参数 | 功能说明 |
---|---|
dev | 必选,分区设备路径(如 dev=/dev/vdb5 ) |
fstype | 必选,文件系统类型(如 fstype=xfs 、fstype=ext4 ) |
force | 强制创建(覆盖已有文件系统,force=yes ,谨慎使用) |
opts | 创建文件系统的额外参数(如 opts="-m 5" 给 EXT4 预留 5% 空间) |
为 node5
的 /dev/sda5
分区创建 XFS 文件系统:
[student@master ansible]$ ansible node5 -m filesystem -a 'fstype=xfs dev=/dev/vdb5'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true
}
(十三)挂载模块:mount
管理文件系统挂载(临时挂载、写入 /etc/fstab
永久挂载)。
参数 | 功能说明 |
---|---|
path /name | 必选,挂载点路径(如 path=/fs ,需先创建目录) |
src | 必选,挂载源(设备路径如 src=/dev/vdb5 ,或 UUID 如 src="UUID=xxx" ) |
fstype | 必选,文件系统类型(如 fstype=xfs ,需与分区格式一致) |
state | 挂载状态: - mounted (挂载并写入 /etc/fstab 永久生效) - present (仅写入 /etc/fstab ,不立即挂载) - unmounted (卸载,保留 /etc/fstab ) - absent (卸载并删除 /etc/fstab 配置) |
opts | 挂载选项(如 opts=defaults ,默认 defaults ) |
在 node1
上创建挂载点 /fs
略
查看 /dev/vda5
的 UUID:
[student@master ansible]$ ansible node5 -m shell -a 'blkid /dev/vdb5'
node5 | CHANGED | rc=0 >>
/dev/vdb5: UUID="7facb414-b6a8-403d-9b28-22f3ebb5c9e5" TYPE="xfs" PARTUUID="ebc69adf-05"
将 /dev/vda5
永久挂载到 /fs
(写入 /etc/fstab
):
[student@master ansible]$ ansible node5 -m mount -a 'path=/fs src="UUID=7facb414-b6a8-403d-9b28-22f3ebb5c9e5" fstype=xfs state=absent'
node5 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"backup_file": "","boot": "yes","changed": false,"dump": "0","fstab": "/etc/fstab","fstype": "xfs","name": "/fs","opts": "defaults","passno": "0","src": "UUID=7facb414-b6a8-403d-9b28-22f3ebb5c9e5"
}
(十四)LVM 卷组模块:lvg
创建、删除 LVM 卷组。
参数 | 功能说明 |
---|---|
vg | 必选,卷组名(如 vg=vg0 ) |
pvs | 必选,组成卷组的物理卷(如 pvs=/dev/vdb5 ,多个物理卷用逗号分隔) |
state | 卷组状态:present (创建卷组)、absent (删除卷组) |
pesize | PE(物理扩展块)大小(如 pesize=16M ,默认 4M,需是 2 的幂) |
force | 强制创建(如覆盖已有卷组,force=yes ,谨慎使用) |
在 node5
上创建卷组 vg0
,使用 /dev/vda5
分区,PE 大小 16M:
[student@master ansible]$ ansible node5 -m lvg -a 'vg=vg0 pesize=16M pvs=/dev/vdb5'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true
}
(十五)LVM 逻辑卷模块:lvol
创建、扩容 LVM 逻辑卷。
参数 | 功能说明 |
---|---|
lv | 必选,逻辑卷名(如 lv=lv0 ) |
vg | 必选,逻辑卷所属的卷组(如 vg=vg0 ) |
size | 逻辑卷大小(如 size=1000M 、size=+500M 表示扩容 500M) |
state | 逻辑卷状态:present (创建 / 保留)、absent (删除) |
resizefs | 扩容时是否自动扩展文件系统:yes (需文件系统支持,如 XFS/EXT4)、no (默认) |
在卷组 vg0
上创建 1000M 的逻辑卷 lv0
:
[student@master ansible]$ ansible node5 -m lvol -a 'lv=lv0 size=1000M vg=vg0'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"msg": ""
}
在线扩容 lv0
到 1600M(自动扩展文件系统);
# 为逻辑卷 lv0 格式化为 XFS 文件系统(加 -b 提权)
[student@master ansible]$ ansible node5 -m filesystem -a 'fstype=xfs dev=/dev/vg0/lv0'
node5 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true
}# 扩容到 1600M
[student@master ansible]$ ansible node5 -m lvol -a 'lv=lv0 size=1600M vg=vg0 resizefs=yes'
node5 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false, "lv": "lv0","size": 1600.0,"vg": "vg0"
}
(十六)计划任务模块:cron
管理远程主机的 crontab 计划任务。
参数 | 功能说明 |
---|---|
name | 必选,任务名称(用于标识和删除任务,如 name="shuchu" ) |
job | 必选,计划任务执行的命令(如 job="/bin/echo I AM RHCE" ) |
user | 执行任务的用户(如 user=root ,默认当前用户) |
state | 任务状态:present (创建任务)、absent (删除任务) |
minute /hour /day /month /weekday | cron 时间字段: - minute=0 (分钟,0-59) - hour=14 (小时,0-23) - day=* (日,1-31) - month=* (月,1-12) - weekday=* (周,0-6,0 = 周日) |
special_time | 特殊时间(替代上述时间字段):reboot (重启时)、daily (每天)等 |
在 node1
上添加计划任务:每天 14:00 以 root
执行 /bin/echo I AM RHCE
:
[student@master ansible]$ ansible node1 -m cron -a 'name="shuchu" job="/bin/echo I AM RHCE" user=root minute=0 hour=14 state=present'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"envs": [],"jobs": ["shuchu"]
}
删除上述计划任务;
[student@master ansible]$ ansible node1 -m cron -a 'name="shuchu" state=absent
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"envs": [],"jobs": []
}
(十七)文件下载模块:get_url
从 HTTP/HTTPS/FTP 下载文件到远程主机。
参数 | 功能说明 |
---|---|
url | 必选,下载源地址(如 url=http://ansible.example.com/file2 ) |
dest | 必选,远程主机目标路径(如 dest=/tmp/file2 ) |
owner /group /mode | 同 copy 模块,设置下载后文件的所有者、所属组、权限 |
force | 是否强制重新下载(即使目标文件已存在):yes 、no (默认,校验 MD5 一致则不下载) |
validate_certs | HTTPS 下载时是否校验证书:yes (默认)、no (忽略证书错误) |
timeout | 下载超时时间(如 timeout=30 ,单位秒,默认 10 秒) |
在 node1
上下载文件(如远程 http://ansilbe.example.com/file2
到 /tmp/
):
[student@master ansible]$ ansible node1 -m get_url -a 'url=http://ansible.example.com/file2 dest=/tmp/file2'
node1 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": true,"checksum_dest": null,"checksum_src": "da39a3ee5e6b4b0d3255bfef95601890afd80709","dest": "/tmp/file2","elapsed": 0,"gid": 0,"group": "root","md5sum": "d41d8cd98f00b204e9800998ecf8427e","mode": "0644","msg": "OK (0 bytes)","owner": "root","secontext": "unconfined_u:object_r:user_home_t:s0","size": 0,"src": "/home/student/.ansible/tmp/ansible-tmp-1756305253.1840584-1389-107803694225127/tmpyo819el6","state": "file","status_code": 200,"uid": 0,"url": "http://ansible.example.com/file2"
}
需求 | 命令 |
---|---|
在 node1 上下载文件(如远程 http://example.com/file.tar.gz 到 /tmp/ ) | ansible node1 -m get_url -a 'url=http://example.com/file.tar.gz dest=/tmp/file.tar.gz' |
强制覆盖已存在的文件 | ansible node1 -m get_url -a 'url=http://example.com/file.tar.gz dest=/tmp/file.tar.gz force=yes' |