资讯专栏INFORMATION COLUMN

SSH连接与自动化部署工具paramiko与Fabric

ermaoL / 1556人阅读

摘要:是基于实现的远程安全连接,支持认证及密钥方法。利用函数发送到,通过函数获取回显。如下全局属性设定对象的作用是定义的全局设定,支持多个属性及自定义属性。相比确实简化了不少。出现异常时,发出警告,继续执行,不要终止。

paramiko

paramiko是基于Python实现的SSH2远程安全连接,支持认证及密钥方法。可以实现远程命令执行,文件传输,中间SSH代理等功能,相对于Pexpect,封装层次更高。

pip install Paramiko

http://www.paramiko.org/
demo:https://github.com/paramiko/p...

如果在linux环境,还需安装依赖:crypto,ecdsa,python3-devel。

paramiko包含两个核心组件:SSHClient类,SFTPClient类

密钥方式登录
import paramiko, base64,getpass
 
paramiko.util.log_to_file("syslogin.log") #日志记录
try:
        key=paramiko.RSAKey.from_private_key_file("pk_path")
except paramiko.PasswordRequiredException:
        password = getpass.getpass("RSA key password: ")
        key = paramiko.RSAKey.from_private_key_file("pk_path", password)    # 需要口令的私钥
#key = paramiko.RSAKey(data=base64.decodestring("AAA..."))
client = paramiko.SSHClient()
# client.get_host_keys().add("ssh.example.com", "ssh-rsa", key)
client.load_system_host_keys()#~/.ssh/known_hosts
client.connect("ssh.example.com", 22,username="strongbad", password="thecheat",pkey=key)
stdin, stdout, stderr = client.exec_command("ls")
# stdin, stdout, stderr=ssh.exec_command("sudo su")
# stdin.write("123456")
for line in stdout:
    print("... " + line.strip("
"))
#使用send
# cmds=["sudo su
", "cd /var/log
", "ls
"] #利用send函数发送cmd到SSH server,添加"
"做回车来执行shell命令。注意不同的情况,如果执行完telnet命令后,telnet的换行符是

# ssh=s.invoke_shell() #在SSH server端创建一个交互式的shell,且可以按自己的需求配置伪终端,可以在invoke_shell()函数中添加参数配置。
# for cmd in cmds:
#         time.sleep(1)
#         ssh.send(cmd) #利用send函数发送cmd到SSH server,
#         out = ssh.recv(1024) #.recv(bufsize)通过recv函数获取回显。
#         print out
client.close()
用户名密码方式登录
#####################################################################################
import paramiko
 
paramiko.util.log_to_file("syslogin.log") #日志记录
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("192.168.8.248", 22, username="root", password="password", timeout=4)
stdin, stdout, stderr = client.exec_command("ls -l")
#print(stdout.read())
for line in stdout.readlines():
  print(line)
client.close()

SSHClient方法参数说明
connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None)

pkey-私钥类型
key_filename-str or list(str) 私钥文件或其列表
timeout-以秒为单位
allow_agent-为False时禁用连接到SSH代理
look_for_keys-为False时禁用在~/.ssh中搜索私钥文件
exec_command(command, bufsize=-1, timeout=None, get_pty=False)
command-字符串

load_system_host_keys(filename=None)指定公钥文件,默认为~/.ssh/known_hosts

set_missing_host_key_policy(policy):设置连接的远程主机没有本地主机密钥时的策略。目前支持三种: RejectPolicy (the default), AutoAddPolicy, WarningPolicy

上传与下载文件
#上传批量文件到远程主机
import paramiko
import os
import datetime
 
hostname = "74.63.229.*"
username = "root"
password = "abc123"
port = 22
local_dir = "/tmp/"
remote_dir = "/tmp/test/"
if __name__ == "__main__":
    #    try:
    t = paramiko.Transport((hostname, port))
    t.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(t)
    #        files=sftp.listdir(dir_path)
    files = os.listdir(local_dir)
    for f in files:
        "#########################################"
        "Beginning to upload file %s " % datetime.datetime.now()
        "Uploading file:", os.path.join(local_dir, f)
        # sftp.get(os.path.join(dir_path,f),os.path.join(local_path,f))
        sftp.put(os.path.join(local_dir, f), os.path.join(remote_dir, f))
        "Upload file success %s " % datetime.datetime.now()
    t.close()

参考http://www.cnblogs.com/yangsh...

Fabric

Fabric是基于paramiko的基础上做了一层更高的封装,操作起来更加方便。
官网:http://www.fabfile.org/index....
github:https://github.com/fabric/fab...

依赖crypto,paramiko.注意:fabric目前不支持Python3.不过github上有个支持py3的版本https://github.com/mathiasert...

在windows上的安装:
1、安装pycrypto.
有几种方式安装:
A.win7下安装 MSVC2010,然后通过pip install pycrypto编译安装.

B.选择别人编译好的。
pycrypto-for-python-3-2及以下
pycrypto-for-python-3-4

2、支持Python3的版本安装:pip install Fabric3

fabfile.py
from fabric.api import run
def host_type():
    run("uname -s")

通过fab命令执行。-f指定文件,-H指定主机列表.

$ fab -f fabfile.py -H localhost,linuxbox host_type

fab参数说明:
-f 指定入口3文件
-g 指定网关设备(中转,堡垒机)IP
-H 指定目标主机,多个用“,”分割
-P 异步运行多主机任务
-R 指定角色,以角色来区分机组
-t 设备连接超时时间,秒
-T 远程主机命令执行超时时间,秒
-w 当命令执行失败,发出警告,而不是终止任务。
当然我们完全可以在代码中设定这些选项值,而无需在命令行指定。如下:全局属性设定
env对象的作用是定义fabfile的全局设定,支持多个属性及自定义属性。

env.hosts,定义目标主机,列表
env.exclude_hosts,排除主机,列表
env.user,定义用户名,str
env.port , 定义端口,str
env.password,定义密码,str
env.passwords,字典,但是形式如下:env.passwords={ "root@192.168.1.21:22":"123456","root@192.168.2.21:22":"1234"}
env.key_filename=None 指定SSH密钥文件,str or list
env.gateway指定网关设备(中转,堡垒机)IP,str
env.roledefs定义角色分组,字典:env.roledefs={ "web":["192.168.1.21","192.168.1.23"],"db":["192.168.1.22","192.168.1.24"]}
env.parallel=False是否并发执行任务
env.path=" " 定义在run/sudo/local使用的$PATH环境变量
env.command_timeout=None
env.timeout=10
env.shell=“/bin/bash -l -c”
env.ssh_config_path=“$HOME/.ssh/config”
env.sudo_password=None
env.sudo_passwords={}
env.use_ssh_config=False
env.warn_only=False,如果为True,当操作遇到错误时,发出警告并继续执行,而不是终止
env.变量名 自定义变量

例如:

@roles("web")
def webtask():
    run("/etc/init.d/nginx start")
@roles("db")
def dbtask():
    run("/etc/init.d/mysql start")
 
@roles("web","db")
def publicstask():
    run("uptime")
def deploy():
    execute(webtask)
    execute(dbtask)
    execute(publictask)

然后终端执行命令就可以了

$ fab deploy

命令行传参:

def hello(name="world"):
    print("Hello %s!" % name)
$ fab hello:name=Jeff
Hello Jeff!
Done.
常用API

fabric.api模块:

local,执行本地命令,如local("uname -s")
lcd,切换本地目录,如lcd("/home")
cd,切换远程目录
run,执行远程命令
sudo,sudo方式执行远程命令
put,上传文件到远程主机 put("/home/aaa","/home/xby/aaa")
get,从远程主机下载文件到本地 get("/opt/bbb","/home/bbb")
prompt,获取用户输入
confirm,获得提示信息确认,如confirm("Continue[Y/N]?")
reboot,重启远程主机,如reboot()
@task函数装饰器,标识函数为fab可调用的,否则对fab不可见
@runs_once,标识函数只会执行一次,不受多台主机影响。
@roles,表示函数执行时的主机角色
@parallel(pool_size=)
@with_settings()

fabric.contrib.console.confirm(question, default=True) 用户输入Y/n,返回True/False

示例1:查看本地与远程主机信息:
from fabric.api import *
 
env.user="root"
env.hosts=["192.168.1.2","192.168.1.3"]
env.password="123"
 
@runs_once #即使有多台主机,但它只会执行一次
def local_task():
    local("uname -a")
def remote_task():
    with cd("/data/logs"): #这个with的作用是让后面的表达式语句继承当前的状态,实现"cd /data/logs && ls -l"的效果。
        run("ls -l")
$ fab -f sample.py local_task
$ fab -f sample.py remote_task
示例2:动态获取远程目录
from fabric.api import *
from fabric.contrib.console import confirm
 
env.user="root"
env.hosts=["192.168.1.2","192.168.1.3"]
env.password="123"
 
@runs_once
def input_raw():
    return prompt("please input dir name:",default="/home")
def worktask(dirname):
    run("ls -l "+dirname)
@task
def go():
    dirname=input_raw()
    worktask(dirname)
示例3:网关模式文件上传与执行

其实只要定义好env.gateway的ip就行了。相比paramiko确实简化了不少。

from fabric.api import *
from fabric.contrib.console import confirm
from fabric.context_managers import *
 
env.user="root"
env.hosts=["192.168.1.2","192.168.1.3"]
env.password="123"
env.gateway="192.168.22.2"
 
lpath="/home/install/lnmp.tar.gz"
rpath="/tmp/install"
 
@task
def put_task():
      run("mkdir -p /tmp/install")
      with settings(warn_only=True): #put出现异常时,发出警告,继续执行,不要终止。
        result=put(lpath,rpath) #上传
       if result.failed and not confirm("put failed,continue[Y/N]?"):
        abort("Aborting")
@task 
def run_task():
      with cd("/tmp/install"):
         run("tar -zxvf lnmp.tar.gz")
       with cd("lnmp"):
        run("./install.sh")
 
@task go():
  put_task()
  run_task()
多彩输出

fabric.colors.blue(text, bold=False)
fabric.colors.cyan(text, bold=False)
fabric.colors.green(text, bold=False)
fabric.colors.magenta(text, bold=False)
fabric.colors.red(text, bold=False)
fabric.colors.white(text, bold=False)
fabric.colors.yellow(text, bold=False)

from fabric.colors import red, green
print(red("This sentence is red, except for " + green("these words, which are green") + "."))
示例-Fabric部署Flask应用

示例1:它可以把当前的源代码上传至服务器,并安装到一个预先存在 的 virtual 环境:

from fabric.api import *
# 使用远程命令的用户名
env.user = "appuser"
# 执行命令的服务器
env.hosts = ["server1.example.com", "server2.example.com"]
def pack():
    # 创建一个新的分发源,格式为 tar 压缩包
    local("python setup.py sdist --formats=gztar", capture=False)
def deploy():
    # 定义分发版本的名称和版本号
    dist = local("python setup.py --fullname", capture=True).strip()
    # 把 tar 压缩包格式的源代码上传到服务器的临时文件夹
    put("dist/%s.tar.gz" % dist, "/tmp/yourapplication.tar.gz")
    # 创建一个用于解压缩的文件夹,并进入该文件夹
    run("mkdir /tmp/yourapplication")
    with cd("/tmp/yourapplication"):
        run("tar xzf /tmp/yourapplication.tar.gz")
        # 现在使用 virtual 环境的 Python 解释器来安装包
        run("/var/www/yourapplication/env/bin/python setup.py install")
    # 安装完成,删除文件夹
    run("rm -rf /tmp/yourapplication /tmp/yourapplication.tar.gz")
    # 最后 touch .wsgi 文件,让 mod_wsgi 触发应用重载
    run("touch /var/www/yourapplication.wsgi")

参考:<>

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44217.html

相关文章

  • 如何通过Telnet和SSH远程监控主机

    摘要:子程序执行将在新进程中完成。要在上执行子程序,该类将使用该函数。如果是字符串,则字符串指定要通过执行的命令。如果是任何其他负值,则表示完全缓冲。它用于通过网络进行系统管理和应用程序部署。 showImg(https://segmentfault.com/img/remote/1460000018833620); 来源 | 愿码(ChainDesk.CN)内容编辑 愿码Slogan |...

    BothEyes1993 评论0 收藏0
  • ansible动化部署(一)

    摘要:自动化部署最近因为工作需要学习了把这几天所学的东西做了个总结,和大家分享一下什么是能干什么是新出现的自动化运维工具,基于开发,集合了众多运维工具的优点,实现了批量系统配置批量程序部署批量运行命令等功能。 ansible自动化部署 最近因为工作需要学习了ansible,把这几天所学的东西做了个总结,和大家分享一下: 1、什么是ansible?ansible能干什么? ansible是新出...

    娣辩孩 评论0 收藏0
  • 在Centos6.3安装Python Fabric运行环境

    摘要:背景在下安装的时候,总是安装不成功,在执行命令的时候,总是会抛出错误。解决方案安装替代系统默认的再安装包系统默认自带的版本是下载安装包在的官网下载页面下载的源码包。在下安装就省事很多。附上执行简单部署的一份代码例子,仅供参考。 背景 在Centos6.3下安装fabric的时候,总是安装不成功,在执行fab命令的时候,总是会抛出错误。 Traceback (most recent ...

    HackerShell 评论0 收藏0
  • python中paramiko模块的使用

    摘要:是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,和内部的远程管理就是使用的来现实。 paramiko paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。 1、下载安装 pycrypto,由于 paramiko 模块内部...

    Cobub 评论0 收藏0

发表评论

0条评论

ermaoL

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<