Подробное объяснение инструмента удаленного развертывания Python Fabric

Python

Операционная среда: Python2.7, Fabric1.x

Введение

Fabric — это модуль Python. Основанный на SSH, он предоставляет богатый интерактивный интерфейс, который можно использовать для автоматического выполнения команд Shell на локальных или удаленных компьютерах. Он очень подходит для удаленного развертывания и системного обслуживания приложений.

В основе Fabric лежит paramiko (paramiko — это библиотека для ssh-соединений).

применение

Установить ткань

$ pip install fabric

Мелкий измельчитель

Файл сценария по умолчанию для Fabric:fabfile.py, создайте файл и определите функцию, начинающуюся с приветствия:

def hello():
    print("Hello Fabric!")

можно использовать параметры-lперечислить текущиеfabfile.pyкакие задачи определены вfabfile.pyВыполните команду в каталоге, чтобы увидеть вывод:

$ fab -l
Available commands:

    hello
    
$ fab hello
Hello Fabric!

Done.

Каждая функция в fabfile.py представляет задачу, а имя задачи — это имя функции. Команда fab используется для выполнения задачи, определенной в fabfile.py, и должна отображать указанное имя задачи.

Задачи также могут принимать параметры, например, мы меняем функцию hello на:

def hello(name, value):
    print("Hello Fabric! %s %s." % (name, value))

На этом этапе при выполнении задачи приветствия вам необходимо передать параметры:

$ fab hello:name=Year,value=2017

Сценарий, который Fabric выполняет по умолчанию:fabfile.py, если вы хотите изменить файл сценария, вам нужно использовать-fуказано. Например, мы помещаем задачу hello вscript.pyбудет выполнен в:

$ fab -f script.py hello:name=Year,value=2017

выполнить локальную команду

Содержимое fabfile.py выглядит следующим образом:

#-*- coding:utf-8 -*-
from fabric.api import local

def taskA():
    local('touch fab.out && echo "fabric" >> fab.out')

def taskB():
    # capture参数可以捕获标准输出存到变量,默认为False
    output = local('echo "Hello World."', capture=True)
    print(output)

Выполнить задания:

$ fab taskA taskB

выполнять удаленные команды

Настоящая сила Fabric заключается в том, что он может легко выполнять команды Shell на удаленных машинах и основан на SSH.

#-*- coding:utf-8 -*-
from fabric.api import run, env

# env被称为环境字典,用来配置一些运行环境相关的信息
env.hosts = ['192.168.1.100', '192.168.1.101']
env.user = 'user'
env.password = 'passwd'

def taskA():
    run('cd /usr/local/webserver/php && ls -l')
    run('sudo /usr/local/webserver/nginx/sbin/nginx -t')

env.hostsЭто для установки списка машин, или вы можете написать пользователя напрямую на хосты:

env.hosts = ['user@192.168.1.100', 'user@192.168.1.101']

Если это не указано в кодеenv.hosts, либо при выполнении задачи через-Hпараметры для указания:

$ fab -H 192.168.1.100 taskA

Словарь среды Fabric.state.env реализован как глобальный синглтон и также для удобства включен в Fabric.api. Ключи в env также часто называют переменными среды.

Вот несколько часто используемых переменных среды:

  • user: вы можете указать имя пользователя, которое Fabric использует при установлении SSH-соединения, установив env.user (локальное имя пользователя используется по умолчанию).
  • пароль: используется для явной установки соединения по умолчанию или для предоставления пароля sudo, если это необходимо. Если пароль не установлен или введен неправильно, Fabric предложит вам ввести его.
  • passwords: словарь паролей, установка паролей для разных машин.
  • warn_only: логическое значение, используемое для установки выхода Fabric при обнаружении удаленной ошибки.
  • hosts: глобальный список хостов.
  • roledefs: словарь отображения, определяющий имена ролей и списки хостов.

Если вы хотите выполнять разные задачи для разных серверов, вышеуказанная программа не может этого сделать, нам нужно определить роли для серверов:

#-*- coding:utf-8 -*-
from fabric.api import env, roles, run, execute, cd

env.roledefs = {
    'dev': ['user1@10.216.224.65', 'user2@10.216.224.66'],
    'online': ['user3@45.33.108.82']
}

# host strings必须由username@host:port三部分构成,缺一不可,否则运行时还是会要求输入密码
env.passwords = {
    'user1@10.216.224.65:22': 'passwd1',
    'user2@10.216.224.66:22': 'passwd2',
    'user3@45.33.108.82:22': 'passwd3'
}

@roles('dev')
def taskA():
    with cd('/usr/local/webserver'):
        run('pwd')

@roles('online')
def taskB():
    run('pwd')

def task():
    execute(taskA)
    execute(taskB)

Затем выполните задачу задачи:

$ fab task

Fabric выполнит задачу A на компьютере разработчика, а затем задачу B на онлайн-машине. Декоратор @roles указывает, сервер какой роли будет выполнять украшаемые им задачи.

Автоматический вход по SSH

