Как делать автоматические бэкапы сервера в Облачном хранилище

Резервное копирование — важная часть управления любой IT-инфраструктурой. Потребности в резервном копировании у всех разные, а хранение резервных копий в отдельном хранилище является хорошей практикой.

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

В данной инструкции приведен пример создания скрипта, который будет регулярно запускать консольный клиент, архивировать и переносить важные данные в объектное хранилище — Облачное хранилище.

Требования для выполнения примера

В качестве консольного клиента используем S3cmd с инструментом для автоматизации crontab.

Для начала работы потребуется:

  1. Облачный или выделенный сервер с установленной Ubuntu версии не ниже 18.04.
  2. Настроенный S3cmd.
  3. Пользователь в Облачном хранилище, созданный согласно инструкции Создание нового пользователя.

Создание скрипта для резервного копирования

В данной инструкции рассмотрим создание базового bash-скрипта, который создает резервную копию файла или каталога с помощью tar и далее загружает эту резервную копию в Облачное хранилище с помощью утилиты командной строки s3cmd.

Откройте на своем сервере домашнюю директорию:

cd ~

С помощью редактора nano создайте пустой файл, например, с именем bkupscript:

nano bkupscript.sh

Начните писать скрипт резервного копирования в текстовом редакторе с шебанга. Шебанг — это директива интерпретатора, которая позволяет запускать скрипты или файлы данных как команды и выглядит как последовательность из двух символов: решетки и восклицательного знака. Включая шебанг в начало скрипта, мы говорим оболочке запускать команды файла в bash.

#!/bin/bash

Назначение переменных

Добавьте в скрипт переменные прямо под шебангом в верхней части текстового файла:

#!/bin/bash

DATETIME=`date +%y%m%d-%H_%M_%S`
SRC=$1
DST=$2
GIVENNAME=$3

Где:

  • DATETIME содержит метку времени, которую нужно прикрепить к имени полученного файла, чтобы каждый файл, резервная копия которого хранится в пространстве, имел уникальное имя. Эта временная метка создается путем вызова команды date и форматирования вывода для отображения двух последних цифр года (% y), двух цифр месяца (% m), двух цифр дня (% d), час (% H), минуты (% M) и секунды (% S);
  • SRC — это исходный путь для файла или папки, в которую мы делаем резервную копию. $1 указывает, что мы берем это значение из первого параметра, переданного скрипту;
  • DST — место назначения файла. В нашем случае это имя пространства, в которое мы загружаем резервную копию. Это имя будет получено из второго параметра, переданного в скрипт, как указано в $2;
  • GIVENNAME — выбранное пользователем имя для файла назначения. Результирующее имя файла будет начинаться с GIVENNAME, и к нему будет добавлено DATETIME. Это имя происходит от третьего параметра, переданного скрипту $3.

Вывод сообщений

Добавьте функцию showhelp в скрипт резервного копирования для вывода сообщений в случае сбоя работы скрипта:

#!/bin/bash

DATETIME=`date +%y%m%d-%H_%M_%S`
SRC=$1
DST=$2
GIVENNAME=$3

showhelp(
        echo "\n This script will backup files/folders into a single compressed file and will store it in the current folder."
}

Сбор файлов

Прежде чем скрипт сможет передавать что-либо в выбранное пространство, ему сначала необходимо собрать нужные файлы и объединить их в единый пакет, который мы можем загрузить. Это выполняется с помощью утилиты tar, условных операторов и функции tarandzip:

#!/bin/bash

DATETIME=`date +%y%m%d-%H_%M_%S`
SRC=$1
DST=$2
GIVENNAME=$3

showhelp(
        echo "\n This script will backup files/folders into a single compressed file and will store it in the current folder."
){

}

tarandzip(){
    echo "\n##### Gathering files #####\n"
    tar -czvf $GIVENNAME-$DATETIME.tar.gz $SRC
}

Когда вызывается инструкция if, скрипт выполняет команду tar и ожидает результата. Если команда выполнена успешно, будут выполнены строки после оператора then:

  • вывод сообщения о том, что процесс tar успешно завершился;
  • возвращение кода ошибки 0, чтобы часть кода, вызывающая эту функцию, знала, что все работает нормально.

Часть else этого скрипта будет выполняться только в том случае, если команда tar обнаружит ошибку при выполнении:

  • вывод сообщения о том, что команда tar не выполнена;
  • возвращение кода ошибки 1, что указывает на то, что что-то пошло не так.

Заканчивайте скрипт if/then/else фразой fi, что на языке bash означает, что предложение if закончилось.

Завершенная функция tarandzip будет выглядеть так:

tarandzip(){
    echo "\n##### Gathering files #####\n"
    if tar -czvf $GIVENNAME-$DATETIME.tar.gz $SRC; then
        echo "\n##### Done gathering files #####\n"
        return 0
    else
        echo "\n##### Failed to gather files #####\n"
        return 1
    fi
}

Перенос файлов в объектное хранилище

Добавим в скрипт резервного копирования функцию передачи файла movetoSpace в выбранное пространство с помощью команды s3cmd. Используем s3cmd и переменные, которые мы объявили ранее, для создания команды, которая будет помещать файлы резервных копий в выбранное пространство:

