zoukankan      html  css  js  c++  java
  • 自动化运维工具fabric使用教程

     

    摘要:当需要同时管理许多服务器时,如果我们一台一台登陆上去操作会显得费时又费力。此时我们可以用fabric这个包提供的API来编写python脚本完成服务器集群的统一管理。

    核心原理:fabric为主动ssh至主机执行指定操作,而不是在主机上装agent接收指令。

     

    1、安装

    pip install fabric3  ====>可以把fabric看做是一个软件,安装后提供操作系统级命令“fab”,然后这个软件开放一些API,可以通过python去调用

     

     

     

    2fab常用参数(操作系统级命令“fab”的使用参数)

    格式:fab 选项参数

    常用选项参数:

    -l:查看目标fab程序可用的函数。(需要和-f结合使用)

    -f:告诉fab程序去读取哪个.py文件

    -g:指定网关

    -H:指定需要控制的目标主机,多个主机用“,”隔开

    -P:以异步并行方式运行多主机任务,默认为串行任务。(可以理解为多线程执行,默认为一个线程)

    -u:指定主机用户名

    -p:指定主机密码

     

    例:fab -p 密码 -H 主机1,主机2 --'命令'

        fab -u root -p 密码 -H '172.20.163.121,172.20.163.126' -- 'ifconfig'   ===>执行此命令后会输出172.20.163.121172.20.163.126ifconfig信息

     

     

     

     

     

    3fabfile脚本编写

     

    3.1、普通场景示例(适用于所有服务器的用户名、密码、业务类型都一致的情况)(即:一个程序对应一个集群):

     

    from fabric.api import *  ===>导入fabric

     

    # 全局属性的设定()

    # envfabric.api里面的一个对象,可以通过操纵它的各个属性实现对自动化运维程序的全局参数配置,它的属性包括目标主机ip、用户、密码、角色等

     

    # 1env.host:存放目标主机的列表

    env.hosts = ['192.168.1.1', '192.168.1.2']

     

    # 2env.user:定义用户名

    env.user = 'root'

     

    # 3env.port:定义端口

    env.port = 22

     

    # 4env.password:定义密码

    env.password = '123456'

     

     

    @task    ===> 如果没加@roles@hosts等装饰器,一旦下面这个函数被执行,则全局env.hosts里面所有的机器都会运行函数内的命令

    def show_net():

        run('ifconfig')  ===>在远程主机上执行“ifconfig”命令(默认情况下fabric会调用/bin/bash来执行该命令,这时如果你连接的是交换机等CLI命令的设备就会出错)

     注意:run('show ip route', shell=False) ===>默认情况下fabric会调用/bin/bash来执行该命令,这时如果你连接的是交换机等CLI命令的设备就会出错,此时将shell参数设为False就可以了

     

     

    if __name__ == '__main__':

        execute(show_net)   ===>如果不使用execute这个函数去执行show_net,则show_net只能用'root@HK:~# fab -f 文件名.py show_net'的方式执行。用了execute后就可以用'python3 文件名.py'的方式执行了。

    ===>执行以上代码后程序会ssh'192.168.1.1', '192.168.1.2'这两台机器上执行'ifconfig'命令并返回结果

     

     

     

    3.2、将不同主机进行分组管理场景(适用于被管理服务器密码、业务类型不相同的情况):

     

    from fabric.api import *  ===>导入fabric

     

    # 5env.passwords:定义多台主机的用户名、IP地址、端口、密码(适用于:一堆服务器的密码不都一样的情况)

    env.passwords = {

        'root@172.20.163.121:22': '123456',   ====>测试发现去掉"root@"":22"后会报错

        'root@172.20.163.126:22': '123456',

    }

     

     

    # 6env.gateway:定义网关  ====>适用于通过跳板机(堡垒机)登陆的方式

    # env.gateway = '192.168.1.254'  ===>因没有环境,所以先把它注掉,这里只是说明有这个功能而已

     

     

    # 7env.roledefs:定义角色分组(可按业务类型将主机进行分组管理)

    env.roledefs = {

        'group1': ['172.20.163.121'],

        'group2': ['172.20.163.126']

    }

     

    @task

    @roles('group1', 'group2')    ====>这个函数被执行时会在'group1', 'group2'这两个组成员上生效

    def show():

        run('uname -a')

     

     

    @task   

    @roles('group1')   ====>这个函数被执行时会在'group1'个组成员上生效

    def show_net():

        run('ifconfig')

     

     

    @task

    @roles('group2')   ====>这个函数被执行时会在'group2'个组成员上生效

    def show_mem():

        run('free -m')

     

     

    if __name__ == '__main__':

        execute(show)       ===>执行show函数时group1group2两个分组内的成员都会执行

        execute(show_net)   ===>执行show-net函数时只有group1分组内成员执行

        execute(show_mem) ===>执行show_mem函数时只有group2分组内成员执行

     

     

     

     

     

     

     

    4、本地与远程运维常用API(本地指运行fabric程序端,远程指被ssh端)

     

    # 1local:执行本地命令

    语法:local('本地命令')

     

    # 2lcd:切换到本地目录

    语法:lcd('本地目录')

     

    例:

    def local_cmd():

        with lcd(r'C:UsersAdministrator'):   ===>切换到C:UsersAdministrator目录(临时性,执行完with这个整体后仍然处在原来的路径)

            local('dir')                       ===>C:UsersAdministrator路径下执行'dir'命令

        local('dir')              ===>执行完with这个整体后再次执行dir发现还处在没有切换目录前的路径

     

     

     

     

     

    # 3cd:切换远程目录

    语法:cd'远程目录'

     

    # 4run:执行远程命令

    语法:run'远程命令'

     

    例:

    def remote_cmd():

        with cd(r'/'):                         ===>切换到/目录(临时性,执行完with体仍然处在原来的路径)

            run('pwd')    ===>此时执行pwd输出路径为'/'

        run('pwd')    ===>此时执行pwd输出路径为'/root'

     

     

     

     

    5put:上传本地文件到远程主机

    语法:put('本地文件', '远程目录')

    例:

    def upload():

        put(r'C:UsersAdministratorDesktopdjango.txt', '/root/111.txt')

     

    6get:从远程主机下载文件到本地

    语法:get('远程文件', '本地目录')

    例:

    def download():

        get('/root/get-pip.py', r'C:UsersAdministratorDesktopiiii.py')

     

     

     

     

     

     

     

    7、异常处理和文件校验

    from fabric.api import *

    from fabric.contrib.console import confirm

    from fabric.colors import *    ====>文字颜色库,包含white()yellow()red()blue()green()cyan()magenta()等函数,将字符串丢进去即可为字符串上色。例:print(yellow('abc')) ===>此时将输出黄色的'abc'

     

    def abnormal():

        # 异常处理

        with settings(warn_only=True):

            result = put(r'./222.txt', '/root/abc.txt')

        if result.failed and not confirm("put file failed,Continue[Y/N]?"):   ===>如果路径错误result.failed将为真,如果result.failed为真后弹出交互界面问用户是否要继续,如果输入N,则not 0为真,则执行abort("Aborting file put task ")

            abort("Aborting file put task ")

     

        # 文件校验

        with settings(warn_only=True):

            local_md5 = local(r'md5sum ./222.txt', capture=True).split(" ")[0]   # capture作用:这个开启后输出结果将不再打印至屏幕,而是将结果赋给local_md5

            remote_md5 = run('md5sum /root/abc.txt').split(" ")[0]               # run函数不用capture参数,默认既会打印至屏幕,也会赋值给remote_md5

        if local_md5 == remote_md5:

            print(green('校验通过'))

        else:

            print(red('校验失败'))

     

     

     

     

     

    confirm说明:

    from fabric.contrib.console import confirm

     

    a = confirm('是否要继续?')   ====>confirm将弹出交互界面:'是否要继续? [Y/n]'    用户可输入YN

    print(a)    =====>如果用户输入的是Y,则此处打印True。如果用户输入的是N,则此处打印False

     

     

     

     

     

     

    5、装饰器说明:

     

    fab调用装饰器:@task

    如果函数前面加了这个装饰器就可以用操作系统级别命令fab直接调用这个函数。如果没加则无法用fab直接调用。例:

    @task

    def remote_cmd():

        run('ifconfig')

    root@HK:~# fab -f ssh.py remote_cmd   ====>如果加了@task则可以直接这么用,如果没加则不能这么用

     

    并行装饰器:@parallel

    角色装饰器:@roles(分组名)

    @task

    @parallel    ====>当有多个主机要执行下面函数任务时,加上这个装饰器就可以起多个进程并行处理了。

    @roles('group1', 'group2')    ====>多个分组需要执行下面函数

    def remote_cmd():

        run('ifconfig')

     

    主机装饰器:@hosts(主机1,主机2

    @task

    @parallel    ====>当有多个主机要执行下面函数任务时,加上这个装饰器就可以起多个进程并行处理了。

    @roles('172.20.163.100', '172.20.163.101')    ====>除了分组方法外,也可以手工指定哪台主机要执行下面函数。

    def remote_cmd():

        run('ifconfig')

     

     

     

     

     

  • 相关阅读:
    React路由基本的使用(一)
    Codeforces Round #627 (Div. 3) C
    Codeforces Round #627 (Div. 3) B
    Codeforces Round #627 (Div. 3) A
    hdu2049 不容易系列之(4)——考新郎(组合,错排)
    Codeforces Round #626 (Div. 2) E. Instant Noodles(二分图,最大公因数)
    Codeforces Round #626 (Div. 2) D. Present(位运算)
    逆元的计算方法
    Educational Codeforces Round 83 D. Count the Arrays(组合,逆元,快速幂)
    hdu4460 Friend Chains(记忆化广度优先搜索)
  • 原文地址:https://www.cnblogs.com/baihualin/p/10764966.html
Copyright © 2011-2022 走看看