мета-данные страницы
Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
| manuals:bareoslto [2024/09/12 13:11] – Администратор | manuals:bareoslto [2024/09/25 07:49] (текущий) – Администратор | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| ====== Свой сервер бэкапирования bareos с возможностью писать на ленточное хранилище ====== | ====== Свой сервер бэкапирования bareos с возможностью писать на ленточное хранилище ====== | ||
| - | У нас в компании имеется ленточное хранилище, | + | У нас в компании имеется ленточное хранилище, |
| - | Я планирую настроить сервер резервного копирования на базе Bareos (Bacula) и организовать хранение архивной информации на ленточных носителях. | + | |
| - | В нашей инфраструктуре используются дисковые полки Infortrend и ленточная библиотека Quantum Scalar i40. | + | Я планирую настроить сервер резервного копирования на базе Bareos (Bacula) и организовать хранение архивной информации на ленточных носителях.\\ |
| - | Физический сервер будет на CentOS Stream release 9 он оснащён двумя процессорами Intel Xeon E5-2609 v3 с тактовой частотой 1.90 ГГц и 64 ГБ оперативной памяти и два сетевых адаптера для подключения к разным сетям. Также предусмотрен адаптер Fiber Channel для связи с дисковыми полками и ленточным хранилищем. | + | |
| - | У меня весь процесс начинается с перенастройки Qlogic, что бы нужные WWPN смотрели в нужные устройства. Подробностей по настройке Qlogic давать не буду т.к. это тема для отдельной статьи с подробными разъяснениями. | + | В нашей инфраструктуре используются дисковые полки Infortrend и ленточная библиотека Quantum Scalar i40.\\ |
| + | |||
| + | Физический сервер будет на CentOS Stream release 9 он оснащён двумя процессорами Intel Xeon E5-2609 v3 с тактовой частотой 1.90 ГГц и 64 ГБ оперативной памяти и два сетевых адаптера для подключения к разным сетям.\\ | ||
| + | |||
| + | Также предусмотрен адаптер Fiber Channel для связи с дисковыми полками и ленточным хранилищем.\\ | ||
| + | |||
| + | У меня весь процесс начинается с перенастройки Qlogic, что бы нужные WWPN смотрели в нужные устройства. Подробностей по настройке Qlogic давать не буду т.к. это тема для отдельной статьи с подробными разъяснениями.\\ | ||
| ===== Приступаем к установке ===== | ===== Приступаем к установке ===== | ||
| Строка 77: | Строка 83: | ||
| < | < | ||
| - | < | + | < |
| === Далее ставим дополнительно компоненты для работы с лентами === | === Далее ставим дополнительно компоненты для работы с лентами === | ||
| < | < | ||
| + | Проверить в наличие ленточных устройств можно несколькими командами | ||
| + | < | ||
| + | < | ||
| + | В моем случае это Quantum с двумя драйвами и авточейнджером | ||
| + | === Создаем файл хранения. === | ||
| + | < | ||
| + | С вот таким содержимым | ||
| + | < | ||
| + | |||
| + | Name = Tape | ||
| + | |||
| + | Address = bacularestore | ||
| + | |||
| + | Password = " | ||
| + | |||
| + | Device = autochanger-0 | ||
| + | |||
| + | Media Type = LTO | ||
| + | |||
| + | Auto Changer = yes | ||
| + | |||
| + | }</ | ||
| + | **Где:** | ||
| + | |||
| + | * Name – Имя любое, но лучше использовать Tape что бы было понятно что это ленточное хранилище | ||
| + | * Address – имя вашего сервера, | ||
| + | * Password – очень сложный пароль для связи устройства с директором. Пароль должен совпадать с паролем из файла / | ||
| + | * Device – Название вашего файла с настройками авточейнджера (робота, | ||
| + | * Media Type – Указывается LTO что бы система понимала что это ленты | ||
| + | * Auto Changer – указываем использовать ваш авточейнджер или нет. | ||
| + | === Создаем файл авточейнджера === | ||
| + | < | ||
| + | С вот таким содержимым | ||
| + | < | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Changer Device = / | ||
| + | |||
| + | Device = ULTRIUM-HH6-0 | ||
| + | |||
| + | Device = ULTRIUM-HH6-1 | ||
| + | |||
| + | Changer Command = "/ | ||
| + | |||
| + | }</ | ||
| + | **Где:** | ||
| + | |||
| + | * Name – должен совпадать со строкой Device из файла / | ||
| + | * Changer Device – Путь к вашему авточейнджеру, | ||
| + | * Device – это названия ваших драйвов, | ||
| + | * Changer Comand – путь к скрипту, | ||
| + | === Теперь создаем файл устройства === | ||
| + | < | ||
| + | С вот таким содержимым | ||
| + | < | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Media Type = " | ||
| + | |||
| + | ArchiveDevice = / | ||
| + | |||
| + | LabelMedia = yes | ||
| + | |||
| + | Autochanger = yes | ||
| + | |||
| + | AlwaysOpen = yes | ||
| + | |||
| + | AutomaticMount = yes | ||
| + | |||
| + | RemovableMedia = yes | ||
| + | |||
| + | DeviceType = " | ||
| + | |||
| + | } | ||
| + | |||
| + | Device { | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Media Type = " | ||
| + | |||
| + | ArchiveDevice = / | ||
| + | |||
| + | LabelMedia = yes | ||
| + | |||
| + | Autochanger = yes | ||
| + | |||
| + | AlwaysOpen = yes | ||
| + | |||
| + | AutomaticMount = yes | ||
| + | |||
| + | RemovableMedia = yes | ||
| + | |||
| + | DeviceType = " | ||
| + | |||
| + | }</ | ||
| + | **Где:** | ||
| + | |||
| + | * Name – имя устройства, | ||
| + | * ArchiveDevice – Путь к вашему драйву, | ||
| + | После этих настроек у вас уже будет отображаться ленточное хранилище и управление им как через веб интерфейс | ||
| + | |||
| + | {{: | ||
| + | |||
| + | так и через bconsole командой | ||
| + | < | ||
| + | Теперь в bconsole командой | ||
| + | < | ||
| + | Мы можем видеть сколько у нас слотов в ленточном хранилище и какие заняты и свободны | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== Теперь нужно настроить задания для того что бы на ленту попадали файлы. ==== | ||
| + | Для этого начнем с создания файла в котором будет информация откуда забирать данные для копирования их на ленту | ||
| + | < | ||
| + | Содержимое файла | ||
| + | < | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Include { | ||
| + | |||
| + | Options { | ||
| + | |||
| + | Compression=GZIP | ||
| + | |||
| + | } | ||
| + | |||
| + | # File = "/ | ||
| + | |||
| + | } | ||
| + | |||
| + | }</ | ||
| + | Как видно тут указан способ сжатия и путь откуда берем данные (У меня он закомментирован т.к. был тестовый вариант и пока не использую его), ничего сложного | ||
| + | === Теперь нужно создать пул для ленты === | ||
| + | Для этого создаем файл | ||
| + | < | ||
| + | Содержимое файла | ||
| + | < | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Pool Type = Archive | ||
| + | |||
| + | Storage = Tape | ||
| + | |||
| + | LabelFormat = "< | ||
| + | |||
| + | Maximum Volumes = 500 | ||
| + | |||
| + | # VolumeRetention = 365 days | ||
| + | |||
| + | AutoPrune = no | ||
| + | |||
| + | } | ||
| + | |||
| + | Pool { | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Pool Type = Archive | ||
| + | |||
| + | Storage = Tape | ||
| + | |||
| + | LabelFormat = "< | ||
| + | |||
| + | Maximum Volumes = 500 | ||
| + | |||
| + | # VolumeRetention = 365 days | ||
| + | |||
| + | AutoPrune = no | ||
| + | |||
| + | }</ | ||
| + | **Где:** | ||
| + | * Name – любое имя удобное для вашего восприятия | ||
| + | * Storage – имя ранее созданного файла / | ||
| + | * LabelFormat – У меня указан баркод это значит что будут считываться штрихкоды с кассет, | ||
| + | === Теперь создаем файл отвечающий за само задание === | ||
| + | < | ||
| + | Содержимое файла | ||
| + | < | ||
| + | |||
| + | Name = " | ||
| + | |||
| + | Type = Backup | ||
| + | |||
| + | FileSet=" | ||
| + | |||
| + | Schedule=" | ||
| + | |||
| + | Storage=" | ||
| + | |||
| + | Pool=" | ||
| + | |||
| + | Messages = Standard | ||
| + | |||
| + | Priority=10 | ||
| + | |||
| + | Client = " | ||
| + | |||
| + | Write Bootstrap = "/ | ||
| + | |||
| + | Backup Format = " | ||
| + | |||
| + | }</ | ||
| + | **Где:** | ||
| + | * Name – любое имя, которое вам будет удобно | ||
| + | * FileSet – имя ранее созданного файла / | ||
| + | * Storage – имя ранее созданного файла / | ||
| + | * Pool – имя из файла / | ||
| + | * Client – имя вашего клиента взятое из каталога / | ||
| + | После всех манипуляций нужно перезагрузить сервисы и проверить их статус работы | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | ==== Дополнения по улучшению (на ваше усмотрение) ==== | ||
| + | Создаем пароль для пользователя, | ||
| + | Заходим в базу | ||
| + | < | ||
| + | Меняем пароль для пользователя bareos т.к. по умолчанию он без пароля | ||
| + | < | ||
| + | Выходим из базы | ||
| + | < | ||
| + | Теперь заносим этот пароль в файл | ||
| + | < | ||
| + | Еще необходимо изменить тип аутентификации в файле | ||
| + | < | ||
| + | Вносим изменения таким образом. Тут выставлен md5 вместо ident и peer | ||
| + | < | ||
| + | host all all 127.0.0.1/ | ||
| + | host all all ::1/128 md5</ | ||
| + | И перезагружаем сервисы bareos и postgresql, после этого обязательно проверяем статус что бы все было в порядке | ||
| + | < | ||
| + | < | ||
| + | ===== Установка клиентов и настройка клиентов на сервере ===== | ||
| + | Установка клиентов — процесс несложный, | ||
| + | - Первый скрипт запускаете на сервере, | ||
| + | - Второй скрипт запускаете на самом клиенте. | ||
| + | Клиентский скрипт сделан таким образом, | ||
| + | |||
| + | ==== Содержимое серверного скрипта ==== | ||
| + | < | ||
| + | # Запрос имени клиента, | ||
| + | read -p " | ||
| + | read -p " | ||
| + | read -p " | ||
| + | read -s -p " | ||
| + | echo | ||
| + | # Формирование имени без суффикса " | ||
| + | client_base_name=" | ||
| + | # Отдельные переменные для пулов и storage | ||
| + | storage_name=" | ||
| + | device_name=" | ||
| + | pool_name=" | ||
| + | full_pool_name=" | ||
| + | differential_pool_name=" | ||
| + | # Создание клиента в конфигурационном файле | ||
| + | client_config_file="/ | ||
| + | cat <<EOL > " | ||
| + | Client { | ||
| + | Name = " | ||
| + | Address = " | ||
| + | Password = " | ||
| + | } | ||
| + | EOL | ||
| + | # Проверка успешности создания файла клиента | ||
| + | if [ $? -ne 0 ]; then | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | echo " | ||
| + | # Создание файла <Имя клиента> | ||
| + | jobdefs_file="/ | ||
| + | cat <<EOL > " | ||
| + | JobDefs { | ||
| + | Name = " | ||
| + | Type = Backup | ||
| + | Level = Incremental | ||
| + | Client = " | ||
| + | FileSet = " | ||
| + | Schedule = " | ||
| + | Storage = ${storage_name} | ||
| + | Messages = Standard | ||
| + | Pool = ${pool_name} | ||
| + | Priority = 10 | ||
| + | Write Bootstrap = "/ | ||
| + | Full Backup Pool = $full_pool_name # write Full Backups into " | ||
| + | Differential Backup Pool = $differential_pool_name # write Diff Backups into " | ||
| + | Incremental Backup Pool = $pool_name # write Incr Backups into " | ||
| + | Backup Format = " | ||
| + | } | ||
| + | EOL | ||
| + | # Создание файла backup-< | ||
| + | backup_file="/ | ||
| + | cat <<EOL > " | ||
| + | Job { | ||
| + | Name = " | ||
| + | JobDefs = " | ||
| + | Client = " | ||
| + | } | ||
| + | EOL | ||
| + | # Создание пулов в каталоге / | ||
| + | pool_files=(" | ||
| + | for pool in " | ||
| + | pool_file="/ | ||
| + | if [[ $pool == I_* ]]; then | ||
| + | pool_type=" | ||
| + | label_format=" | ||
| + | retention=" | ||
| + | volume_bytes=" | ||
| + | elif [[ $pool == D_* ]]; then | ||
| + | pool_type=" | ||
| + | label_format=" | ||
| + | retention=" | ||
| + | volume_bytes=" | ||
| + | elif [[ $pool == F_* ]]; then | ||
| + | pool_type=" | ||
| + | label_format=" | ||
| + | retention=" | ||
| + | volume_bytes=" | ||
| + | fi | ||
| + | cat <<EOL > " | ||
| + | Pool { | ||
| + | Name = " | ||
| + | Pool Type = Backup | ||
| + | Recycle = yes # Bareos может автоматически перерабатывать тома | ||
| + | AutoPrune = yes # Удалять тома с истекшим сроком действия | ||
| + | Volume Retention = $retention # Как долго следует хранить резервные копии ${pool_type} ? | ||
| + | Maximum Volume Bytes = $volume_bytes # Ограничить размер тома до разумного уровня | ||
| + | Maximum Volumes = 100 # Ограничить количество томов в пуле | ||
| + | Label Format = " | ||
| + | } | ||
| + | EOL | ||
| + | done | ||
| + | # Создание Storage в каталоге / | ||
| + | storage_file="/ | ||
| + | cat <<EOL > " | ||
| + | Storage { | ||
| + | Name = " | ||
| + | Address = " | ||
| + | Password = " | ||
| + | Device = " | ||
| + | Media Type = " | ||
| + | } | ||
| + | EOL | ||
| + | # Создание Device в каталоге / | ||
| + | device_file="/ | ||
| + | archive_device="/ | ||
| + | # Проверка существования директории | ||
| + | if [ ! -d " | ||
| + | echo " | ||
| + | sudo mkdir -p " | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | cat <<EOL > " | ||
| + | Device { | ||
| + | Name = " | ||
| + | Media Type = " | ||
| + | Archive Device = " | ||
| + | LabelMedia = yes; # позволяет Bareos помечать немаркированные носители | ||
| + | Random Access = yes; | ||
| + | AutomaticMount = yes; # когда устройство будет открыто, | ||
| + | RemovableMedia = no; | ||
| + | AlwaysOpen = no; | ||
| + | Description = " | ||
| + | } | ||
| + | EOL | ||
| + | # Проверка успешности создания файлов storage и device | ||
| + | if [ $? -ne 0 ]; then | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | echo " | ||
| + | # Изменение владельца файлов | ||
| + | # Каталог, | ||
| + | target_dir="/ | ||
| + | # Проверка существования каталога | ||
| + | if [ ! -d " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | # Поиск и изменение владельца, | ||
| + | for file in " | ||
| + | if [ -e " | ||
| + | # Получаем текущих владельца и группу | ||
| + | owner=$(stat -c ' | ||
| + | group=$(stat -c ' | ||
| + | # Проверка, | ||
| + | if [ " | ||
| + | echo " | ||
| + | sudo chown bareos: | ||
| + | sudo chmod 750 " | ||
| + | fi | ||
| + | fi | ||
| + | done | ||
| + | echo " | ||
| + | # Автомонтирование папок | ||
| + | # Формирование строки для fstab | ||
| + | remote_path="// | ||
| + | local_path="/ | ||
| + | options=" | ||
| + | # Обработка пробелов только в первой части | ||
| + | remote_path_escaped=$(echo " | ||
| + | # Формирование окончательной строки для fstab | ||
| + | mount_entry=" | ||
| + | # Проверка, | ||
| + | if grep -q -F " | ||
| + | echo " | ||
| + | else | ||
| + | # Добавление строки в /etc/fstab | ||
| + | echo " | ||
| + | # Проверка успешности добавления | ||
| + | if [ $? -eq 0 ]; then | ||
| + | echo " | ||
| + | # Перезапуск fstab и монтирование всех файловых систем | ||
| + | echo " | ||
| + | sudo mount -a | ||
| + | # Проверка успешности монтирования | ||
| + | if [ $? -eq 0 ]; then | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | fi | ||
| + | # Вывод информации о завершении | ||
| + | echo " | ||
| + | echo " | ||
| + | echo " | ||
| + | echo " | ||
| + | echo " | ||
| + | echo " | ||
| + | for pool in " | ||
| + | echo " - / | ||
| + | done | ||
| + | echo " | ||
| + | echo " | ||
| + | # Сервисы для перезагрузки | ||
| + | services=(" | ||
| + | # Перезагрузка сервисов | ||
| + | for service in " | ||
| + | echo " | ||
| + | sudo systemctl restart " | ||
| + | # Проверка успешности перезагрузки | ||
| + | if [ $? -eq 0 ]; then | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | done | ||
| + | echo "" | ||
| + | # Вывод статусов сервисов | ||
| + | for service in " | ||
| + | echo " | ||
| + | sudo systemctl status " | ||
| + | echo "" | ||
| + | done | ||
| + | # Конец скрипта</ | ||
| + | ==== Содержимое клиентского скрипта ==== | ||
| + | < | ||
| + | # Определяем переменную DIST в зависимости от дистрибутива | ||
| + | if grep -q -i " | ||
| + | DIST=" | ||
| + | elif grep -q -i " | ||
| + | DIST=" | ||
| + | else | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | # Скачиваем настройки для репозитория | ||
| + | if [[ $DIST == xUbuntu* ]]; then | ||
| + | wget https:// | ||
| + | # Устанавливаем пакет для шифрования и Дешифровки цифровых подписей | ||
| + | apt install -y gnupg2 | ||
| + | # Устанавливаем ключ подписи пакетов | ||
| + | wget -q https:// | ||
| + | # Обновляем список пакетов | ||
| + | apt update | ||
| + | # Устанавливаем пакет для bareos-fd | ||
| + | apt install -y bareos-filedaemon | ||
| + | # Разрешаем автозапуск сервиса | ||
| + | systemctl enable bareos-filedaemon | ||
| + | # Настраиваем брандмауэр | ||
| + | iptables -I INPUT -p tcp --dport 9102 -j ACCEPT | ||
| + | apt-get install -y iptables-persistent | ||
| + | netfilter-persistent save | ||
| + | elif [[ $DIST == EL* ]]; then | ||
| + | wget https:// | ||
| + | # Устанавливаем пакет для bareos-fd | ||
| + | yum install -y bareos-fd | ||
| + | # Разрешаем автозапуск сервиса и стартуем его | ||
| + | systemctl enable bareos-fd --now | ||
| + | # Настраиваем брандмауэр | ||
| + | firewall-cmd --permanent --add-port=9102/ | ||
| + | firewall-cmd --reload | ||
| + | else | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | # Проверяем доступность сервера | ||
| + | ping -c 3 ВАШ СЕРВЕР ГДЕ УСТАНОВЛЕН ДИРЕКТОР | ||
| + | if [ $? -ne 0 ]; then | ||
| + | echo " | ||
| + | ping -c 3 ВАШ СЕРВЕР ГДЕ УСТАНОВЛЕН ДИРЕКТОР | ||
| + | if [ $? -ne 0 ]; then | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | fi | ||
| + | # Настройка файла / | ||
| + | cat <<EOL > / | ||
| + | Director { | ||
| + | Name = bareos-dir | ||
| + | Password = " | ||
| + | Description = "Allow the configured Director to access this file daemon." | ||
| + | } | ||
| + | EOL | ||
| + | # Перезапускаем bareos-fd и выводим его статус | ||
| + | systemctl restart bareos-fd | ||
| + | systemctl status bareos-fd --no-pager | ||
| + | echo " | ||
| + | echo " | ||
| + | |||
| + | Таким образом, | ||
| + | |||
| + | Мы завершили это увлекательное путешествие в мир резервного копирования, | ||
| + | |||
| + | Я надеюсь, | ||
| + | |||
| + | Удачи вам в ваших проектах и до новых встреч! | ||
| + | |||
| + | |||