movetoSpace(){
    /bin/s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST
}

Где:

  • /bin/s3cmd вызывает s3cmd — инструмент командной строки, используемый для управления сегментами хранилища объектов;
  • put используется s3cmd для загрузки данных в бакет;
  • $ GIVENNAME- $ DATETIME.tar.gz — это имя резервной копии, которая будет загружена в пространство. Он состоит из четвертой и первой объявленных нами переменных, за которыми следует .tar.gz, и создается функцией tarandzip;
  • s3: // $ DST ; — место, куда мы загружаем файл;
  • s3: // — это схема типа URI, используемая для описания мест хранения объектов в сети, а $DST; — это третья переменная, которую мы объявили ранее.

Добавьте уведомления о том, что процесс переноса файлов начался:

movetoSpace(){
     echo “\n##### MOVING TO SPACE #####\n”
    /bin/s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST
}

Поскольку команда будет либо успешной, либо неудачной (это означает, что она либо загрузит файлы в выбранное пространство, либо нет), можно сообщить пользователям, сработала ли она, повторив одну из двух строк, содержащихся в if/then/else, например:

if /bin/s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST; then
    echo "\n##### Done moving files to s3://"$DST" #####\n"
    return 0
else
    echo "\n##### Failed to move files to the Space #####\n"
    return 1
fi

В целом функция movetoSpace должна выглядеть так:

movetoSpace(){
echo “\n##### MOVING TO SPACE #####\n”

if /bin/s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST; then
    echo "\n##### Done moving files to s3://"$DST" #####\n"
    return 0
else
    echo "\n##### Failed to move files to the Space #####\n"
    return 1
fi

Настройка управления потоком

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

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

Мы можем упорядочить отлов ошибки, добавив в конец файла условную инструкцию if / then / else:

if [ ! -z "$GIVENNAME" ]; then
    if tarandzip; then
        movetoSpace
    else
        showhelp
    fi
else
    showhelp
fi

Первый оператор if в приведенном выше разделе проверяет, что третья переданная переменная не пуста. Это происходит следующим образом:

  • [] — квадратные скобки означают, что то, что находится между ними, является тестом. В этом случае проверка заключается в том, чтобы конкретная переменная не была пустой;
  • ! — в данном случае этот символ означает «нет»;
  • -z — эта опция указывает на пустую строку и в сочетании с ! мы запрашиваем не пустую строку;
  • $ GIVENNAME указывает, что строка, которая не должна быть пустой, является значением, присвоенным переменной $GIVENNAME. Этой переменной присваивается значение, переданное третьим параметром, при вызове скрипта из командной строки. Если мы передадим сценарию менее 3 параметров, в коде не будет третьего параметра для присвоения значения $GIVENNAME, он назначит пустую строку и этот запуск завершится ошибкой.

Пример скрипта

Завершенный скрипт выглядит следующим образом:

#!/bin/bash

DATETIME=`date +%y%m%d-%H_%M_%S`
SRC=$1
DST=$2
GIVENNAME=$3

showhelp(){
        echo "\n This script will backup files/folders into a single compressed file and will store it in the current folder."
     }

tarandzip(){
    echo "\n##### Gathering files #####\n"
    if tar -czvf $GIVENNAME-$DATETIME.tar.gz $SRC; then
        echo "\n##### Done gathering files #####\n"
        return 0
    else
        echo "\n##### Failed to gather files #####\n"
        return 1
    fi
}
movetoSpace(){
    echo "\n##### MOVING TO SPACE #####\n"
    if /bin/s3cmd put $GIVENNAME-$DATETIME.tar.gz s3://$DST; then
        echo "\n##### Done moving files to s3://"$DST" #####\n"
        return 0
    else
        echo "\n##### Failed to move files to the Spac #####\n"
        return 1
    fi
}

if [ ! -z "$GIVENNAME" ]; then
    if tarandzip; then
        movetoSpace
    else
        showhelp
    fi
else
    showhelp
fi

После проверки скрипта закройте файл сочетанием клавиш CTRL+Х и сохраните внесенные изменения клавишей Y+ENTER перед выходом из nano.

Автоматизация резервного копирования с помощью Crontab

Настройте задание cron, которое будет использовать скрипт для регулярного резервного копирования в выбранное пространство. В рамках этого примера резервное копирование будет выполняться каждую минуту.

Сделайте скрипт исполняемым:

chmod +x bkupscript.sh

Отредактируйте файл crontab, чтобы скрипт запускался каждую минуту:

crontab -e

При первом запуске команды crontab -e будет предложено выбрать редактор из списка:

no crontab for root - using an empty one
Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny
Choose 1-4 [2]:

Можно выбрать nano по умолчанию или любой другой текстовый редактор.

Перейдя в crontab, добавьте следующую строку внизу скрипта:

* * * * * ~/bkupscript.sh ~/backupthis nameofyourspace cronupload

Закройте файл сочетанием клавиш CTRL+Х и сохраните внесенные изменения клавишей Y+ENTER.

Если оставить задание cron запущенным без каких-либо изменений, новый файл будет копироваться в выбранное пространство каждую минуту. Убедившись, что cron работает успешно, перенастройте crontab для резервного копирования файлов с нужным интервалом.