company_banner

Резервное копирование на удаленный сервер

    Назрела необходимость замены медленного rdiff-backup на более шустрое решение для инкрементальных бекапов на удаленый сервер. Сперва рассматривался Rsnapshot, но причине того, что он не умеет без костылей делать бекапы именно на удаленные серверы от него отказались. Прочие аналоги нам также не подошли по тем или иным причинам. Искать что-то готовое на просторах github и допиливать под себя мы не захотели, поэтому было решено написать новый скрипт с нуля своими силами. Главная цель сделать решение для инкрементального бекапа на удаленный сервер схожее с rdiff, но с использованием жестких ссылок rsync.


    Скрипт выложен в нашем репо на github, будем рады получить отзывы, советы, коммиты!

    Инструкция по приминению нашего решения на примере CentOS 6.x

    Подготовка сервера бэкапов.

    Общая настройка.

    Устанавливаем rsync и xinetd:
    yum -y install rsync xinetd

    Добавляем в атозагрузку сервис xinetd:
    chkconfig --add xinetd

    Разрешаем rsync
    vi /etc/xinetd.d/rsync

    Меняем disable = yes на disable = no
    и создаем файл конфигурации /etc/rsyncd.conf

    И добавляем в него:
    pid file = /var/run/rsyncd.pid
    log file = /var/log/rsyncd.log

    На этом общую настройку заканчиваем и переходим к настройке бэкапа под конкретный сервер.

    Настройка окружения для бэкапа сервера.

    Добавляем пользователя если он не еще не добавлен:
    usernames=backup
    useradd -g backups $usernames
    rm -f /home/$usernames/.bash*
    mkdir /home/$usernames/.ssh /home/$usernames/rsyncbackups
    chown -R $usernames:backups /home/$usernames
    chown -R root:root /home/$usernames/.ssh
    touch /home/$usernames/.ssh/authorized_keys
    

    Блок с ключом необходимо заменить на сгенерированные данные id_rsa.pub:
    no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa ---your-ssh-key-here--- root@backup.example.com

    Добавляем в /etc/rsyncd.conf

    cat << EOF >> /etc/rsyncd.conf
    [$usernames]
    comment = backups for $usernames
    path = /home/$usernames/rsyncbackups
    use chroot = true
    uid = root
    gid = root
    log file = /var/log/rsyncd/$usernames.log
    read only = false
    write only = false
    hosts allow = 1.2.3.4
    hosts deny = *
    transfer logging = false
    EOF
    

    где:
    path = /home/$usernames/rsyncbackups - путь где будут лежать бэкапы
    log file = /var/log/rsyncd/$usernames.log - путь к логам
    hosts allow = 1.2.3.4 - IP с которого разрешен доступ к данному окружению
    На этом, настройка серверной части завершена.

    Настройка сервера клиента.

    Для изменения параметров сервера бэкапов, исключений контейнеров из бэкапа, локальной папки (или ее отсутствия) достаточно внести изменения в файл
    rsync-backup.local.conf

    Исключения

    Для исключений существуют файлы со списком исключений, указанных с каждой новой строки без первичного слеша (правила исключений для rsync).

    srv/southbridge/etc/rsync-backup.exclude.dist - файл с общими исключениями
    srv/southbridge/etc/rsync-backup.exclude.local.example - пример названия исключений для локального бэкапа
    srv/southbridge/etc/rsync-backup.exclude.remote.example - пример название исключений для удаленного бэкапа

    Cкрипт бэкапа проверяет наличие файлов srv/southbridge/etc/rsync-backup.exclude.local и srv/southbridge/etc/rsync-backup.exclude.remote и при их наличии добавляет исключения при бэкапах. Если локальный бэкап отменили — локальные исключения добавляются в удаленные.

    Включения

    Особенностью этого скрипта является возможность включения определенных файлов или каталогов из исключенной директории выше иерархией. Для этого нужно создать файлы
    /srv/southbridge/etc/rsync-backup.include.local
    /srv/southbridge/etc/rsync-backup.include.remote
    соотвественно для локальных и удаленных включений.
    Если нужно включить конкретный файл, то необходимо указать его путь без первичного слеша, к примеру:
    var/log/nginx/server.log
    Если же нужно рекурсивно включить директорию, то нужно указать включение так:
    var/log/nginx/**
    Каждое новое включение с новой строки без первичного слеша.

    При работе включений будет бэкапиться вся иерархия директорий контейнера, даже если раннее было добавлено исключение определенных директорий, но бэкапиться будет именно директории без файлов.
    Это особенность работы rsync, к сожалению другого пути пока не нашли.
    Часть скрипта для работы включений:
         if [ -f "$LOCAL_INCLUDE" ]; then
              e "sync include" 
              e "rsync -ax --include=*/ --include-from=$LOCAL_INCLUDE --exclude=* --link-dest=../../Latest $VZ_PRIVATE/$VEID $LOCAL_DIR/$VEID/$WHICH/Processing$DATE" 
              LLOG=`rsync -ax --include=*/ --include-from=$LOCAL_INCLUDE --exclude=* --link-dest=../../Latest $VZ_PRIVATE/$VEID $LOCAL_DIR/$VEID/$WHICH/Processing$DATE 2>&1`
          fi
    


    Дальнейшая работа с бэкапами

    По умолчанию скрипт будет создавать бэкапы: 7 дневных, 4 недельных и 1 месячный для изменения этого в
    /srv/centos-admin.ru/etc/rsync-backup.local.conf можно вписать иные цифры следующих параметров

    DAILY=7
    WEEKLY=4
    MONTHLY=1


    Инкрементальные бэкапы производятся с использованием хардлинков. Поэтому, чтобы сократить объем дискового пространства занимаемого бэкапом, при добавлении исключений, и при чистке бэкапов от этих исключений нужно будет удалить соответствующие директории в каждой папке бэкапов. Конечно можно написать скрипт для автоматизации этой рутины, это в планах.

    В заключение, какой выйгрыш по времени мы все-таки получили:

    Cравнительный тест rdiff vs. rsync:

    Сравнение времени выполнения бэкапа:
    1. Первичный бэкап контейнера в 5Gb (локальный и удаленный)
    rdiff-backup — 6 минут 30 секунд
    rsync-backup — 1 минута 34 секунды

    2. Вторичный бэкап, изменения в контейнерах не было
    rdiff-backup — 30 секунд
    rsync-backup — 2 секунды

    3. Вторичный бэкап, в контейнер добавлена папка c дистрибутивом debian (не iso) в 4.7Gb
    rdiff-backup — 11 минут 32 секунды
    rsync-backup — 2 минуты 15 секунд

    И на графиках, первый скачек — rdiff, второй — rsync



    Southbridge
    477,54
    Обеспечиваем стабильную работу серверов
    Поделиться публикацией

    Комментарии 41

      +15
      Искать что-то готовое на просторах github и допиливать под себя мы не захотели, поэтому было решено написать новый скрипт с нуля своими силами.

      Так и получаются велосипеды =/
        +2
        Я правильно понимаю, что вы написали свою версию rsnapshot?
        А почему не использовали rsnapshot?
        Я правильно понимаю, что инициация бекапа идет со стороны клиента (а не со стороны сервера, как в случае с rsnapshot)?
        Посмотрел в исходники и не нашел cp -al. За счет чего получаются хардлинки между одинаковыми предыдущими копиями?
          0
          Нет, это все-таки немного попроще чем rsnapshot.
          Rsnapshot не подошел как раз потому, что нам нужен бекап с клиентского сервера на сервер бекапов.
          Хардлинки делает rsync c опцией -H

          rsync --help

          -H, --hard-links preserve hard links
            0
            Этот ключик я тоже искал и не нашел в rsync-backup.sh Надо искать где-то в другом месте?

            А бекапы вы делаете на сервер в том же датацентре или в другом?

            И, если таки хардлинки где-то делаются, то сколько это занимает времени на куче мелких файлов? Мы сделали себе аналогичную систему на rsnapshot, но cp -al на каталог с сотнями битриксовских сайтов занимает часы, если в бекапном сервере не ssd.
              0
              --link-dest=DIR

              То есть делается первый бэкап после чего на него создается симлинк, с которым уже и сравнивается последующий. В случае совпадения — создается хардлинк на файл. Сейчас есть неудобство у скрипта в том виде какой он есть сейчас — если нужно подчистить бэкап — нужно удалить все хардлинки.

                0
                А вот и автор. :)
                  0
                  ну и да, после фазы следующего бэкапа — симлинк заменяется новым — на свежий бэкап
                    0
                    Последнего не понял. Что есть «подчистить бэкап»? Зачем удалять все хардлинки?
                      0
                      Ну, бывают случаи когда бэкап какого-то определенного сервера сильно разрастается, и необходимо уменьшить его размер за счет добавления в исключений не критичных данных, после чего подчистить бэкап от этих данных.
                        0
                        Что-то типа
                        rm -fr /path/to/backup/*/home/user/big_folder/
                        не?
                          0
                          НУ да :)
                    0
                    Насчет ключа, я не совсем прав был (скрипт не я писал), там немного по-другому:
                    --link-dest=DIR hardlink to files in DIR when unchanged

                    Насчет датацентров — по разному, иногда в одном и том же, иногда в разных странах серверы.

                    Хардлинки делаются не долго. Из цифр которые я приводил в конце статьи, это можно примерно понять.

                  • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Объясню почему не rsnapshot. в силу удаленности нашего сервера бэкапов, использование монтирования по ssh или NFS мы отмели за ненадежностью. В другом случае rsnapshot делать удаленный бэкапы не умеет, в силу как раз использования хардлинков (да суть та же rsnapshot работает на базе rsync). В нашем случае это удалось обойти использованием rsync сервера, почему к этому не пришли разработчики rsnapshot — не понятно :)
                      0
                      Есть мысль, что удалённому серверу виднее, когда у него сеть и диски менее нагружены. В итоге мы сделали бекапный сервер который по очереди в несколько потоков ходит ко всем клиентам и делает с них снапшоты. И работает это заметно быстрее, чем когда клиенты (особенно не доверенные) в произвольное время (обычно в полночь или 2-3 ночи по москве) массово начинают слать бекапы на сервер, у которого на дисках ~200 иопсов.
                        0
                        Кстати да, забыл почему-то написать — мы то это сделали как раз на rsnapshot — он умеет со стороны сервера ходить к клиентам по ссх и забирать оттуда данные по рсинк, например.
                          0
                          Этот вариант мы отмели из-за специфики работы. Имея большое количество серверов различных клиентов, очень не хочется оставлять дыру в виде рутового парольного доступа на ВСЕ сервера наших клиентов. Можете назвать это паранойей.
                            0
                            А как связаны наличие рутового, да ещё и парольного доступа и бэкап с удалённой машины?
                            А так вы наоборот оставляете дыру ещё большую: кто-то из клиентов может разобраться в вашей системе бэкапа, залезть на бэкапный сервер и стащить чужие бэкапы ( ну это если вы им вдруг рута выдаёте, хотя это не очень ясно из статьи. непонятных моментов после прочтения слишком много (: ).
                              0
                              Рута мы никому не даем, пока обслуживаем сервер.
                                0
                                имелось в виду «непарольного» для бэкапа с удаленной машины (если мы говорим о полном бэкапе контейнеров) нужен рутовый доступ на эту машину. ТО есть разработчики rsnapshot предлагают организовать доступ по ключу.
                                А что касается доступа на сервер бэкапа. тот тут все происходит по иному. За счет настроек rsync сервера во первых область хранения бэкапов конкретного сервера на едином сервере бэкапов зачрутена, да еще и предлагается ограничить IP с которого позволительно обращаться к этому хранилищу,
                                [$usernames]
                                comment = backups for $usernames
                                path = /home/$usernames/rsyncbackups
                                use chroot = true
                                uid = root
                                gid = root
                                log file = /var/log/rsyncd/$usernames.log
                                read only = false
                                write only = false
                                hosts allow = 1.2.3.4
                                hosts deny = *
                                transfer logging = false

                                То есть для хардлинков нужен рутовые права, и rsync сервер позволяет это организовать безопасно, поэтому был и выбран этот вариант на стороне сервера бэкапов.

                                А для операций ротации на стороне сервера бэкапов используется не привилегированный доступ. Для бэкапов каждого клиента заводится отдельный доступ.
                                  0
                                  предлагается ограничить IP с которого позволительно обращаться к этому хранилищу,
                                  ssh тоже такое позволяет. см. AllowUsers в конфиге sshd. Так что rsync over ssh ничуть не уступает в этом плане.
                                  То есть для хардлинков нужен рутовые права
                                  Можно тут подробнее? Что вы имеете в виду?
                                    0
                                    Это я погорячился. Потребность в руте нужна для того что бы сохранить права файлов при бэкапе. rsync запускается с опцией -a, но очевидно что при отсутствии привилегий — этого не получится.
                                      0
                                      При бэкапе с правами всё отлично как раз. Проблемы начинаются при ротации бэкапов, если бэкапится директория, например, с правами 555 ( если ротация устроена по подобию реализации rsnapshot'a)
                                      Однако, разработчики rsnapshot'a в качестве решения рекомендуют не использовать рутовый аккаунт, как это решили делать вы, а использовать более интеллектуальные средства рекурсивного удаления, например rmtree. Чуть подробнее можно прочитать тут.
                                0
                                Тот, кто имеет доступ к бекапному серверу — в любом случае имеет доступ ко всем файлам.

                                У ssh ключей можно прописывать со стороны сервера какие команды разрешено запускать при авторизации по этому ключу — на сколько я понимаю — оставить только rsync — решает вашу задачу.

                                А вот _парольный_ доступ там в любом случае нигде не нужен.
                                  0
                                  Про ограничения для ключа можно поподробнее?
                                    +1
                                    Первая же страница ссылок в гугле по запросу «ssh key limit commands».
                            0
                            Я правильно понял, что вы считаете, что rsnapshot умеет делать бэкап исключительно с локальной машины на локальную, т.к. всё завязано на хардлинки?
                            Или вам принципиально, чтобы именно клиент инициировал бэкап?
                              0
                              Да, принципиален именно пуш бэкапа. и NFS мы отмели
                          0
                          Кстати, вы смотрели на duplicity и dar? Если смотрели, то почему не подошло? Они быстрее rdiff-backup.

                          И, если я правильно догадываюсь по исходникам, что это для бекапа вдс на базе OpenVZ, то почему вы не переходите на ploop и на бекап его снапшотов, diff для которых за счет COW должен получатся даже меньше, чем как сейчас (сейчас большой изменившийся файл будет на бекапном сервере продублирован целиком, если изменится хотя бы его один байт).
                            0
                            Честно говоря в контексте той задачи мы не рассматривали duplicity и dar. Хотя мы с ними знакомы.
                            В нашем случае принципиально было сделать легкое решение на базе rsync, поэтому не долго думаю мы начали писать свой скрипт.

                            Насчет контейнеров — верно. Мы практически везде их используем, но мы их неограничиваем. И использовать ploop для нас нет смысла, поскольку контейнер обычно занимает весь раздел.
                              0
                              Это все понятно, но в случае с ploop можно получить снапшоты с только изменёнными блоками (как при блочной репликации в zfs, примерно).

                              Хотя на не SSD дисках это потом начнет медленно работать, единственный минус.
                            0
                            Я подсел на btrfs — очень удобный механизм снапшотов и инкрементального удалённого бекапа:
                            btrfs subvolume snapshot -r /home /home/BACKUP-new
                            btrfs send -p /home/BACKUP /home/BACKUP-new | btrfs receive /backup/home
                              0
                              Каждый снапшот всё ещё новый блочный дивайс?
                              btrfs receive поверх ssh тоже работает?
                                0
                                Каждый снапшот это как новая папка со своим блекджеком и… Можно примонтировать как девайс или работать как с папкой, если примонтировать уровень выше по дереву.
                                send — это сериализация состояния фс в файл, работать будет через любой пайп. А можно сохранить, передать и развернуть на удалённом сервере с помощью того же receive.
                                  0
                                  Я общую концепцию знаю по знакомству с ZFS. Но к BTRFS есть куча вопросов, включая скорость, деградацию её по времени/месту/количеству снапшотов, мортирует ли каждый снапшот себя в директорию тома и т.п. Полгода-год назад тут был хороший обзор недоделанности btrfs.
                              +1
                              Я не понимаю, почему бы просто не использовать bacula/bareos? Зачем очередной велосипед? Тем более, если я верно понял, есть централизованный сервер. С ростом инфраструктуры поддерживать самописные скрипты — довольно накладно.
                                0
                                Bacula — хорошее решение для корпоративного сектора и это как раз то, что нужно когда одна контора, один центральный сервер. У нас не так — есть много клиентов и все бекапятся кто-куда, у многих есть свои серверы для бекапов. Всем настраивать бакулу не целесообразно. Просто зачем? Если всего два-три сервера и один сервер бекапов? И потом, нам критично быстрое восстановление из бекапа, а не ползанье по консоли бакулы (она может и не самая плохая, но все же с ней процесс замедляется).
                                  0
                                  Если один раз настроили сервер и отдали клиенту — тогда я понимаю (правда, я бы предпочёл более предсказуемый и оттестированный duplicity/duply), но я если я верно понял, то вы так же оказываете поддержку настроенным серверам. В этом случае разумнее использовать bacula/bareos. Там легко настраиваются различные стораджи (куда и какие бэкапы сливать), и есть веб-морды в которых есть права доступа, и бэкапы оттуда легко и быстро извлекаются.
                                0
                                Что непредсказуемого вы видите в нашем решении? Простой скрипт, все прозрачно.

                                P.S. Веб-морды это не наш метод. :) Только консоль, только харкор!

                                P.P.S. Да и с веб-мордами все не так очевидно. Если бы они еще заводились с пол-пинка и работали как надо на всех дистрибутивах (типа как Almir).
                                  0
                                  10 лет назад пользовался для решения подобной задачи скриптом Bontmia: folk.uio.no/johnen/bontmia/
                                    +1
                                    Откройте для себя obnam и не плодите велосипедов :)

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое