Ansible
Ansible 是一款自动化运维工具。 用来批量操控多台 Linux 服务器批量执行命令、安装软件、部署程序、配置文件。假设需要管理几十台服务器 不用一台一台 ssh 登录手动敲命令。 Ansible 相当于一个批量遥控器临时干活Ad-Hoc 单行命令成套流水线部署Playbook 剧本ansible部署指南1.1 安装ansible首先部署三台虚拟机两台rocky9.6、一台centos7在第一台rocky9.6上面安装ansible[rootserver1 ~]# yum install -y ansible-core.x86_641.2 ansible配置文件Ansible 主机清单 Inventory# vim /etc/ansible/hosts 添加如下配置 192.168.223.161 [web] 192.168.223.162 [db] 192.168.223.181 [rocky9] server2 [centos7] host11.3 ansible ad-hocad-hoc临时命令是 Ansible 中最直接、最快速的执行方式。它指的是通过单条命令快速完成一次性任务无需编写和保存 Playbook 剧本。这种模式非常适合日常运维中的临时检查、快速修复或简单配置变更。主要特点即时执行直接在命令行中调用 ansible 命令指定目标主机、模块和参数即可运行。无需持久化执行完成后不会保存为可重复使用的脚本适合一次性任务。灵活高效对于简单的、无需复杂流程的任务ad-hoc 命令比编写 Playbook 更快捷。学习与测试新手可以通过 ad-hoc 命令熟悉 Ansible 模块的基本用法也是验证模块功能的有效方式。基本语法ansible 目标主机或组 -m 模块名 -a 模块参数虽然 ad-hoc 命令方便快捷但对于需要多步骤、条件判断、错误处理或需要重复执行的复杂任务建议使用Playbook。Playbook 以 YAML 格式编写能够将任务流程、变量、模板等组织起来实现真正的自动化编排。ansible 模块2.1 测试主机连通性Ansible 第一次连接新机器需要先确认对方主机指纹ssh server2 ssh server1 ssh host1 ssh 192.168.223.161 ssh 192.168.223.162 ssh 192.168.223.181 [rootserver1 ~]# ansible * -m ping -k SSH password: 192.168.223.181 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python }, changed: false, ping: pong } host1 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python }, changed: false, ping: pong } server2 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: false, ping: pong } 192.168.223.162 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: false, ping: pong } 192.168.223.161 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: false, ping: pong }但是这样太麻烦了所以直接配置免密[rootserver1 ~]# ssh -keygen [rootserver1 ~]# ssh-copy-id 192.168.223.161 [rootserver1 ~]# ssh-copy-id 192.168.223.162 [rootserver1 ~]# ssh-copy-id 192.168.223.181 [rootserver1 ~]# ansible centos7 -m ping host1 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python }, changed: false, ping: pong }2.2 command 模块command 模块是 Ansible 最基础、最常用的模块之一用于在目标主机上执行简单的命令。它相当于在远程主机上直接运行一个 shell 命令但不经过远程主机的 shell 环境如 bash、sh因此不支持管道符|、重定向、、变量展开$VAR等 shell 特性。基本语法ansible 目标主机或组 -m command -a 命令示例查看目标主机监听的 TCP 端口[rootserver1 ansible]# ansible web -m command -a ss -ntl 192.168.223.162 | CHANGED | rc0 State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*注意事项如果命令中需要包含空格、引号等特殊字符需使用适当的引号包裹如单引号、双引号。不支持管道、重定向等 shell 操作若需要这些功能应使用shell 模块。command 模块是 Ansible 的默认模块因此-m command可以省略直接写ansible 目标 -a 命令即可。2.3 shell 模块shell 模块是 Ansible 中用于在远程主机上执行 shell 命令的核心模块。与command模块不同shell模块会通过远程主机的默认 shell如/bin/bash、/bin/sh来执行命令因此支持完整的 shell 特性包括管道符|、重定向、、、变量展开$VAR、环境变量、条件判断、||以及通配符*、?等。基本语法ansible 目标主机或组 -m shell -a shell 命令示例 1使用管道和 grep 过滤内容[rootserver1 ansible]# ansible web -m shell -a cat /etc/passwd | grep keer 192.168.223.162 | FAILED | rc1 non-zero return code结果分析此命令失败rc1因为目标主机上不存在名为 “keer” 的用户。grep 未找到匹配项因此返回非零退出码Ansible 将其标记为FAILED。这体现了shell模块对命令退出码的敏感处理。与 command 模块的对比特性command 模块shell 模块Shell 特性支持不支持管道、重定向、变量展开等完全支持管道、重定向、变量、通配符等执行环境直接执行命令不通过 shell通过远程主机的默认 shell 执行安全性较高避免 shell 注入较低需注意参数安全适用场景简单的、无 shell 特性的命令需要 shell 功能如管道、重定向的复杂命令默认模块是-m command可省略否必须指定-m shell2.3 copy 模块copy 模块是 Ansible 中用于在控制节点和受管主机之间复制文件的常用模块。它可以将本地文件或目录传输到远程主机也可以在远程主机上直接创建包含指定内容的文件。基本语法ansible 目标主机或组 -m copy -a src源路径 dest目标路径 [其他参数]示例 1复制本地文件到远程主机[rootserver1 ansible]# ansible web -m copy -a src./ansible.cfg dest/tmp示例 2在远程主机上创建并写入内容[rootserver1 ansible]# ansible web -m copy -a contenthelloword\n dest/tmp/ansible.cfg 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, checksum: ab4276b7a29337c96919309719e2506a9c428b47, dest: /tmp/ansible.cfg, gid: 0, group: root, md5sum: 0425823a38b591b104ca0c3fcf1f3d9d, mode: 0644, owner: root, secontext: unconfined_u:object_r:admin_home_t:s0, size: 10, src: /root/.ansible/tmp/ansible-tmp-1786620529.305857-14699-38592325825183/source, state: file, uid: 0 }执行后可以通过cat命令验证文件内容[rootserver1 ansible]# ansible web -a cat /tmp/ansible.cfg 192.168.223.162 | CHANGED | rc0 helloword模块说明src源文件或目录在控制节点上的路径。可以是相对路径或绝对路径。dest文件或目录在远程主机上的目标路径。content当不需要复制本地文件而是直接在远程主机上创建文件并写入内容时使用此参数。其他常用参数owner属主、group属组、mode权限、backup备份等。copy 模块在配置分发、脚本部署、模板文件传输等场景中非常实用。2.4 file 模块file 模块是 Ansible 中用于管理远程主机上文件、目录、链接等文件系统对象的常用模块。它可以创建目录、设置文件属性、创建软硬链接以及删除文件或目录。基本语法ansible 目标主机或组 -m file -a path目标路径 state状态 [其他参数]常用状态state参数directory创建目录如果目录已存在则不会报错。file确保文件存在如果不存在则创建空文件。touch创建空文件或更新文件的访问/修改时间。link/hard创建软链接或硬链接。absent删除文件、目录或链接。示例 1创建目录[rootserver1 ansible]# ansible web -m file -a path/data/app statedirectory 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, gid: 0, group: root, mode: 0755, owner: root, path: /data/app, secontext: unconfined_u:object_r:default_t:s0, size: 6, state: directory, uid: 0 }创建后可以使用ls -dl命令验证目录属性[rootserver1 ansible]# ansible web -a ls -dl /data/app 192.168.223.162 | CHANGED | rc0 drwxr-xr-x. 2 root root 6 Aug 13 19:32 /data/app示例 2删除目录[rootserver1 ansible]# ansible web -m file -a path/data/a stateabsent 192.168.223.162 | SUCCESS { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: false, path: /data/a, state: absent }模块说明path远程主机上文件或目录的路径。state指定文件系统对象的目标状态如directory、file、absent等。其他常用参数owner属主、group属组、mode权限、recurse递归设置目录属性等。file 模块在自动化部署中常用于创建应用目录、设置配置文件权限、清理临时文件等场景。2.5 fetch 模块fetch 模块是 Ansible 中用于从远程受管主机拉取文件到控制节点的模块。它与copy模块的功能相反常用于收集日志、备份配置文件或下载远程文件到本地进行分析。基本语法ansible 目标主机或组 -m fetch -a src远程文件路径 dest本地存放目录 [其他参数]示例从 centos7 主机组拉取 /etc/hostname 文件到控制节点当前目录[rootserver1 ansible]# ansible centos7 -m fetch -a src/etc/hostname dest. host1 | CHANGED { changed: true, checksum: d31b7c48a0acee92e0199216a4724ee03a33ef6e, dest: /etc/ansible/host1/etc/hostname, md5sum: 0eeb3b7facbd4cc871fef13b24d78ac2, remote_checksum: d31b7c48a0acee92e0199216a4724ee03a33ef6e, remote_md5sum: null }结果验证[rootserver1 ansible]# ls ansible.cfg host1 hosts roles test.yml [rootserver1 ansible]# cd host1 [rootserver1 host1]# ls etc [rootserver1 host1]# cd etc/ [rootserver1 etc]# ls hostname [rootserver1 etc]# cat hostname host1模块说明src远程主机上要拉取的文件路径必须是文件不支持目录。dest控制节点上存放文件的目录不是完整路径。Ansible 会自动在目标目录下创建以主机名或 IP命名的子目录并将文件放入其中以区分不同主机的同名文件。其他常用参数flat如果设为yes则不会创建主机名子目录直接保存到dest路径、validate_checksum校验文件完整性等。fetch 模块在日志收集、配置备份和审计等场景中非常实用。2.6 cron 模块cron 模块是 Ansible 中用于管理远程主机上周期性计划任务cron job的模块。它可以创建、修改、禁用或删除 crontab 条目实现定时任务的自动化配置。基本语法ansible 目标主机或组 -m cron -a name任务名称 minute分 hour时 day日 month月 weekday周 job要执行的命令 [其他参数]示例 1创建定时任务以下命令在centos7主机组上创建一个名为test的 cron 任务该任务每 5 分钟执行一次/usr/bin/date命令。[rootserver1 etc]# ansible centos7 -m cron -a nametest minute*/5 job/usr/bin/date host1 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python }, changed: true, envs: [], jobs: [ test ] }创建后可以使用crontab -l命令验证任务是否已成功添加[rootserver1 ansible]# ansible centos7 -a crontab -l host1 | CHANGED | rc0 #Ansible: test */5 * * * * /usr/bin/date示例 2删除定时任务要删除之前创建的名为test的 cron 任务可以将state参数设置为absent。[rootserver1 ansible]# ansible centos7 -m cron -a nametest stateabsent host1 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python }, changed: true, envs: [], jobs: [] }模块说明namecron 任务的唯一标识名称。这是管理修改、禁用、删除任务的关键。job要定时执行的命令或脚本。minute, hour, day, month, weekday定义任务执行时间的字段。支持标准 cron 语法如*,*/5,1,15和特殊关键字如hourly,daily。state任务状态。present默认表示创建或更新任务absent表示删除任务disabled表示禁用任务在行首添加#注释。其他常用参数user指定运行任务的用户默认为 root、backup修改前备份 crontab等。cron 模块在自动化部署中常用于配置日志轮转、定时备份、数据同步等周期性运维任务。2.7 yum 模块yum 模块是 Ansible 中用于在基于 Red Hat 系列如 CentOS、Rocky Linux、Fedora的 Linux 系统上管理软件包的核心模块。它封装了yum或dnf包管理器的功能可以执行软件包的安装、更新、卸载、查询等操作。基本语法ansible 目标主机或组 -m yum -a name软件包名 state状态 [其他参数]示例安装 httpd 软件包[rootserver1 ansible]# ansible centos7 -m yum -a namehttpd statepresent参数说明name要操作的软件包名称可以指定单个包名也可以是用逗号分隔的多个包名。state软件包的目标状态。present或installed确保软件包已安装如果未安装则安装。latest确保软件包已安装且为最新版本。absent或removed确保软件包已卸载。其他常用参数enablerepo启用特定仓库、disablerepo禁用特定仓库、update_cache更新包缓存等。2.8 service 模块service 模块是 Ansible 中用于管理远程主机上系统服务如 systemd 服务、SysV init 服务的核心模块。它可以启动、停止、重启、重载服务以及设置服务的开机自启状态。基本语法ansible 目标主机或组 -m service -a name服务名 state状态 [其他参数]示例启动 httpd 服务并设置开机自启[rootserver1 ansible]# ansible centos7 -m service -a namehttpd statestarted enabledyes参数说明name要管理的系统服务名称如httpd、nginx、sshd等。state服务的目标运行状态。started确保服务正在运行如果未运行则启动。stopped确保服务已停止。restarted重启服务。reloaded重载服务配置不重启。enabled设置服务是否开机自启。yes表示启用no表示禁用。2.9 user 模块user 模块是 Ansible 中用于管理远程主机上用户账户的核心模块。它可以创建、修改、删除用户并设置用户的 UID、GID、家目录、登录 Shell 等属性。基本语法ansible 目标主机或组 -m user -a name用户名 [其他参数]示例创建用户并指定 UID以下命令在web主机组的所有服务器上创建名为kyy的用户并指定其 UID 为 1111。[rootserver1 ansible]# ansible web -m user -a namekyy uid1111 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, comment: , create_home: true, group: 1111, home: /home/kyy, name: kyy, shell: /bin/bash, state: present, system: false, uid: 1111 }示例删除用户[rootserver1 ansible]# ansible web -m user -a namekyy stateabsent 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, force: false, name: kyy, remove: false, state: absent }模块说明name要创建或管理的用户名。uid指定用户的 UID用户标识符。group指定用户的主组GID 或组名。home指定用户的家目录路径。shell指定用户的登录 Shell如/bin/bash、/sbin/nologin。state用户状态。present默认表示创建或确保用户存在absent表示删除用户。2.10 group 模块group 模块是 Ansible 中用于管理远程主机上用户组group的核心模块。它可以创建、修改、删除用户组并设置组的 GID组标识符等属性。基本语法ansible 目标主机或组 -m group -a name组名 [其他参数]示例创建用户组并指定 GID以下命令在web主机组的所有服务器上创建名为developers的用户组并指定其 GID 为 2000。[rootserver1 ansible]# ansible web -m group -a namedevelopers gid2000 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, gid: 2000, name: developers, state: present, system: false }模块说明name要创建或管理的用户组名称。gid指定组的 GID组标识符。state组状态。present默认表示创建或确保组存在absent表示删除组。system是否创建为系统组。yes表示创建系统组通常 GID 1000no表示创建普通组。group 模块通常与 user 模块配合使用用于在自动化部署中创建应用运行所需的用户和组确保权限隔离和系统安全。2.11 script 模块script 模块是 Ansible 中用于在远程主机上执行本地脚本的模块。它可以将控制节点上的脚本文件传输到远程主机并在远程主机上执行执行完成后会自动清理传输的临时文件。该模块非常适合执行需要复杂逻辑或依赖本地环境的脚本任务。基本语法ansible 目标主机或组 -m script -a 本地脚本路径 [其他参数]示例执行本地脚本首先在控制节点上创建一个简单的脚本文件/tmp/hello.sh内容为输出当前主机名[rootserver1 ansible]# vim /tmp/hello.sh echo $HOSTNAME为脚本添加执行权限[rootserver1 ansible]# chmod x /tmp/hello.sh使用 script 模块在web主机组上执行该脚本[rootserver1 ansible]# ansible web -m script -a /tmp/hello.sh 192.168.223.162 | CHANGED { changed: true, rc: 0, stderr: Shared connection to 192.168.223.162 closed.\r\n, stderr_lines: [ Shared connection to 192.168.223.162 closed. ], stdout: server2\r\n, stdout_lines: [ server2 ] }结果分析脚本成功执行返回码rc0表示执行成功。输出显示远程主机的主机名为server2与预期一致。模块说明脚本路径指定控制节点上脚本文件的路径相对或绝对路径。执行流程Ansible 将脚本文件复制到远程主机的临时目录。在远程主机上为脚本添加执行权限。执行脚本。执行完成后自动删除远程主机上的临时脚本文件。参数传递可以通过args参数向脚本传递命令行参数。环境变量脚本在远程主机上执行时会继承远程主机的环境变量如$HOSTNAME。script 模块在需要执行复杂逻辑、依赖本地工具或需要一次性脚本任务的场景中非常实用避免了在远程主机上手动上传和执行脚本的繁琐步骤。2.12 lineinfile 模块lineinfile 模块是 Ansible 中用于管理远程主机上文本文件中特定行的核心模块。它可以在文件中查找、添加、修改或删除指定的单行内容非常适合用于配置文件的精确修改如修改参数值、添加配置项或注释掉特定行。基本语法ansible 目标主机或组 -m lineinfile -a path文件路径 regexp正则表达式 line要插入/替换的行内容 [其他参数]示例 1确保某行存在不存在则添加以下命令确保在/etc/ssh/sshd_config文件中存在PermitRootLogin no这一行如果不存在则添加[rootserver1 ansible]# ansible web -m lineinfile -a path/etc/ssh/sshd_config regexp^PermitRootLogin linePermitRootLogin no 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, msg: line added }示例 2修改已存在的行如果文件中有以PermitRootLogin开头的行则将其替换为PermitRootLogin yes[rootserver1 ansible]# ansible web -m lineinfile -a path/etc/ssh/sshd_config regexp^PermitRootLogin linePermitRootLogin yes 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, msg: line replaced }示例 3删除特定行删除/etc/hosts文件中包含192.168.223.200的行[rootserver1 ansible]# ansible web -m lineinfile -a path/etc/hosts regexp^192\.168\.223\.200 stateabsent 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, found: 1, msg: line removed }模块说明path要修改的远程主机上的文件路径。regexp用于匹配目标行的正则表达式。如果找到匹配的行则根据line参数进行替换如果未找到且statepresent则在文件末尾添加新行。line要插入或替换的行内容。state行状态。present默认表示确保行存在absent表示删除匹配的行。其他常用参数insertafter在匹配某行之后插入、insertbefore在匹配某行之前插入、backrefs启用反向引用、backup修改前备份原文件等。lineinfile 模块在自动化配置管理中非常实用常用于修改系统配置文件、应用配置文件、环境变量文件等确保配置的精确性和一致性。2.13 unarchive 模块unarchive 模块是 Ansible 中用于在远程主机上解压归档文件如 .tar、.tar.gz、.zip 等的核心模块。它可以将控制节点上的压缩包传输到远程主机并解压也可以直接解压远程主机上已有的归档文件常用于软件部署、配置文件分发等场景。基本语法ansible 目标主机或组 -m unarchive -a src源文件路径 dest目标目录 [其他参数]示例 1解压本地压缩包到远程主机假设控制节点上有一个名为app.tar.gz的压缩包需要解压到远程主机的/opt目录[rootserver1 ansible]# ansible web -m unarchive -a src./app.tar.gz dest/opt 192.168.223.162 | CHANGED { ansible_facts: { discovered_interpreter_python: /usr/bin/python3 }, changed: true, dest: /opt, extract_results: { cmd: [/usr/bin/tar, --extract, -z, -f, /root/.ansible/tmp/ansible-tmp-.../source, -C, /opt], err: , out: }, gid: 0, group: root, handler: TarArchive, mode: 0755, owner: root, size: 4096, src: /root/.ansible/tmp/ansible-tmp-.../source, state: directory, uid: 0 }模块说明src要解压的归档文件路径。如果remote_srcno默认则从控制节点复制到远程主机再解压如果remote_srcyes则直接解压远程主机上的文件。dest解压文件的目标目录。该目录必须存在否则模块会报错。remote_src是否使用远程主机上的源文件。默认为no表示从控制节点复制设为yes时直接解压远程文件。其他常用参数owner设置解压后文件的属主、group设置属组、mode设置文件权限、creates如果目标文件/目录已存在则跳过解压等。unarchive 模块支持多种压缩格式包括 .tar、.tar.gz、.tar.bz2、.zip 等是自动化部署中分发软件包、配置文件或静态资源的常用工具。