介绍

从问题入手,当你有几台服务器,要在这几台服务器上进行一些相同操作,例如启动一个软件,修改一些配置,以及查看一些文件目录。你会怎么做?

你可能会直接操作,或者写一个脚本,再分别运行。 但是如果不是几台,而是成百上千台呢?上述方式就不再优雅了,而且费时费力。即便是写了脚本,你仍然需要逐个登录,然后执行。即便你使用了密钥登录,而非密码登录。但是如果每个都需要再使用sudo或者root权限运行,是不是还是很麻烦?

这时候你就需要一个工具,能够让你在一台机器上完成对其它机器的管理。

ansible就是一个这样的工具,能够进行批量的系统配置管理、批量程序部署、批量程序运行等功能。同类工具还有puppet、chef、cfengine、func、fabric、saltstack等等,这里不做对比。

ansible基于ssh,但是也可以自定义接口,但不是这里重点。

ansible的架构如下。

  • connection plugins(连接插件):用于连接主机,用来连接被管理端
  • core modules (核心模块):连接主机实现操作,它依赖于具体的模块来做具体的事情
  • custom modules (自定义模块):根据自己的需求编写具体的模块。
  • plugins (插件):完成模块功能的补充
  • playbooks(剧本):ansible的配置文件,将多个任务定义在剧本中,由ansible自动执行。大家很大一部分都是在写playbook。
  • host inventory (主机清单):定义ansible需要操作主机(网络设备、控制器、可以对接ansible的第三方软件控制器)的范围,这个其实相当于一个简单文件描述的CMDB,可以对设备打标签、角色等等,可以在一些场景下筛选设备,不同设备执行不同的命令。这段大家可以细细看看ansible的一些官方文档

image.png

安装

ansible最好用在linux上,windows支持不太行,wsl应该可以,不用mac不晓得行不行。

从源码安装可从Ansible - Github获取,不过推荐直接安装。安装只需要在管理端服务器上安装即可,不需要在被管理端安装,用人话就是只需要在一台服务器(管理端)上安装即可,不用在所有其它机器(被管理端)都安装。

$ pip install ansible
$ ansible --version
ansible [core 2.17.12]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.12 (main, May 27 2025, 17:12:29) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True

可能还需要系统安装sshpass,否则提示:to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program。安装例如:apt install sshpass

使用

本文作为快速上手类,不会涉及playbook这种复杂东西。只涉及一些内容。

首先,创建一个主机清单,用于描述各个主机。一般都是一个inventory.ini。例如:

[ipv4]
1.2.3.4
2.3.4.1
[ipv6]
1::2
2::2
3::2
[domain]
www.example.com

ansible支持ipv4或者ipv6主机或者服务器域名,上述清单中有两个,一个ipv4,一个ipv6。

除了ini格式,还支持yaml格式,不过大概率简单用用没啥必要。复杂创建可参考:How to build your inventory — Ansible Community Documentation

ansible有很多模块,以下简单介绍几个最常用的。

shell模块

最常用的模块,肯定是shell模块,因为这个基本完整支持所有的shell命令了。

ansible ipv4 -i ~/inventory.ini -m shell -a 'systemctl status ssh'

这里,ipv4就是主机清单中的一个组,-i指定主机清单文件位置以及文件名,-m指定使用的模块,-a指定要执行的命令。

copy模块

用于拷贝文件。

ansible ipv4 -u user -i inventory.ini -m copy -b -k -K -a "src=/usr/local/lib/example.sh dest=/usr/local/lib/example.sh"

-u user用于指定被管理端机器的用户名,默认不指定时,和执行ansible命令的管理端用户名相同,不知道就用whoami或者echo $USER查看当前管理端的用户名。

src=xxx以及dest=yyy这里分别指定管理端机器文件地址和被管理端机器文件地址。

由于/usr/local/lib一般是属于root用户的,但是root用户一般是不能ssh登录的,这里-k用于输入管理端密码,使用-b -K用于输入被管理端user用户提权后的密码(要所有被管理端密码相同),其实就类似于执行了sudo scp xxx yyy

参考

  1. 可能会成为网工ansible的最强教程(一) - 知乎
  2. Ansible中文权威指南 — 国内最专业的Ansible中文官方学习手册