Application: "Bacula Dir/SD/FD 2.4/5.2/7.4" и "MySQL/PostgreSQL".
Инсталлируем утилиты, полезные в дальнейшей работе:
# aptitude install sudo nfs-client ifenslave net-tools htop iotop bmon mc
Устанавливаем компоненты "Bacula" и выбранную СУБД, на примере "MySQL":
# aptitude install bacula-director bacula-director-mysql bacula-sd bacula-fd bacula-client mysql-server
В случае использования в качестве СУБД "PostgreSQL", набор компонентов иной:
# aptitude install bacula-director bacula-director-pgsql bacula-sd bacula-fd bacula-client postgresql
В процессе инсталляции сервера "Bacula" будет предложено конфигурировать подключение к СУБД. Я обычно отказываюсь от таких предложений, рассчитывая впоследствии вручную произвести все необходимые настройки.
Вывод инсталлятора, свидетельствующий о более или менее успешном завершении его работы:
....
Starting Bacula Director: bacula-dir.
....
Starting Bacula Storage daemon: bacula-sd.
....
Starting MySQL database server: mysqld.
....
Starting Bacula Director: bacula-dir.
....
Starting Bacula Storage daemon: bacula-sd.
....
Starting MySQL database server: mysqld.
....
Установка и предварительная настройка СУБД "MySQL".
Прежде всего убедимся в том, что сервер "MySQL" успешно запущен и слушает назначенный ему порт:
# netstat -apn | grep mysql
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1768/mysqld
Для работы "Bacula Director" необходимо наличие сконфигурированной СУБД, в которой будут хранится метаданных. В том случае, если мы выбрали себе "MySQL" - используем соответствущим образом именованный Bash-скрипт "/usr/share/bacula-director/make_mysql_tables" создания "схемы" СУБД, подготовленный разработчиками. Перед использованием чуть дополняем и корректируем скрипт для полностью автоматизированной работы считая, что база чиста:
# vi /usr/share/bacula-director/make_mysql_tables
....
db_name="bacula"
db_user="bacula"
db_password="<userPassword>"
....
if $bindir/mysql $* -f <<END-OF-DATA
....
CREATE DATABASE IF NOT EXISTS ${db_name};
GRANT alter, create, create temporary tables, delete, drop, index, insert, lock tables, select, update ON ${db_name}.* TO '${db_user}'@'localhost' IDENTIFIED BY '${db_password}';
....
USE ${db_name};
....
db_name="bacula"
db_user="bacula"
db_password="<userPassword>"
....
if $bindir/mysql $* -f <<END-OF-DATA
....
CREATE DATABASE IF NOT EXISTS ${db_name};
GRANT alter, create, create temporary tables, delete, drop, index, insert, lock tables, select, update ON ${db_name}.* TO '${db_user}'@'localhost' IDENTIFIED BY '${db_password}';
....
USE ${db_name};
....
Исполняем скрипт создания "схемы" с указанием реквизитов суперпользователя СУБД, от имени которого будут произведены работы:
# /usr/share/bacula-director/make_mysql_tables -h localhost -u root -p
После того, как скрипт отработал, можно проверить, всё ли прошло гладко:
# mysql -h localhost -u bacula -p
#mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bacula |
+--------------------+
2 rows in set (0.00 sec)
| Database |
+--------------------+
| information_schema |
| bacula |
+--------------------+
2 rows in set (0.00 sec)
# mysql> use bacula;
# mysql> show tables;
# mysql> show tables;
+------------------+
| Tables_in_bacula |
+------------------+
| BaseFiles |
| CDImages |
| Client |
...
+------------------+
24 rows in set (0.00 sec)
| Tables_in_bacula |
+------------------+
| BaseFiles |
| CDImages |
| Client |
...
+------------------+
24 rows in set (0.00 sec)
Установка и предварительная настройка СУБД "PostgreSQL".
Из соображений унификации методов доступа и повышения пассивной безопасности для обращений через локальный файловый сокет и "сетевую петлю" потребуем аутентификации паролем, используемым внутри СУБД - это позволяет не смешивать локальных системных пользователей и пользователей СУБД:
# vi /etc/postgresql/9.5/main/pg_hba.conf
....
# TYPE DATABASE USER ADDRESS METHOD
....
# Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
....
# TYPE DATABASE USER ADDRESS METHOD
....
# Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
....
Для применения изменений потребуется перезапуск сервиса:
# /etc/init.d/postgresql restart
Убедимся в том, что "PostgreSQL" успешно запущен и слушает назначенный ему порт:
# netstat -apn | grep postgres
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 704/postgres
Подготовим "базу данных" для "Bacula" (применительно к "MySQL" всё дальнейшее делается одним скриптом, но у "PostgreSQL" всё несколько сложнее):
# su - postgres
postgres@bacula:~$ psql
postgres@bacula:~$ psql
postgres=# DROP DATABASE IF EXISTS bacula;
postgres=#
postgres=# CREATE USER bacula WITH PASSWORD '<userPassword>';
postgres=#
postgres=# CREATE DATABASE bacula WITH OWNER = 'bacula' ENCODING = 'SQL_ASCII' LC_COLLATE = 'C' LC_CTYPE = 'C' TEMPLATE = 'template0';
postgres=#
postgres=# GRANT ALL PRIVILEGES ON DATABASE bacula TO bacula;
postgres=# \q
postgres=#
postgres=# CREATE USER bacula WITH PASSWORD '<userPassword>';
postgres=#
postgres=# CREATE DATABASE bacula WITH OWNER = 'bacula' ENCODING = 'SQL_ASCII' LC_COLLATE = 'C' LC_CTYPE = 'C' TEMPLATE = 'template0';
postgres=#
postgres=# GRANT ALL PRIVILEGES ON DATABASE bacula TO bacula;
postgres=# \q
Обращаю внимание на то, что выше мы создаём "базу данных" в кодировке "SQL_ASCII", а не современной "UTF-8", для обеспечения обратной совместимости "Bacula" с именованиями в устройствах вроде ленточных накопителей, которые с древних времён размечаются в "исконно американской" символике. Если кодировка БД всё-таки была задана неверно, то желательно исправить это.
Поскольку мы выбрали для "Bacula" в качестве СУБД "PostgreSQL" - используем соответствующий Bash-скрипт "/usr/share/bacula-director/make_postgresql_tables" создания "схемы" СУБД, подготовленный разработчиками (считая, что имя БД "bacula"):
# su - postgres
postgres@bacula:~$ /usr/share/bacula-director/make_postgresql_tables
postgres@bacula:~$ /usr/share/bacula-director/make_postgresql_tables
....
CREATE TABLE
CREATE INDEX
INSERT 0 1
Creation of Bacula PostgreSQL tables succeeded.
CREATE TABLE
CREATE INDEX
INSERT 0 1
Creation of Bacula PostgreSQL tables succeeded.
После создания набора таблиц "базы данных" необходимо ещё указать, какой пользователь будет ими распоряжаться. Избегая недоразумений чуть корректируем устанавливающий разрешения доступа скрипт, явно указывая БД и её владельца, деактивируя при этом процедуру создания соответствующего пользователя:
# vi /usr/share/bacula-director/grant_postgresql_privileges
....
db_name=bacula
db_user=bacula
psql -f - -d ${db_name} $* <<END-OF-DATA
# create user ${db_user} ${pass};
....
db_name=bacula
db_user=bacula
psql -f - -d ${db_name} $* <<END-OF-DATA
# create user ${db_user} ${pass};
....
Запускаем скрипт, пробегающий по табличным ресурсам "базы данных" и устанавливающий для них параметры доступа:
postgres@bacula:~$ /usr/share/bacula-director/grant_postgresql_privileges
ALTER DATABASE
....
GRANT
GRANT
Privileges for user bacula granted on database bacula.
....
GRANT
GRANT
Privileges for user bacula granted on database bacula.
После того, как скрипт отработал, можно проверить, всё ли прошло гладко:
$ psql -h localhost -U bacula -W bacula
bacula=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------+----------+-----------+-------------+-------------+-------------------
bacula | bacula | SQL_ASCII | C | C | =Tc/bacula +
| | | | | bacula=CTc/bacula
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
....
bacula=> \dt
public | basefiles | table | postgres
public | cdimages | table | postgres
public | client | table | postgres
....
bacula=> \q
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------+----------+-----------+-------------+-------------+-------------------
bacula | bacula | SQL_ASCII | C | C | =Tc/bacula +
| | | | | bacula=CTc/bacula
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
....
bacula=> \dt
public | basefiles | table | postgres
public | cdimages | table | postgres
public | client | table | postgres
....
bacula=> \q
Подготовка файловой структуры для конфигураций и данных.
Заранее заготовим директории для расширенных и клиентских конфигураций:
# mkdir -p /etc/bacula/.draft
# mkdir -p /etc/bacula/client.d
# mkdir -p /etc/bacula/includes
# mkdir -p /etc/bacula/scripts
# chown -R bacula:bacula /etc/bacula
# chmod -R o-rwx /etc/bacula
# mkdir -p /etc/bacula/client.d
# mkdir -p /etc/bacula/includes
# mkdir -p /etc/bacula/scripts
# chown -R bacula:bacula /etc/bacula
# chmod -R o-rwx /etc/bacula
Заводим директории для хранения файлов состояния резервных копий на случай отказа "Каталога":
# mkdir -p /var/lib/bacula/bsr
# chown -R bacula:bacula /var/lib/bacula/bsr
# chmod -R u+rw /var/lib/bacula/bsr
# chmod -R go-rwx /var/lib/bacula/bsr
# chown -R bacula:bacula /var/lib/bacula/bsr
# chmod -R u+rw /var/lib/bacula/bsr
# chmod -R go-rwx /var/lib/bacula/bsr
Заведём набор директорий в файловых хранилищах "Bacula", где каждая из поддиректорий с именем вида "devX" будет рассматриваться в дальнейшем как условное "устройство хранения", для которой в один момент времения доступна лишь одна задача записи (это упрощает процедуры приоритезации и формирования очередей заданий):
# mkdir -p /mnt/storage0/bacula
# mkdir -p /mnt/storage0/bacula/dev0
# mkdir -p /mnt/storage0/bacula/dev1
# mkdir -p /mnt/storage0/bacula/dev2
# mkdir -p /mnt/storage1/bacula
# mkdir -p /mnt/storage1/bacula/dev10
# mkdir -p /mnt/storage1/bacula/dev11
# mkdir -p /mnt/storage1/bacula/dev12
# mkdir -p /mnt/nfs_storage0/bacula
# mkdir -p /mnt/nfs_storage0/bacula/dev20
# mkdir -p /mnt/nfs_storage0/bacula/dev21
# mkdir -p /mnt/nfs_storage0/bacula/dev22
# mkdir -p /mnt/fc_storage0/bacula
# mkdir -p /mnt/fc_storage0/bacula/dev30
# mkdir -p /mnt/fc_storage0/bacula/dev31
# mkdir -p /mnt/fc_storage0/bacula/dev32
# chown -R bacula:bacula /mnt/*/bacula
# chmod -R ug+rw /mnt/*/bacula
# chmod -R o-rwx /mnt/*/bacula
# mkdir -p /mnt/storage0/bacula/dev0
# mkdir -p /mnt/storage0/bacula/dev1
# mkdir -p /mnt/storage0/bacula/dev2
# mkdir -p /mnt/storage1/bacula
# mkdir -p /mnt/storage1/bacula/dev10
# mkdir -p /mnt/storage1/bacula/dev11
# mkdir -p /mnt/storage1/bacula/dev12
# mkdir -p /mnt/nfs_storage0/bacula
# mkdir -p /mnt/nfs_storage0/bacula/dev20
# mkdir -p /mnt/nfs_storage0/bacula/dev21
# mkdir -p /mnt/nfs_storage0/bacula/dev22
# mkdir -p /mnt/fc_storage0/bacula
# mkdir -p /mnt/fc_storage0/bacula/dev30
# mkdir -p /mnt/fc_storage0/bacula/dev31
# mkdir -p /mnt/fc_storage0/bacula/dev32
# chown -R bacula:bacula /mnt/*/bacula
# chmod -R ug+rw /mnt/*/bacula
# chmod -R o-rwx /mnt/*/bacula
Если файловое хранилище расположено на NFS-томе, не забываем указать опцию монтирования "_netdev", предписывающую задействовать "том" только после полной активации сетевой подсистемы сервера:
# vi /etc/fstab
....
1.2.3.4:/backup_bacula.local/ /mnt/nfs_storage0 nfs _netdev,rw 0 0
1.2.3.4:/backup_bacula.local/ /mnt/nfs_storage0 nfs _netdev,rw 0 0
В том случае, если файловое хранилище расположено на файловой системе, подключаемой в контексте FUSE, вносим пользователя "bacula" в группу "fuse" и монтируем "том" с опцией "allow_other".
Общие сведения о подходах конфигурирования.
Каждый сервис в составе Bacula имеет собственный файл настройки, на который можно указать при запуске, используя ключ "-c". По умолчанию, в директории конфигураций сервисами ищется файл с соответствующим сервису именем, типа: "bacula-dir.conf", "bacula-sd.conf", "bacula-fd.conf", "console.conf" (а также "bconsole.conf", "bgnome-console.conf", "bwx-console.conf", "bat.conf" и тому подобное).
Образцы конфигурационных файлов можно найти в директориях "/usr/share/bacula-common/defconfig" и "/usr/share/doc/bacula-common/examples", при необходимости там можно подсмотреть решения "по умолчанию".
"Bacula" позволяет использовать в конфигурационных файлах два типа подстановочных переменных (странно, да - вероятно это побочный эффект резкого добавления новой функциональности и необходимости сохранить обратную совместимость): один из них используется только в строках вызова скриптов, а второй может применяться лишь при формировании некоторых внутренних взаимопересекающихся переменных.
Набор переменных для вызова скриптов:
%% = %
%c = Client's name
%d = Director's name
%e = Job Exit Status
%i = JobId
%j = Unique JobId
%l = Job Level
%n = Job Name
%s = since time
%t = Job type
%v = Volume name
%c = Client's name
%d = Director's name
%e = Job Exit Status
%i = JobId
%j = Unique JobId
%l = Job Level
%n = Job Name
%s = since time
%t = Job type
%v = Volume name
Набор переменных для формирования переменных конфигурации:
${Year} - full year
${Month} - current month 1-12
${Day} - day of the month 1-31
${Hour} - hour 0-24
${Minute} - current minute 0-59
${Second} - current second 0-59
${WeekDay} - current day of the week 0-6 with 0 being Sunday
${Job} - job name
${general} - Director's name
${Level} - Job Level
${Type} - Job type
${JobId} - JobId
${JobName} - unique job name composed of Job and date
${Storage} - Storage daemon's name
${Client} - Client's name
${NumVols} - current number of Volumes in the Pool
${Pool} - Pool name
${Catalog} - Catalog name
${MediaType} - Media Type
${Month} - current month 1-12
${Day} - day of the month 1-31
${Hour} - hour 0-24
${Minute} - current minute 0-59
${Second} - current second 0-59
${WeekDay} - current day of the week 0-6 with 0 being Sunday
${Job} - job name
${general} - Director's name
${Level} - Job Level
${Type} - Job type
${JobId} - JobId
${JobName} - unique job name composed of Job and date
${Storage} - Storage daemon's name
${Client} - Client's name
${NumVols} - current number of Volumes in the Pool
${Pool} - Pool name
${Catalog} - Catalog name
${MediaType} - Media Type
Настраиваем "Storage Daemon (Bacula-SD)".
Поработаем с конфигурацией сервиса хранения файлов, так как он запускается первым и до его полной инициализации никакой другой компонент Bacula не будет работать. Почистим его от не применяемых нами типов хранилищ, уточним параметры применяемых:
# vi /etc/bacula/bacula-sd.conf
# # Общее описание сервиса "Storage Daemon":
Storage {
# Произвольное имя блока описания сервиса "Storage Daemon"
Name = "sd0.bacula.local"
# Прослушиваемый службой адрес и порт (полный диапазон для подключения от любого клиента)
SDAddress = 0.0.0.0; SDPort = 9103
WorkingDirectory = "/var/lib/bacula"; PidDirectory = "/var/run/bacula"
# Укажем максимальное количество одновременных обращений к сервису
MaximumConcurrentJobs = 20;
# Указываем период посылки поддерживающих соединение пакетов. Необходимо для борьбы со слишком умными маршрутизаторами, которые закрывают соединение по истечению интервала неактивности
HeartbeatInterval = 30 sec;
}
# # Перечень "Директоров" (Directors), которым разрешено использование описываемого сервиса "Storage Daemon":
Director {
# Имя и пароль для связи "Директора" со "Storage Daemon"
Name = "bacula.local"; Password = "<passwordForStorage>"
}
# # Блок описания подсистемы отправки уведомлений о состоянии сервиса "Storage Daemon":
Messages {
Name = Standard
# Указание посылать все уведомления "Директору"
Director = "bacula.local" = all
}
# # Блок подключений расширенных конфигураций:
@/etc/bacula/includes/bacula-sd-devices.conf
Storage {
# Произвольное имя блока описания сервиса "Storage Daemon"
Name = "sd0.bacula.local"
# Прослушиваемый службой адрес и порт (полный диапазон для подключения от любого клиента)
SDAddress = 0.0.0.0; SDPort = 9103
WorkingDirectory = "/var/lib/bacula"; PidDirectory = "/var/run/bacula"
# Укажем максимальное количество одновременных обращений к сервису
MaximumConcurrentJobs = 20;
# Указываем период посылки поддерживающих соединение пакетов. Необходимо для борьбы со слишком умными маршрутизаторами, которые закрывают соединение по истечению интервала неактивности
HeartbeatInterval = 30 sec;
}
# # Перечень "Директоров" (Directors), которым разрешено использование описываемого сервиса "Storage Daemon":
Director {
# Имя и пароль для связи "Директора" со "Storage Daemon"
Name = "bacula.local"; Password = "<passwordForStorage>"
}
# # Блок описания подсистемы отправки уведомлений о состоянии сервиса "Storage Daemon":
Messages {
Name = Standard
# Указание посылать все уведомления "Директору"
Director = "bacula.local" = all
}
# # Блок подключений расширенных конфигураций:
@/etc/bacula/includes/bacula-sd-devices.conf
"Bacula" поддерживает механизм вставки в конфигурационные файлы содержимого файлов. Опрометчиво было бы этим не воспользоваться в схемах с десятками и сотнями объектов резервирования. Включение содержимого файловых ресурсов элементарно: "@/path/file.name.conf". Воспользуемся этим для вынесения конфигураций клиентов в отдельные файлы.
Директива подключения конфигураций также поддерживает автоматизацию, реализуемую через подстановку ответов от запускаемых простейших скриптов. Далее мы таким образом будем подключать из соответствующей директории клиентские конфигурации.
Перечень "устройств хранения" есть смысл вынести отдельно, так как в реальной системе резервного копирования их описаний накапливается много, что затрудняет восприятие конфигурации в целом:
# vi /etc/bacula/includes/bacula-sd-devices.conf
# # Перечень используемых сервисом устройств хранения данных (в нашем случае это выделенные каталоги файловой системы):
Device {
# (для подключения к описываемым устройствам "Директору" необходимо указывать "Name" и "MediaType" из непосредственного описания устройства)
# Произвольное уникальное имя устройства
Name = "dev0.sd0.bacula.local"
# Произвольное описание типа устройства (своего рода - дескриптор)
MediaType = FileDev0
# Путь к устройству или точке файловой системы
ArchiveDevice = "/mnt/storage0/bacula/dev0"
# Разрешение для Bacula производить автоматическую разметку неразмеченных устройств
LabelMedia = yes; RandomAccess = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}
....
Device {
# Произвольное уникальное имя устройства
Name = "dev20.sd0.bacula.local"
# Произвольное описание типа устройства (своего рода - дескриптор)
MediaType = FileDev20
# Путь к устройству или точке файловой системы
ArchiveDevice = "/mnt/nfs_storage0/bacula/dev20"
# Разрешение для Bacula производить автоматическую разметку неразмеченных устройств
LabelMedia = yes; RandomAccess = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}
Device {
# (для подключения к описываемым устройствам "Директору" необходимо указывать "Name" и "MediaType" из непосредственного описания устройства)
# Произвольное уникальное имя устройства
Name = "dev0.sd0.bacula.local"
# Произвольное описание типа устройства (своего рода - дескриптор)
MediaType = FileDev0
# Путь к устройству или точке файловой системы
ArchiveDevice = "/mnt/storage0/bacula/dev0"
# Разрешение для Bacula производить автоматическую разметку неразмеченных устройств
LabelMedia = yes; RandomAccess = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}
....
Device {
# Произвольное уникальное имя устройства
Name = "dev20.sd0.bacula.local"
# Произвольное описание типа устройства (своего рода - дескриптор)
MediaType = FileDev20
# Путь к устройству или точке файловой системы
ArchiveDevice = "/mnt/nfs_storage0/bacula/dev20"
# Разрешение для Bacula производить автоматическую разметку неразмеченных устройств
LabelMedia = yes; RandomAccess = Yes; AutomaticMount = yes; RemovableMedia = no; AlwaysOpen = no;
}
Проверим корректность конфигурации средствами самого "Bacula":
# bacula-sd -c /etc/bacula/bacula-sd.conf -t
Перезапустим "Storage Daemon":
# /etc/init.d/bacula-sd restart
Убедимся в том, что "Storage Daemon" успешно запущен и слушает назначенный ему порт:
# netstat -apn | grep bacula-sd
tcp ... 0 0.0.0.0:9103 0.0.0.0:* LISTEN 4027/bacula-sd
Настраиваем "Director Daemon (Bacula-Dir)".
Перейдем к конфигурационному файлу организующего работу системы резервного копирования сервиса "Директора", расположив в ней описание общей (серверной) конфигурации:
# vi /etc/bacula/bacula-dir.conf
# # Общее описание сервиса "Director Daemon":
Director {
# Произвольное уникальное FQDN имя
Name = "bacula.local"
# Прослушиваемый службой адрес и порт (полный диапазон для подключения от любого клиента)
DirAddress = 0.0.0.0; DIRport = 9101
WorkingDirectory = "/var/lib/bacula"; PidDirectory = "/var/run/bacula"
# Пароль для подключения консоли управления
Password = "<passwordForConsole>"
# Количество одновременно исполняемых заданий
MaximumConcurrent Jobs = 10;
FDConnectTimeout = 20 minutes; SDConnectTimeout = 20 minutes
# Указываем период посылки поддерживающих соединение пакетов. Необходимо для борьбы со слишком умными маршрутизаторами, которые закрывают соединение по истечению интервала неактивности (после запуска задачи данные передаются между клиентом и "Storage Daemon" а "Director Daemon" просто ждёт отчёта о результате - так вот, чтобы маршрутизаторы не удаляли информацию о простаивающем соединении из таблицы, например NAT, нужно поддерживать его периодическим посылом heartbeat-пакетов)
HeartbeatInterval = 30 sec
# Указание на блок обработки сообщений исходящих от службы (блок описывается далее)
Messages = Standard
}
# # Описывание конфигурации сервера СУБД используемого для хранения "мета-данных" сервиса "Director Daemon":
Catalog {
Name = "cd0.bacula.local";
DBAddress = localhost;
DBPort = 5432;
DBName = "bacula"; DBUser = "bacula";
DBPassword = "<passwordForCatalogDB>";
}
# # Описание "пула" для служебных нужд (вскользь прочитал о том, что он нужен для поддержки стриммеров):
Pool {
Name = Scratch
PoolType = Backup
}
# # Блок описания подсистемы отправки уведомлений о состоянии сервиса "Director Daemon":
Messages {
Name = Standard
Console = all, !skipped, !saved
Append = "/var/lib/bacula/log" = all, !skipped
# Syslog = all
}
# # Блок подключений расширенных конфигураций:
@/etc/bacula/includes/bacula-dir-storages.conf
@/etc/bacula/includes/bacula-dir-schedules.conf
@/etc/bacula/includes/bacula-dir-defjobs.conf
# # Блок динамических подключений клиентских конфигураций:
@|"sh -c 'for f in /etc/bacula/client.d/*.conf ; do echo @${f} ; done'"
Director {
# Произвольное уникальное FQDN имя
Name = "bacula.local"
# Прослушиваемый службой адрес и порт (полный диапазон для подключения от любого клиента)
DirAddress = 0.0.0.0; DIRport = 9101
WorkingDirectory = "/var/lib/bacula"; PidDirectory = "/var/run/bacula"
# Пароль для подключения консоли управления
Password = "<passwordForConsole>"
# Количество одновременно исполняемых заданий
MaximumConcurrent Jobs = 10;
FDConnectTimeout = 20 minutes; SDConnectTimeout = 20 minutes
# Указываем период посылки поддерживающих соединение пакетов. Необходимо для борьбы со слишком умными маршрутизаторами, которые закрывают соединение по истечению интервала неактивности (после запуска задачи данные передаются между клиентом и "Storage Daemon" а "Director Daemon" просто ждёт отчёта о результате - так вот, чтобы маршрутизаторы не удаляли информацию о простаивающем соединении из таблицы, например NAT, нужно поддерживать его периодическим посылом heartbeat-пакетов)
HeartbeatInterval = 30 sec
# Указание на блок обработки сообщений исходящих от службы (блок описывается далее)
Messages = Standard
}
# # Описывание конфигурации сервера СУБД используемого для хранения "мета-данных" сервиса "Director Daemon":
Catalog {
Name = "cd0.bacula.local";
DBAddress = localhost;
DBPort = 5432;
DBName = "bacula"; DBUser = "bacula";
DBPassword = "<passwordForCatalogDB>";
}
# # Описание "пула" для служебных нужд (вскользь прочитал о том, что он нужен для поддержки стриммеров):
Pool {
Name = Scratch
PoolType = Backup
}
# # Блок описания подсистемы отправки уведомлений о состоянии сервиса "Director Daemon":
Messages {
Name = Standard
Console = all, !skipped, !saved
Append = "/var/lib/bacula/log" = all, !skipped
# Syslog = all
}
# # Блок подключений расширенных конфигураций:
@/etc/bacula/includes/bacula-dir-storages.conf
@/etc/bacula/includes/bacula-dir-schedules.conf
@/etc/bacula/includes/bacula-dir-defjobs.conf
# # Блок динамических подключений клиентских конфигураций:
@|"sh -c 'for f in /etc/bacula/client.d/*.conf ; do echo @${f} ; done'"
Аналогично тому, как мы это сделали для "Bacula-SD", выносим всё множество описаний "устройств хранения" отдельно, чтобы упростить восприятие глобальной конфигурации:
# vi /etc/bacula/includes/bacula-dir-storages.conf
# # Перечень используемых ресурсов хранения данных:
Storage {
# (связь с устройствами "Bacula-SD" через параметры "Name" и "MediaType")
# Произвольное уникальное имя хранилища
Name = "dev0.sd0.bacula.local"
# FQDN адрес сервиса, порт и пароль подключения к файловому хранилищу
Address = "sd0.bacula.local"; SDPort = 9103
Password = "<passwordForStorage>"
# Имя устройства используемого в хранилище
Device = "dev0.sd0.bacula.local"
# Тип устройства используемого в хранилище
MediaType = FileDev0
# Количество одновременно исполняемых заданий
MaximumConcurrentJobs = 10
}
....
Storage {
# Произвольное уникальное имя хранилища
Name = "dev10.sd0.bacula.local"
# FQDN адрес сервиса, порт и пароль подключения к файловому хранилищу
Address = "sd0.bacula.local"; SDPort = 9103
Password = "<passwordForStorage>"
# Имя устройства используемого в хранилище
Device = "dev10.sd0.bacula.local"
# Тип устройства используемого в хранилище
MediaType = FileDev10
# Количество одновременно исполняемых заданий
MaximumConcurrent Jobs = 10
}
Storage {
# (связь с устройствами "Bacula-SD" через параметры "Name" и "MediaType")
# Произвольное уникальное имя хранилища
Name = "dev0.sd0.bacula.local"
# FQDN адрес сервиса, порт и пароль подключения к файловому хранилищу
Address = "sd0.bacula.local"; SDPort = 9103
Password = "<passwordForStorage>"
# Имя устройства используемого в хранилище
Device = "dev0.sd0.bacula.local"
# Тип устройства используемого в хранилище
MediaType = FileDev0
# Количество одновременно исполняемых заданий
MaximumConcurrentJobs = 10
}
....
Storage {
# Произвольное уникальное имя хранилища
Name = "dev10.sd0.bacula.local"
# FQDN адрес сервиса, порт и пароль подключения к файловому хранилищу
Address = "sd0.bacula.local"; SDPort = 9103
Password = "<passwordForStorage>"
# Имя устройства используемого в хранилище
Device = "dev10.sd0.bacula.local"
# Тип устройства используемого в хранилище
MediaType = FileDev10
# Количество одновременно исполняемых заданий
MaximumConcurrent Jobs = 10
}
В работающей на сколь либо серьёзных задачах системах резервного копирования количество блоков расписаний разрастается до явной необходимости выноса их в отдельный файл:
# vi /etc/bacula/includes/bacula-dir-schedules.conf
# # Перечень доступных расписаний запуска задач резервного копирования:
# Ежедневное, с полным резервированием для особо критичных данных:
Schedule {
Name = "DailyFull"
Run = Full mon-sun at 22:05
}
# Ежедневное, с одним полным резервированием во Вторник и шестью ежедневными инкрементальными:
Schedule {
Name = "WeeklyFullDailyInc"
Run = Full tue at 22:05
Run = Incremental wed-mon at 22:05
}
# Еженедельное, с одним полным резервированием в Среду:
Schedule {
Name = "WeeklyFull"
Run = Full wed at 22:05
}
# Еженедельное, с полным резервированием в первую Субботу месяца и еженедельными инкрементальными во Вторник:
Schedule {
Name = "MonthlyFullWeeklyInc"
Run = Full 1st sat at 20:05
Run = Incremental tue at 22:05
}
# Ежемесячное, с одним полным резервированием:
Schedule {
Name = "MonthlyFull"
Run = Full 1st sat at 20:05
}
# Ежемесячное, с одним полным резервированием в первую Субботу Января и ежемесячными инкрементальными в первые Субботы:
Schedule {
Name = "YearlyFullMonthlyInc"
Run = Full jan 1st sat at 20:05
Run = Incremental 1st sat at 22:05
}
# Ежегодное, с одним полным резервированием:
Schedule {
Name = "YearlyFull"
Run = Full jan 1st sat at 20:05
}
# Ежедневное, с полным резервированием для особо критичных данных:
Schedule {
Name = "DailyFull"
Run = Full mon-sun at 22:05
}
# Ежедневное, с одним полным резервированием во Вторник и шестью ежедневными инкрементальными:
Schedule {
Name = "WeeklyFullDailyInc"
Run = Full tue at 22:05
Run = Incremental wed-mon at 22:05
}
# Еженедельное, с одним полным резервированием в Среду:
Schedule {
Name = "WeeklyFull"
Run = Full wed at 22:05
}
# Еженедельное, с полным резервированием в первую Субботу месяца и еженедельными инкрементальными во Вторник:
Schedule {
Name = "MonthlyFullWeeklyInc"
Run = Full 1st sat at 20:05
Run = Incremental tue at 22:05
}
# Ежемесячное, с одним полным резервированием:
Schedule {
Name = "MonthlyFull"
Run = Full 1st sat at 20:05
}
# Ежемесячное, с одним полным резервированием в первую Субботу Января и ежемесячными инкрементальными в первые Субботы:
Schedule {
Name = "YearlyFullMonthlyInc"
Run = Full jan 1st sat at 20:05
Run = Incremental 1st sat at 22:05
}
# Ежегодное, с одним полным резервированием:
Schedule {
Name = "YearlyFull"
Run = Full jan 1st sat at 20:05
}
Описание практически обязательной заготовки задания для восстановления из резервной копии тоже выносим в отдельный файл:
# vi /etc/bacula/includes/bacula-dir-defjobs.conf
# # Описание общего на все задания блока восстановления данных из резервных копий:
Pool {
Name = "pool-restore"
Pool Type = Backup
}
Client {
Name = "client-restore"
Address = "restore.local"; FDPort = 9102; Password = "noPassword"
Catalog = "cd0.bacula.local"
}
FileSet {
Name = "file-set-restore"
Include {
File = "/tmp"
}
}
Job {
Name = "job-restore"
Type = Restore
Client = "client-restore"
FileSet = "file-set-restore"
Storage = "dev0.sd0.bacula.local"
Pool = "pool-restore"
Messages = Standard
Where = "/tmp/bacula-restores"
}
Pool {
Name = "pool-restore"
Pool Type = Backup
}
Client {
Name = "client-restore"
Address = "restore.local"; FDPort = 9102; Password = "noPassword"
Catalog = "cd0.bacula.local"
}
FileSet {
Name = "file-set-restore"
Include {
File = "/tmp"
}
}
Job {
Name = "job-restore"
Type = Restore
Client = "client-restore"
FileSet = "file-set-restore"
Storage = "dev0.sd0.bacula.local"
Pool = "pool-restore"
Messages = Standard
Where = "/tmp/bacula-restores"
}
Проверяем корректность конфигурации средствами самого "Bacula":
# bacula-dir -c /etc/bacula/bacula-dir.conf -t
Типичный вывод сообщения об ошибке, если таковая обнаруживается, что-то вроде этого:
01-Jul 11:11 bacula-dir: ERROR TERMINATION at parse_conf.c:483
Config error: Could not find config Resource MyCatalog referenced on line 151 : Catalog = MyCatalog : line 151, col 22 of file /etc/bacula/bacula-dir.conf
Catalog = MyCatalog
Config error: Could not find config Resource MyCatalog referenced on line 151 : Catalog = MyCatalog : line 151, col 22 of file /etc/bacula/bacula-dir.conf
Catalog = MyCatalog
После настройки и устранения всех обнаруженных ошибок перезапускаем "Director Daemon":
# /etc/init.d/bacula-director restart
Убедимся в том, что сервис успешно запущен и слушает назначенный ему порт:
# netstat -apn | grep bacula-dir
tcp ... 0 0.0.0.0:9101 0.0.0.0:* LISTEN 4045/bacula-dir
В одном из первых примеров расписания в конфигурационном файле выше мы определились с тем, что во Вторник будем делать полное резервирование, а в остальные дни - инкрементальное. Тогда, чтобы восстановить данные по состоянию на Воскресенье, нужно будет использовать полную резервную копию за последний Вторник и, последовательно, наложить на восстановленные данные резервные копии за прошедшие Среду, Четверг, Пятницу и Субботу.
Блок "задания на восстановление" описан таким образом, что при прямом исполнении он не отработает - указанные параметры не соответствуют действительности. В процессе исполнения задания на восстановление необходимо будет подставить все необходимые для запуска задания данные в режиме модификации. "Bacula" требует наличие как минимум одного такого блока в конфигурации и мы это сделали; создавать же для каждого задания резервирования соответствующего блока на восстановление нерационально, так как в действительности, в "хорошем хозяйстве", сервера не теряют данные часто и восстановление таковых не приходится ставить на поток.
Задания резервного копирования.
Описание методик задания параметров заданий резервного копирования в "Bacula" выливается в отдельную инструкцию - читайте её здесь.
Настраиваем CLI-консоль интерактивного управления.
В управлении "Bacula" не обойтись без специализованной CLI-утилиты "bconsole", которую нужно настроить на подключение к "Директору" (здесь в режиме анониманого суперпользователя):
# vi /etc/bacula/bconsole.conf
# # Указываем на сервис "Director Daemon", которым нужно управлять:
Director {
# Имя "Директора", к которому осуществляется подключение
Name = "bacula.local"
# Порт, адрес и пароль подключения
Address = bacula.local; DIRport = 9101
Password = "<passwordForConsole>"
}
Director {
# Имя "Директора", к которому осуществляется подключение
Name = "bacula.local"
# Порт, адрес и пароль подключения
Address = bacula.local; DIRport = 9101
Password = "<passwordForConsole>"
}
Проверяем корректность конфигурации средствами самой утилиты:
# bconsole -c /etc/bacula/bconsole.conf -t
Подключение "Директору" элементарно, осуществляется при запуске CLI-консоли:
# bconsole
Connecting to Director bacula.local:9101
1000 OK: bacula.local
Enter a period to cancel a command.
*
* help
Command Description
======= ===========
add add media to a pool
autodisplay autodisplay [on|off] -- console messages
automount automount [on|off] -- after label
....
*
* status director
bacula.local
Daemon started 01-Jul-10 15:50, 0 Jobs run since started.
Heap: heap=241,664 smbytes=24,011 max_bytes=24,467 bufs=133 max_bufs=140
Scheduled Jobs:
Level Type Pri Scheduled Name Volume
=============================================================================
Incremental Backup 10 01-Jul-10 22:05 job-example.net test
....
*
* quit
1000 OK: bacula.local
Enter a period to cancel a command.
*
* help
Command Description
======= ===========
add add media to a pool
autodisplay autodisplay [on|off] -- console messages
automount automount [on|off] -- after label
....
*
* status director
bacula.local
Daemon started 01-Jul-10 15:50, 0 Jobs run since started.
Heap: heap=241,664 smbytes=24,011 max_bytes=24,467 bufs=133 max_bufs=140
Scheduled Jobs:
Level Type Pri Scheduled Name Volume
=============================================================================
Incremental Backup 10 01-Jul-10 22:05 job-example.net test
....
*
* quit
"Звёздочка" в выводе - символ ожидания ввода в интерпретаторе консоли. Из вывода ясно, что сервер в общем функционирует нормально, есть задание для исполнения и для него создан соответствующий "том".
История команд, отдаваемых в "bconsole" записывается в текстовый файл ".bconsole_history", располагающийся в домашней директории пользователя, от имени которого запускается утилита.
О сохранение конфигурации.
Важно понимать, что "Bacula" руководствуется в работе исключительно параметрами конфигурации сохранёнными в таблицах СУБД, а текстовые файлы директории "/etc/bacula/" используются как однократный источник данных, считываемый при запуске сервиса или команде обновления настроек, которую нужно явно давать после каждого изменения конфигурационных. Удобнее всего это сделать из специализированной CLI утилиты управления:
# bconsole
Connecting to Director bacula.local:9101
*
* reload
* quit
*
* reload
* quit
Настраиваем подсистему ротацию журналов событий.
Заменяем несовременный конфигурационный файл "Logrotate" на свой:
# vi /etc/logrotate.d/bacula-common
/var/log/bacula/*.log {
monthly
rotate 12
compress
delaycompress
missingok
notifempty
copytruncate
su bacula bacula
}
monthly
rotate 12
compress
delaycompress
missingok
notifempty
copytruncate
su bacula bacula
}
Проверяем корректность конфигурации, не воздействуя при этом на файлы журналов:
# logrotate -d /etc/logrotate.d/bacula-common