在使用 Fabric 的过程中,如果大批量服务器处理的话,我们就需要针对配置主机的密码,每台主机的密码相同还好,不同的话,就需要针对不同的主机做配置了,以下有两种配置方式
注:本文主要参考官方文档 Password management 以及 grimnes 的文章 Using SSH keys with Fabric
env.password
Fabric 在某些场合下通过保持在内存中以及双重缓存来帮助你记录登录密码以及 sudo 密码。当多个系统的密码一样的时候,这可以避免让你重复乏味的输入密码。或者是一个远程系统的 sudo 配置文件没有缓存它自己的密码时候。
第一层是一个默认简单的或是备用的密码缓存。 env.password (它也可以通过命令行参数 --password 或是 --initial-password-prompt 来设定)。这个 env 变量存储单个密码,它会咋当前的 host string 没有指定的主机缓存条目的事件的时候尝试。
env.passwords (复数,表示多个密码),作为每一个主机用户的缓存,为唯一的 user/host/port 组合存储了最近输入的密码1。由于这个缓存,连接具有相同 session 的不同用户和主机,仅仅只要求单个的密码。
依赖于你的配置文件以及你 session 连接的主机的数目,你可能会发现设置这些 env 是非常有用的。尽管如此, Fabric 会在必要的时候自动填充他们,不需要你多余的配置。
特别说明,每次对用户提出的密码提示,这值都会被用于更新这默认的密码缓存以及 env.host_string 当前值的缓存值。
没代码说的球,上代码。NO CODE NO BB
- 所有主机密码一样的代码,下面代码的几台主机是用户名和密码一样的,主要做的事情是批量注释,批量停止应用,以及批量关机
#!/usr/bin/python env
# -*- coding: utf-8 -*-
from fabric.api import env from fabric.api import cd from fabric.api import run from fabric.api import local from fabric.api import get from fabric.api import put env.user = 'username' env.password = 'passwd' env.hosts = ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4'] def get_version(): local('cat /etc/issue') run('cat /etc/issue') #with cd('/root/'): # put('/home/libaoyin/test.txt', 'test.txt', mode=0755) # get('hello_world.txt') run('ls') def get_host_name(): run('hostname') #kill all stockd'service def kill_apps_stockd(): run('killall stockd') #discharge the crontab def comment_crontabl(): put ('/home/apps/ykq/crontab.txt','crontab.txt') run('crontab crontab.txt') # offline stockd's service def offline_stockd(): kill_apps_stockd() comment_crontabl() #shutdown all stockd server def shutdown_stockd_server(): run('sudo poweroff')
- 所有主机的用户名一样,但密码不一样
这里感谢@Kollin 的提示,修正下错误,并且以他的示例程序为例。
不过感觉这个Fabric的这方面这样做的原因应该是“基于不同的用户名和不同的密码考虑的”
没有考虑过相同用户名,不同密码的情况。如果要这样做,个人感觉可以修改源码,然后支持env.user 和 env.passwords拼接的方式。不然每个值都要输入user@
这样要多写很多代码
错误的示例程序。
env.user = 'username'
env.passwords = {'192.168.1.1':'passwd1','192.168.1.2':'passwd2','192.168.1.3':'passwd3'} env.hosts = ['192.168.1.1', '192.168.1.2', '192.168.1.3']
正确的 @Kollin的示例程序
from fabric.api import *
env.hosts = [
'[email protected]',
'[email protected]', ] env.passwords = { '[email protected]:22': 'password1', '[email protected]:22': 'password2', } @task def echo(): run('echo "hello,world"')
注:后续会专门写一篇关于 Fabric 中角色的文章
SSH KEY
官方文档中建议,为了安全起见,最好是使用 SSH KEY 的方式来批量执行主机,操作方式如下:
- 登录服务器,生成 SSH Key
$ ssh-keygen -t rsa -b 4096
键入以上命令后,会出现一连串的提示,忽略它,一直按回车键即可。
执行完成后,将在用户的 ~/.ssh/
目录生成以下两个文件:
~/.ssh/id_rsa 私钥
~/.ssh/id_rsa.pub 公钥
-
公钥填充
把生成的公钥文件
~/.ssh/id_rsa.pub
里面的数据添加进远程服务器的authorized_keys file
文件中注:如果远程服务器没有
.ssh
文件夹,需要创建
scp ~/.ssh/id_rsa.pub user@host:~/.ssh/
cat ~/.ssh/id_rsa.pub >> authorized_keys
然后准备我们的用我们的 SSH Key 代替我们的密码:
#!/usr/bin/python env
from fabric.api import *
from fabric.colors import * from fabric.context_managers import * env.hosts=['168.192.1.10','168.192.1.12'] # env.password='xxxxxx' env.key_filename = "~/.ssh/id_rsa" def ls_path(): print(green("I'm local /home/apps/")) with cd('/home/apps'): run('ls -l') def put_path(): print(green("I'm put local's test file to 10 and 12")) put('/home/apps/test','/home/apps/') print(yellow("I'm 10 or 12 /home/apps/")) with cd('/home/apps'): run('ls -l') def deploy(): execute(ls_path) execute(put_path)
-
我们强烈推荐使用基于 SSH key 的访问方式代替依靠同样的密码,SSH key 方式是更加安全的