之前的文章<<Ansible入门>>介绍了做为自动化配置管理的Ansible,这篇文章简要来介绍Python远程执行库 Fabric 。
Fabric是一个通过SSH远程执行SHELL命令的库,主要用于自动化的安装部署及远程管理任务。Ansible也能够实现Fabric的这些能力,但Fabric更为轻量,只是单纯地用于远程执行。它本身是一个Python库,可以在我们自己的Python程序中直接 import
,并基于它实现远程命令执行。此外,它还提供了一个 fab
命令行工具,使用它可以更简单地编写我们需要执行的任务。这种模式被使用的更为普遍,我们主要来介绍以 fab
命令来使用fabric。
需要注意的是,Fabric的2.x版本并不兼容1.x版本,而且2.x版本很大程度上边缘化了fab命令行工具,因而我们还是来介绍1.x版本。当前最新1.x版本为1.14, 文档地址为: http://docs.fabfile.org/en/1.14/%E3%80%82
首先我们使用 pip
安装fabric:
pip install ‘fabric<2.0’
安装完可以执行 fab
命令查看版本:
[root@centos1 fabv1]# fab –version Fabric 1.14.0 Paramiko 2.4.2
fab
命令行工具默认从当前目录下的文件 fabfile.py
中加载Python代码,其中的每个python函数定义了一个 task
, 可以直接以fab命令行直接执行。
如, fabfile.py
内容如下:
def helloworld(): print(“Hello world!”) def hello(name=”world”): print(“Hello %s!” % name)
可以通过执行如下命令查看当前 fabfile.py
中定义的task:
[root@centos1 fabv1]# fab -l Available commands: hello helloworld [root@centos1 fabv1]#
可以看到 hello
和 helloworld
两个 task
被定义。
其中, hello
函数中定义了参数,在调用时可以如下形式调用 fab
命令:
<task name>:<arg>,<kwarg>=<value>,…
比如,我们使用两种参数传入方式都可以:
[root@centos1 fabv1]# fab hello:name=flygoast Hello flygoast! Done. [root@centos1 fabv1]# fab hello:flygoast Hello flygoast! Done. [root@centos1 fabv1]#
Fabric提供了若干操作函数,主要有:
- local(): 在本地主机执行命令
- run(): 在远程主机执行命令
- sudo(): 类似于run(), 区别在于在SHELL命令前加上”sudo”
- get(remote, local): 从远程主机下载文件到本地
- put(local, remote): 将本地文件上传到远程主机
- prompt(): 提示用户输入,并返回其输入内容
- reboot(): 重启服务器
在远程主机上需要执行的操作,我们直接定义在Python函数中, 如:
from fabric.api import run def test_remote(): run(“hostname”)
不过,在哪些主机上执行如何指定呢?Fabric提供了许多方式,我们简要介绍几种。
一种是直接由fab命令的选项来指定如:
[root@centos1 fabv1]# fab -H dev01 test_remote [dev01] Executing task ‘test_remote’ [dev01] run: hostname [dev01] Login password for ‘root’: [dev01] out: dev01 [dev01] out: Done. Disconnecting from dev01… done. [root@centos1 fabv1]#
支持的主机格式为SSH风格: user@host:port
。值得一提的是,当执行上述命令时,会提示用户需要手动输入密码。
也可以在fabric的全局变量 env.hosts
中指定远程主机,我们将代码修改为:
from fabric.api import run, env env.hosts=[‘dev01’, ‘dev02’] def test_remote(): run(“hostname”)
执行结果如下:
[root@centos1 fabv1]# fab test_remote [dev01] Executing task ‘test_remote’ [dev01] run: hostname [dev01] Login password for ‘root’: [dev01] out: dev01 [dev01] out: [dev02] Executing task ‘test_remote’ [dev02] run: hostname [dev02] out: bogon [dev02] out: Done. Disconnecting from dev01… done. Disconnecting from dev02… done. [root@centos1 fabv1]#
通过 env.hosts
设置远程主机,对于所有的 task
全局有效。如果每个 task
有不同的执行主机,可以给 task
使用 hosts
修饰器单独指定, 如
my_hosts=(‘dev01’, ‘dev03’) @hosts(my_hosts) def test_remote2(): run(‘hostname’)
执行结果如下:
[root@centos1 fabv1]# fab test_remote2 [dev01] Executing task ‘test_env’ [dev01] run: hostname [dev01] Login password for ‘root’: [dev01] out: dev01 [dev01] out: [dev03] Executing task ‘test_env’ [dev03] run: hostname [dev03] out: bogon [dev03] out: Done. Disconnecting from dev01… done. Disconnecting from dev03… done. [root@centos1 fabv1]#
此外,还可以给不同的远程主机定义 Roles
, 再将不同角色分配到不同的 task
。 具体细节可参考: http://docs.fabfile.org/en/1.14/usage/execution.html#roles
在上面的示例中,在执行前都需要输入主机密码。也可以将密码提前在代码中写好,则不再需要输入。
env.password = ‘123456’
若主机密码不一致,可以通过 env.passwords
中按每台主机来指定密码。该变量是 dict
类型, 它的 key
必须必须是用户名、主机、端口的组合,这三个元素必须全部提供,如:
env.passwords = {‘root@dev01:22′:’123456’, ‘root@dev03:22’:’456789’}
这种方法需要将密码编写在文件中,存在安全风险,官方还是推荐使用SSH KEY登录。
本文只简要介绍fabric的用法,其他如并行执行,与远程程序的交互等可以参考官方文档: http://docs.fabfile.org/en/1.14/