乐于分享
好东西不私藏

Ansible 入门完全指南:从安装到批量管理服务器

Ansible 入门完全指南:从安装到批量管理服务器
安装配置 + SSH 密钥认证 + 4 大核心模块实战演练

当你需要管理 2 台服务器时,手动 SSH 上去敲命令还能接受。但当服务器变成 20 台、200 台时,逐台登录操作就是一场灾难。Ansible 就是为解决这个问题而生——通过 SSH 批量控制远程主机,无需在目标机器上安装任何 Agent,开箱即用。

本文从零开始,带你完成 Ansible 的安装、配置、SSH 密钥认证,并通过 4 个核心模块的实战演练,让你快速上手批量管理服务器。


一、安装 Ansible

Ansible 在 EPEL 源中,CentOS/RHEL 系统需要先配置 EPEL 源:

# 配置 EPEL 源(以 CentOS 7 为例)vi /etc/yum.repos.d/epel.repo[epel]name=epelbaseurl=https://mirrors.aliyun.com/epel/7/x86_64/gpgcheck=0
# 安装 Ansibleyum install ansible -y# 验证安装ansible --version

其他系统安装方式:

  • Ubuntu/Debian:apt install ansible

  • pip 安装(推荐获取最新版):pip install ansible


二、目录结构与配置文件

核心文件一览

路径说明
/etc/ansible/ansible.cfg主配置文件,控制 Ansible 的工作行为
/etc/ansible/hosts主机清单(Inventory),定义被管理的服务器
/etc/ansible/roles/存放 Roles 的目录

核心程序

命令用途
ansible主程序,执行临时命令(Ad-Hoc)
ansible-playbook执行 Playbook(剧本)
ansible-doc查看模块文档
ansible-galaxy下载/管理社区 Roles
ansible-vault加密敏感文件(密码、密钥等)
ansible-console交互式执行命令的控制台

ansible.cfg 关键配置

默认配置文件大部分保持默认即可,但建议修改以下 3 项

[defaults]# 1. 关闭主机密钥检查(否则首次连接每台主机都要手动确认)host_key_checking = False# 2. 开启日志记录(方便排查问题)log_path = /var/log/ansible.log# 3. 将默认模块改为 shell(command 模块不支持管道、重定向等功能)module_name = shell
配置项默认值说明
inventory/etc/ansible/hosts主机清单文件路径
remote_tmp~/.ansible/tmp远程主机临时文件目录
forks5并发执行的主机数
remote_port22SSH 连接端口
ask_passTrue是否提示输入 SSH 密码
sudo_userroot默认 sudo 用户

三、主机清单(Inventory)

主机清单是 Ansible 的核心概念之一,它定义了你要管理哪些服务器,以及如何对它们分组。

基本格式

主机清单遵循 INI 文件风格

# /etc/ansible/hosts[webserver]                     # 中括号中的字符为组名192.168.1.10192.168.1.11:2222               # 非标准 SSH 端口[appserver]192.168.1.10                    # 同一主机可以属于多个组192.168.1.[20:30]               # 连续 IP 的简写方式(20~30)[dbserver]db-node[01:03].example.com      # 主机名也支持列表写法

常用主机模式

# 操作所有主机ansible all -m ping# 操作指定组ansible webserver -m ping# 操作多个组(并集)ansible 'webserver:appserver' -m ping# 操作交集(同时属于两个组的主机)ansible 'webserver:&appserver' -m ping# 排除某个组ansible 'all:!dbserver' -m ping

四、SSH 认证:密码 vs 密钥

Ansible 通过 SSH 连接远程主机,有两种认证方式。

方式一:密码认证(临时使用)

# -k 选项提示输入 SSH 密码ansible webserver -m ping -kSSH password:192.168.1.10 | SUCCESS => {"changed"false,"ping""pong"}

密码认证要求所有被管理主机的密码相同,且每次都要输入,不推荐生产使用

方式二:密钥认证(生产推荐)

第一步:在 Ansible 管理机上生成密钥对

ssh-keygen  -t  rsa -P "" -f  ~/.ssh/id_rsa

第二步:将公钥分发到所有被管理主机

ssh-copy-id 192.168.1.10ssh-copy-id 192.168.1.11# ... 对每台被管理主机执行

第三步:验证免密连接

# 不再需要 -k 选项ansible webserver -m ping192.168.1.10 | SUCCESS => {"changed"false,"ping""pong"}192.168.1.11 | SUCCESS => {"changed"false,"ping""pong"}

批量分发密钥的技巧: 当主机很多时,可以用 sshpass 配合循环来批量分发:

for ip in 10 11 12do sshpass  -p  'your_password' ssh-copy-id -o StrictHostKeyChecking=no 192.168.1.$ipdone

补充:sudo 提权

有时需要以普通用户 SSH 登录,再通过 sudo 执行特权操作:

# -u 指定登录用户,-b 启用 sudo 提权,-K 输入 sudo 密码ansible webserver -m ping -u deploy -k -b -K

如果在目标机器上配置了 NOPASSWD,则不需要 -K 选项。


五、核心模块实战

ansible-doc:查看模块文档

在使用任何模块之前,都可以用 ansible-doc 查看用法:

# 查看模块详细文档ansible-doc copy# 查看简要用法(推荐)ansible-doc -s copy# 列出所有可用模块ansible-doc -l

5.1 ping 模块 — 连通性测试

最简单的模块,用于验证 Ansible 能否正常连接到目标主机:

ansible webserver -m ping192.168.1.10 | SUCCESS => {"changed"false,"ping""pong"}

返回 pong 表示连接成功。注意:这不是 ICMP ping,而是 Ansible 通过 SSH 连接并执行 Python 代码来验证连通性。

5.2 shell 模块 — 执行 Shell 命令

shell 模块用于在远程主机上执行 Shell 命令,支持管道、重定向、变量等所有 Shell 特性。

示例 1:执行基本命令

ansible webserver -m shell -a 'echo 123456 | passwd --stdin deploy'192.168.1.10 | CHANGED | rc=0 >>Changing password for user deploy.passwd: all authentication tokens updated successfully.

示例 2:单引号 vs 双引号(重要)

# 单引号:变量在远程主机上解析(正确)ansible webserver -m shell -a  'echo $HOSTNAME'192.168.1.10 | CHANGED | rc=0 >>web1192.168.1.11 | CHANGED | rc=0 >>web2# 双引号:变量在本机解析(通常不是你想要的)ansible webserver -m shell -a "echo $HOSTNAME"192.168.1.10 | CHANGED | rc=0 >>ansible-server192.168.1.11 | CHANGED | rc=0 >>ansible-server

记住: Ansible 命令中的 -a 参数,用单引号包裹可以防止本机 Shell 提前展开变量。

示例 3:切换目录 + 重定向

# chdir 参数:先 cd 到指定目录再执行命令ansible webserver -m shell -a  'chdir=/data echo "hello ansible" > test.log'# 验证ansible webserver -m shell -a  'cat /data/test.log'192.168.1.10 | CHANGED | rc=0 >>hello ansible

示例 4:使用 sed 修改文件

ansible webserver -m shell -a 'sed -i  "s/old_text/new_text/"  /data/test.log'

Ansible 会提示建议使用 replacelineinfile 或 template 模块替代 sed,这些模块具备幂等性,多次执行结果一致。

shell vs command 模块

特性command(默认)shell
管道 \|不支持支持
重定向 >>>不支持支持
变量 $VAR不支持支持
通配符 *不支持支持
安全性更安全(不经过 Shell 解释)注意命令注入风险

这就是为什么建议在 ansible.cfg 中把默认模块改为 shell——command 模块限制太多,日常使用不方便。

5.3 script 模块 — 远程执行本机脚本

script 模块可以在远程主机上执行 Ansible 管理机上的脚本,无需事先将脚本复制过去。

# 在管理机上编写脚本cat > /server/scripts/hello.sh << 'EOF'#!/bin/bashecho"hello world from $(hostname)"EOFchmod +x  /server/scripts/hello.sh# 在所有 webserver 上执行ansible webserver -m script -a  '/server/scripts/hello.sh'192.168.1.10 | CHANGED => {"changed"true,"rc"0,"stdout""hello world from web1\r\n",    ...}

适用场景: 临时需要在远程主机执行一段逻辑,但不想把脚本复制过去。常驻脚本推荐用 copy 模块先分发再执行。

5.4 copy 模块 — 文件分发

将管理机上的文件复制到远程主机,支持设置权限、属主、备份等。

