ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ansible

Ansible

Ansible 是一款自动化运维工具。 用来批量操控多台 Linux 服务器,批量执行命令、安装软件、部署程序、配置文件。

假设需要管理几十台服务器: 不用一台一台 ssh 登录手动敲命令。 Ansible 相当于一个批量遥控器

临时干活:Ad-Hoc 单行命令

成套流水线部署:Playbook 剧本

ansible部署指南

1.1 安装ansible

首先部署三台虚拟机,两台rocky9.6、一台centos7;在第一台rocky9.6上面安装ansible

[root@server1 ~]# yum install -y ansible-core.x86_64

1.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] host1

1.3 ansible ad-hoc

ad-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 [root@server1 ~]# 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" }

但是这样太麻烦了所以直接配置免密

[root@server1 ~]# ssh -keygen [root@server1 ~]# ssh-copy-id 192.168.223.161 [root@server1 ~]# ssh-copy-id 192.168.223.162 [root@server1 ~]# ssh-copy-id 192.168.223.181 [root@server1 ~]# 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 端口

[root@server1 ansible]# ansible web -m command -a 'ss -ntl' 192.168.223.162 | CHANGED | rc=0 >> 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 过滤内容

[root@server1 ansible]# ansible web -m shell -a 'cat /etc/passwd | grep "keer"' 192.168.223.162 | FAILED | rc=1 >> non-zero return code

结果分析:此命令失败(rc=1),因为目标主机上不存在名为 “keer” 的用户。grep 未找到匹配项,因此返回非零退出码,Ansible 将其标记为FAILED。这体现了shell模块对命令退出码的敏感处理。

与 command 模块的对比:

特性command 模块shell 模块
Shell 特性支持不支持管道、重定向、变量展开等完全支持管道、重定向、变量、通配符等
执行环境直接执行命令,不通过 shell通过远程主机的默认 shell 执行
安全性较高,避免 shell 注入较低,需注意参数安全
适用场景简单的、无 shell 特性的命令需要 shell 功能(如管道、重定向)的复杂命令
默认模块是(-m command可省略)否(必须指定-m shell

2.3 copy 模块

copy 模块是 Ansible 中用于在控制节点和受管主机之间复制文件的常用模块。它可以将本地文件或目录传输到远程主机,也可以在远程主机上直接创建包含指定内容的文件。

基本语法:

ansible <目标主机或组> -m copy -a 'src=<源路径> dest=<目标路径> [其他参数]'

示例 1:复制本地文件到远程主机

[root@server1 ansible]# ansible web -m copy -a 'src=./ansible.cfg dest=/tmp'

示例 2:在远程主机上创建并写入内容

[root@server1 ansible]# ansible web -m copy -a 'content="helloword\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命令验证文件内容:

[root@server1 ansible]# ansible web -a 'cat /tmp/ansible.cfg' 192.168.223.162 | CHANGED | rc=0 >> 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:创建目录

[root@server1 ansible]# ansible web -m file -a 'path=/data/app state=directory' 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命令验证目录属性:

[root@server1 ansible]# ansible web -a 'ls -dl /data/app' 192.168.223.162 | CHANGED | rc=0 >> drwxr-xr-x. 2 root root 6 Aug 13 19:32 /data/app

示例 2:删除目录

[root@server1 ansible]# ansible web -m file -a 'path=/data/a state=absent' 192.168.223.162 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "path": "/data/a", "state": "absent" }

模块说明:

  • path:远程主机上文件或目录的路径。

  • state:指定文件系统对象的目标状态,如directoryfileabsent等。

  • 其他常用参数owner(属主)、group(属组)、mode(权限)、recurse(递归设置目录属性)等。

file 模块在自动化部署中常用于创建应用目录、设置配置文件权限、清理临时文件等场景。

2.5 fetch 模块

fetch 模块是 Ansible 中用于从远程受管主机拉取文件到控制节点的模块。它与copy模块的功能相反,常用于收集日志、备份配置文件或下载远程文件到本地进行分析。

基本语法:

ansible <目标主机或组> -m fetch -a 'src=<远程文件路径> dest=<本地存放目录> [其他参数]'

示例:从 centos7 主机组拉取 /etc/hostname 文件到控制节点当前目录

[root@server1 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 }

结果验证:

[root@server1 ansible]# ls ansible.cfg host1 hosts roles test.yml [root@server1 ansible]# cd host1 [root@server1 host1]# ls etc [root@server1 host1]# cd etc/ [root@server1 etc]# ls hostname [root@server1 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命令。

[root@server1 etc]# ansible centos7 -m cron -a 'name=test minute=*/5 job=/usr/bin/date' host1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "test" ] }

创建后,可以使用crontab -l命令验证任务是否已成功添加:

[root@server1 ansible]# ansible centos7 -a 'crontab -l' host1 | CHANGED | rc=0 >> #Ansible: test */5 * * * * /usr/bin/date

示例 2:删除定时任务

要删除之前创建的名为test的 cron 任务,可以将state参数设置为absent

[root@server1 ansible]# ansible centos7 -m cron -a 'name=test state=absent' host1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [] }

模块说明:

  • name:cron 任务的唯一标识名称。这是管理(修改、禁用、删除)任务的关键。

  • 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 系统上管理软件包的核心模块。它封装了yumdnf包管理器的功能,可以执行软件包的安装、更新、卸载、查询等操作。

基本语法:

ansible <目标主机或组> -m yum -a 'name=<软件包名> state=<状态> [其他参数]'

示例:安装 httpd 软件包

[root@server1 ansible]# ansible centos7 -m yum -a 'name=httpd state=present'

参数说明:

  • name:要操作的软件包名称,可以指定单个包名,也可以是用逗号分隔的多个包名。

  • state:软件包的目标状态。

    • presentinstalled:确保软件包已安装(如果未安装则安装)。

    • latest:确保软件包已安装且为最新版本。

    • absentremoved:确保软件包已卸载。

  • 其他常用参数enablerepo(启用特定仓库)、disablerepo(禁用特定仓库)、update_cache(更新包缓存)等。

2.8 service 模块

service 模块是 Ansible 中用于管理远程主机上系统服务(如 systemd 服务、SysV init 服务)的核心模块。它可以启动、停止、重启、重载服务,以及设置服务的开机自启状态。

基本语法:

ansible <目标主机或组> -m service -a 'name=<服务名> state=<状态> [其他参数]'

示例:启动 httpd 服务并设置开机自启

[root@server1 ansible]# ansible centos7 -m service -a 'name=httpd state=started enabled=yes'

参数说明:

  • name:要管理的系统服务名称,如httpdnginxsshd等。

  • 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。

[root@server1 ansible]# ansible web -m user -a 'name=kyy uid=1111' 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 }

示例:删除用户

[root@server1 ansible]# ansible web -m user -a 'name=kyy state=absent' 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。

[root@server1 ansible]# ansible web -m group -a 'name=developers gid=2000' 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 < 1000);no表示创建普通组。

group 模块通常与 user 模块配合使用,用于在自动化部署中创建应用运行所需的用户和组,确保权限隔离和系统安全。

2.11 script 模块

script 模块是 Ansible 中用于在远程主机上执行本地脚本的模块。它可以将控制节点上的脚本文件传输到远程主机,并在远程主机上执行,执行完成后会自动清理传输的临时文件。该模块非常适合执行需要复杂逻辑或依赖本地环境的脚本任务。

基本语法:

ansible <目标主机或组> -m script -a '<本地脚本路径> [其他参数]'

示例:执行本地脚本

首先,在控制节点上创建一个简单的脚本文件/tmp/hello.sh,内容为输出当前主机名:

[root@server1 ansible]# vim /tmp/hello.sh echo $HOSTNAME

为脚本添加执行权限:

[root@server1 ansible]# chmod +x /tmp/hello.sh

使用 script 模块在web主机组上执行该脚本:

[root@server1 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" ] }

结果分析:脚本成功执行,返回码rc=0表示执行成功。输出显示远程主机的主机名为server2,与预期一致。

模块说明:

  • 脚本路径:指定控制节点上脚本文件的路径(相对或绝对路径)。

  • 执行流程

    1. Ansible 将脚本文件复制到远程主机的临时目录。

    2. 在远程主机上为脚本添加执行权限。

    3. 执行脚本。

    4. 执行完成后,自动删除远程主机上的临时脚本文件。

  • 参数传递:可以通过args参数向脚本传递命令行参数。

  • 环境变量:脚本在远程主机上执行时,会继承远程主机的环境变量(如$HOSTNAME)。

script 模块在需要执行复杂逻辑、依赖本地工具或需要一次性脚本任务的场景中非常实用,避免了在远程主机上手动上传和执行脚本的繁琐步骤。

2.12 lineinfile 模块

lineinfile 模块是 Ansible 中用于管理远程主机上文本文件中特定行的核心模块。它可以在文件中查找、添加、修改或删除指定的单行内容,非常适合用于配置文件的精确修改,如修改参数值、添加配置项或注释掉特定行。

基本语法:

ansible <目标主机或组> -m lineinfile -a 'path=<文件路径> regexp=<正则表达式> line=<要插入/替换的行内容> [其他参数]'

示例 1:确保某行存在(不存在则添加)

以下命令确保在/etc/ssh/sshd_config文件中存在PermitRootLogin no这一行,如果不存在则添加:

[root@server1 ansible]# ansible web -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^PermitRootLogin" line="PermitRootLogin no"' 192.168.223.162 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "msg": "line added" }

示例 2:修改已存在的行

如果文件中有以PermitRootLogin开头的行,则将其替换为PermitRootLogin yes

[root@server1 ansible]# ansible web -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^PermitRootLogin" line="PermitRootLogin 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的行:

[root@server1 ansible]# ansible web -m lineinfile -a 'path=/etc/hosts regexp="^192\.168\.223\.200" state=absent' 192.168.223.162 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "found": 1, "msg": "line removed" }

模块说明:

  • path:要修改的远程主机上的文件路径。

  • regexp:用于匹配目标行的正则表达式。如果找到匹配的行,则根据line参数进行替换;如果未找到且state=present,则在文件末尾添加新行。

  • 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目录:

[root@server1 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_src=no(默认),则从控制节点复制到远程主机再解压;如果remote_src=yes,则直接解压远程主机上的文件。

  • dest:解压文件的目标目录。该目录必须存在,否则模块会报错。

  • remote_src:是否使用远程主机上的源文件。默认为no,表示从控制节点复制;设为yes时直接解压远程文件。

  • 其他常用参数owner(设置解压后文件的属主)、group(设置属组)、mode(设置文件权限)、creates(如果目标文件/目录已存在则跳过解压)等。

unarchive 模块支持多种压缩格式,包括 .tar、.tar.gz、.tar.bz2、.zip 等,是自动化部署中分发软件包、配置文件或静态资源的常用工具。

返回列表