Все приведенные выше примеры записывают пароль для входа в файл сценария, что небезопасно.Рекомендуемый метод — установить SSH KEY для автоматического входа в систему. Войдите на локальный компьютер, чтобы сгенерировать КЛЮЧ:

$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_fabric

После создания пары ключей добавьте открытый ключ на удаленный сервер.~/.ssh/authorized_keysфайл, вы можете добиться автоматического входа в систему.

#-*- coding:utf-8 -*-
from fabric.api import env, roles, run, execute, cd

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

def taskA():
    with cd('/usr/local/webserver'):
        run('pwd')

Права доступа к файлу Authorized_keys могут быть записаны только владельцем, и никакие другие пользователи не имеют прав на запись, иначе sshd сочтет его небезопасным и не позволит использовать файл, в результате чего потребуется ввести пароль для аутентификации.

менеджер контекста

Менеджер контекста Fabric представляет собой серию методов, используемых в сочетании с оператором Python Python для установки контекста текущей рабочей среды в блоке оператора with.

#-*- coding:utf-8 -*-
from fabric.api import env, lcd, local, cd, path, settings, shell_env, prefix, sudo, run

env.hosts = ['10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

def task():
    # 设置本地工作目录
    with lcd('/usr/local/webserver'):
        local('touch local.out')

    # 设置远程机器的工作目录
    # sudo功能类似run方法,以超级用户权限执行远程命令
    with cd('/usr/local/webserver'):
        sudo('touch remote.out')

    # 添加远程机器的path路径
    # 出了with语句path又回到原来的值
    with path('/usr/local/webserver'):
        run('echo $PATH')
    run('echo $PATH')

    # 设置Fabric环境变量参数
    # fabric.api.env
    # warn_only设置为True,遇到错误不会退出
    with settings(warn_only=True):
        run('echo $USER')

    # shell_env可以用来临时设置远程和本机上的Shell环境变量
    with shell_env(JAVA_HOME='/opt/java'):
        run('echo $JAVA_HOME')
        local('echo $JAVA_HOME')

    # 设置命令执行前缀,等同于 run('echo Hi && pwd')
    with prefix('echo Hi'):
        run('pwd')
        local('pwd')

обработка ошибок

По умолчанию Fabric завершает работу, когда задача сталкивается с ошибкой.Если мы хотим отловить эту ошибку, а не выходить из задачи, нам нужно включить параметр warn_only. Когда мы представили контекстный менеджер settings() выше, мы увидели метод временного включения warn_only.Если вы хотите включить его глобально, есть два метода:

  1. Добавьте параметр -w при выполнении fab
$ fab -w task
  1. Установите для параметра среды env.warn_only значение True.
#-*- coding:utf-8 -*-
from fabric.api import env

env.warn_only = True

При возникновении ошибки консоль теперь печатает предупреждающее сообщение и продолжает выполнение последующих задач. Так как же нам ловить ошибки и обрабатывать их? Такие функции, как local/run/sudo/get/put, имеют возвращаемые значения.Если атрибут успешного возвращаемого значения равен True, выполнение выполнено успешно, в противном случае — сбой; вы также можете проверить атрибут failed возвращаемого значения. True означает, что выполнение не удалось. Произошла ошибка.

#-*- coding:utf-8 -*-
from fabric.api import env, local, cd, put

env.hosts = ['10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'
env.warn_only=True

def task():
    with cd('/data/server'):
    	local('touch /data/server/README.md')
    	upload = put('/data/server/README.md', 'README.md')
    	if upload.failed:
    	    put('/data/server/README.md', 'README.md', use_sudo=True)

параллельное выполнение

Fabric по умолчанию является последовательным при выполнении задач на нескольких машинах. Fabric поддерживает параллельное выполнение задач на нескольких серверах, что может значительно ускорить выполнение. Есть два способа включить параллельное выполнение:

  1. Добавьте параметр -w при выполнении команды fab
$ fab -P task
  1. Установите для параметра среды env.parallel значение True.
#-*- coding:utf-8 -*-
from fabric.api import env
env.parallel = True

Вышеизложенное представляет собой глобальный контроль параллелизма задач. Если мы хотим распараллелить только определенную задачу, мы можем добавить декоратор @parallel в функцию задачи, так что даже если глобальный параллелизм не включен, задачи, украшенные @parallel, будут выполняться параллельно:

#-*- coding:utf-8 -*-
from fabric.api import env, run, parallel

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'

@parallel
def taskA():
    run('echo "parallel"')

def taskB():
    run('echo "serial"')

Если включен глобальный параллелизм и мы хотим, чтобы задача выполнялась последовательно, мы можем добавить декоратор @serial в функцию задачи, так что даже если параллелизм включен, задачи, украшенные @serial, будут выполняться последовательно:

#-*- coding:utf-8 -*-
from fabric.api import env, run, serial

env.hosts = ['10.216.224.65', '10.216.224.66']
env.user = 'user'
env.key_filename = '~/.ssh/id_rsa_fabric'
env.parallel = True

def taskA():
    run('echo "parallel"')

@serial
def taskB():
    run('echo "serial"')

Здесь в основном представлены общие принципы использования Fabric, а подробности см. в официальной документации.