参数说明
src管理机上的源文件路径
dest远程主机的目标路径(必填)
owner设置文件属主
group设置文件属组
mode设置文件权限
backup目标文件已存在时是否备份(yes/no)
content直接指定文件内容(与 src 二选一)

示例 1:复制文件并设置权限

ansible webserver -m copy -a 'src=/etc/fstab dest=/data/fstab.bak owner=deploy mode=0644 backup=yes'192.168.1.10 | CHANGED => {"changed"true,"dest""/data/fstab.bak","owner""deploy","mode""0644",    ...}

backup=yes 的效果:如果目标文件已存在且内容不同,会自动备份为 文件名.日期时间.bak,防止覆盖丢失。

示例 2:直接生成文件内容

ansible webserver -m copy -a  'content="hello ansible\nwelcome\n" dest=/data/greeting.txt'# 验证ansible webserver -a  'cat /data/greeting.txt'192.168.1.10 | CHANGED | rc=0 >>hello ansiblewelcome

content 参数适合生成简短的配置文件或标记文件,复杂模板推荐用 template 模块。


六、补充:更多常用模块速览

除了上面详细讲解的 4 个模块,以下模块在日常运维中也非常高频:

模块用途示例
yum / apt软件包管理ansible all -m yum -a 'name=nginx state=present'
systemd / service服务管理ansible all -m systemd -a 'name=nginx state=started enabled=yes'
file文件/目录管理ansible all -m file -a 'path=/data state=directory mode=0755'
lineinfile修改文件中的某一行ansible all -m lineinfile -a 'path=/etc/hosts line="192.168.1.10 web1"'
user用户管理ansible all -m user -a 'name=deploy state=present'
cron定时任务管理ansible all -m cron -a 'name="sync time" minute="*/5" job="/sbin/ntpdate ntp.aliyun.com"'
fetch从远程主机拉取文件到管理机ansible all -m fetch -a 'src=/var/log/messages dest=/tmp/'
template使用 Jinja2 模板生成配置文件在 Playbook 中使用
unarchive解压文件到远程主机ansible all -m unarchive -a 'src=app.tar.gz dest=/opt/'

七、Ansible 命令选项速查

ansible <主机模式> [-m 模块] [-a '参数']
选项说明
-m module指定模块(默认 command)
-a 'args'模块参数
-k提示输入 SSH 密码
-u user指定远程登录用户
-b启用 sudo 提权
-K提示输入 sudo 密码
-C检查模式(只检查不执行)
-v / -vv / -vvv显示详细过程(v 越多越详细)
--list-hosts显示匹配的主机列表
-T timeout设置连接超时时间
--version显示版本信息

八、新手避坑指南

  1. 首次连接报 host_key 错误 — 在 ansible.cfg 中设置 host_key_checking = False

  2. command 模块不支持管道和重定向 — 改用 shell 模块,或修改默认模块为 shell。

  3. 双引号导致变量在本机展开 — -a 参数用单引号包裹。

  4. 执行命令提示 Permission denied — 检查 SSH 密钥是否分发,或使用 -k 输入密码。

  5. sudo 报错 "a password is required" — 加上 -K 选项,或在目标机配置 NOPASSWD

  6. 模块不知道怎么用 — 先跑一次 ansible-doc -s 模块名,养成查文档的习惯。

  7. copy 模块覆盖了重要文件 — 加上 backup=yes 参数,自动备份原文件。


写在最后

本文覆盖了 Ansible 入门的完整路径:

  • 安装部署 + 3 项关键配置修改

  • 主机清单的格式、分组与主机模式

  • SSH 密码认证与密钥认证的完整流程

  • sudo 提权的使用方法

  • 4 大核心模块深度实战(ping / shell / script / copy)

  • shell vs command 对比、单引号 vs 双引号的区别

  • 常用模块速览 + 命令选项速查 + 新手避坑指南

这是 Ansible 自动化的第一课。 掌握了 Ad-Hoc 命令后,接下来将进入更强大的领域:

  • Playbook — 将操作编排成可复用的剧本

  • Roles — 项目级别的组织方式,代码复用的最佳实践

  • 变量与模板 — 让同一套 Playbook 适配不同环境

关注本公众号,Ansible 系列持续更新,每篇都是从零到生产的完整闭环。