Bacula 是一款开源的跨平台网络备份工具,提供基于企业级的CS的备份解决方案,可以对数据进行备份、恢复、以及完整性校验。

组件

bacula

  • Director:中央控制程序,管理所有组件
  • Console:管理控制台
  • Storage Daemon:负责文件的实际存储和读取,同时对接存储硬盘或者磁带
  • Catalog:数据库,建立备份文件和存储路径建立索引,支持MySQL、PG和SQLite
  • File Daemon:客户端程序,负责执行文件的备份、还原和文件传输

部署

准备数据库

# 安装
dnf makecache
dnf update -y
dnf install -y mariadb mariadb-server mariadb-server
# 指定客户端和服务端使用utf8来访问mariadb
cat > /etc/my.cnf.d/charset.cnf <<EOF
[mysqld]
character-set-server = utf8mb4

[client]
default-character-set = utf8mb4
EOF

# 拉起服务
systemctl enable --now mariadb.service
systemctl status --no-pager mariadb.service

# 创建Bacula数据库,用户名为gbacula,密码为bacula
mysql -uroot << EOF
CREATE DATABASE bacula CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
GRANT ALL PRIVILEGES ON bacula.* to bacula@'localhost' IDENTIFIED BY 'bacula';
GRANT ALL PRIVILEGES ON bacula.* to bacula@'%' IDENTIFIED BY 'bacula';
FLUSH PRIVILEGES;
exit
EOF

# 访问测试
mysql -ubacula -pbacula -hlocalhost <<EOF
show databases;
exit
EOF

安装软件

# 安装备份软件
dnf -y install bacula-director bacula-storage bacula-console bacula-client

# 将默认的PG数据库修改为MySQL
[root@bacula ~]# alternatives --config libbaccats.so

There are 3 programs which provide 'libbaccats.so'.

Selection Command
-----------------------------------------------
1 /usr/lib64/libbaccats-mysql.so
2 /usr/lib64/libbaccats-sqlite3.so
*+ 3 /usr/lib64/libbaccats-postgresql.so

Enter to keep the current selection[+], or type selection number: 1

# 创建相关数据库表
echo 'bacula' | /usr/libexec/bacula/make_mysql_tables -p

# 创建相关目录
mkdir -p /bacula/backup /bacula/restore
chown -R bacula:bacula /bacula
chmod -R 700 /bacula

# 开启防火墙
firewall-cmd --permanent --add-service=bacula
firewall-cmd --reload

服务端配置

# 修改Director连接各个组件的密码
sed -e "s|@@DIR_PASSWORD@@|bacula-dir|" -e "s|@@FD_PASSWORD@@|bacula-fd|g" -e "s|@@MON_DIR_PASSWORD@@|bacula-mon|g" -e "s|dbpassword = ""|dbpassword = "bacula"|g" -e "s|@@SD_PASSWORD@@|bacula-sd|g" -e "s|Address = localhost |Address = bak.contoso.com |g" -i.bak /etc/bacula/bacula-dir.conf
# 去除注释行
sed '/^#/d' -i /etc/bacula/bacula-dir.conf

# 配置bconsole的密码
sed -e "s|@@DIR_PASSWORD@@|bacula-dir|g" -i.bak /etc/bacula/bconsole.conf

# 配置SD的密码
sed -e "s|@@SD_PASSWORD@@|bacula-sd|g" -e "s|@@MON_SD_PASSWORD@@|bacula-mon|g" -i.bak /etc/bacula/bacula-sd.conf
# 修改备份目录
sed -e "s|/tmp|/bacula/backup|g" -i /etc/bacula/bacula-sd.conf

# 配置FD的密码
sed -e "s|@@FD_PASSWORD@@|bacula-fd|g" -e "s|@@MON_SD_PASSWORD@@|bacula-mon|g" -i.bak /etc/bacula/bacula-fd.conf

# 修改备份作业名称和备份路径
sed -e "s|BackupClient1|BackupLocalFiles|g" -e "s|RestoreFiles|RestoreLocalFiles|g" -e "s|/tmp/bacula-restores|/bacula/restore|g" -i /etc/bacula/bacula-dir.conf

# 设置配置文件集,File选项指向备份目标,exclude指向忽略目标。
# 以下设置表明对系统文件进行全备
FileSet {
Name = "Full Set"
Include {
Options {
signature = MD5
# 增加一个压缩选项
compression = GZIP
}
File = /
}
Exclude {
File = /var/lib/bacula
File = /proc
File = /tmp
File = /.journal
File = /.fsck
File = /dev
File = /usr/share
# 将自定义备份目录排除
File = /bacula
}
}

# 拉起服务
systemctl enable --now bacula-dir
systemctl enable --now bacula-sd
systemctl enable --now bacula-fd

# 验证配置文件
bacula-sd -tc /etc/bacula/bacula-sd.conf

远程客户端配置

# 在infra主机上安装客户端
dnf -y install bacula-client bacula-console
# 开启防火墙
firewall-cmd --permanent --add-service=bacula-client
firewall-cmd --reload

# 配置fd密码
sed -e "s|@@FD_PASSWORD@@|bacula-fd|g" -e "s|@@MON_SD_PASSWORD@@|bacula-mon|g" -i.bak /etc/bacula/bacula-fd.conf
systemctl enable --now bacula-fd

# 配置bconsole的密码
sed -e "s|@@DIR_PASSWORD@@|bacula-dir|g" -e "s|localhost|bak.contoso.com|g"-i.bak /etc/bacula/bconsole.conf

使用

本地备份

# 本地备份
# 通过bconsole控制台登陆Director
root@backup ~]# bconsole
Connecting to Director localhost:9101
1000 OK: 10002 bacula-dir Version: 11.0.1 (05 February 2020)
Enter a period to cancel a command.
# 开始配置备份
*label
Automatically selected Catalog: MyCatalog
Using Catalog "MyCatalog"
# 使用pool定义的存储资源,配置在bacula-sd中
The defined Storage resources are:
1: File1
2: File2
Select Storage resource (1-2): 1
Connecting to Storage daemon File1 at bak.contoso.com:9103 ...
# 配置备份文件的卷名称
Enter new Volume name: Vol-2023103001
# 选择默认的存储池,使用文件保存
Defined Pools:or Enter for none):
1: Default
2: File
3: Scratch
Select the Pool (1-3): 2
Connecting to Storage daemon File1 at bak.contoso.com:9103 ...
# 使用第一个槽位
Sending label command for Volume "Vol-2023103001" Slot 0 ...
3000 OK label. VolBytes=223 VolABytes=0 VolType=1 Volume="Vol-2023103001" Device="FileChgr1-Dev1" (/bacula/backup)
Catalog record for Volume "Vol-2023103001", Slot 0 successfully created.
Requesting to mount FileChgr1 ...
3906 File device ""FileChgr1-Dev1" (/bacula/backup)" is always mounted.
# 执行上述的备份操作
*run
A job name must be specified.
# 选择是执行本地全备,还是只备份数据库,还是恢复本地文件
The defined Job resources are:
1: BackupLocalFiles
2: BackupCatalog
3: RestoreLocalFiles
# 本地文件全备
Select Job resource (1-3): 1
Run Backup job
JobName: BackupLocalFiles
Level: Incremental
Client: bacula-fd
FileSet: Full Set
Pool: File (From Job resource)
Storage: File1 (From Job resource)
When: 2023-10-31 17:10:04
Priority: 10
OK to run? (yes/mod/no): yes
Job queued. JobId=1
You have messages.
# 查询备份作业消息
*message
31-Oct 17:10 bacula-dir JobId 1: No prior or suitable Full backup found in catalog. Doing FULL backup.
31-Oct 17:10 bacula-dir JobId 1: Start Backup JobId 1, Job=BackupLocalFiles.2023-10-31_17.10.12_03
31-Oct 17:10 bacula-dir JobId 1: Using Device "FileChgr1-Dev1" to write.
31-Oct 17:10 bacula-sd JobId 1: Wrote label to prelabeled Volume "Vol-2023103001" on File device "FileChgr1-Dev1" (/bacula/backup)
31-Oct 17:10 bacula-fd JobId 1: /boot is a different filesystem. Will not descend from / into it.
31-Oct 17:10 bacula-fd JobId 1: /dev is a different filesystem. Will not descend from / into it.
31-Oct 17:10 bacula-fd JobId 1: /run is a different filesystem. Will not descend from / into it.
# 查看备份作业情况
*status director
bacula-dir Version: 11.0.1 (05 February 2020) x86_64-redhat-linux-gnu redhat Beta
Daemon started 31-Oct-23 17:08, conf reloaded 31-Oct-2023 17:08:00
Jobs: run=0, running=1 mode=0,0
Crypto: fips=N/A crypto=OpenSSL
Heap: heap=536,576 smbytes=448,787 max_bytes=448,860 bufs=435 max_bufs=436
Res: njobs=3 nclients=1 nstores=2 npools=3 ncats=1 nfsets=3 nscheds=2

Scheduled Jobs:
Level Type Pri Scheduled Job Name Volume
===================================================================================
Incremental Backup 10 31-Oct-23 23:05 BackupLocalFiles Vol-2023103001
Full Backup 11 31-Oct-23 23:10 BackupCatalog Vol-2023103001
====

Running Jobs:
Console connected at 31-Oct-23 17:08
JobId Type Level Files Bytes Name Status
======================================================================
1 Back Full 4,923 178.6 M BackupLocalFiles is running
====
No Terminated Jobs.
====
# 备份作业完成,备份文件大小为896.3M
# 查看备份结果
*message
31-Oct 17:11 bacula-sd JobId 1: Elapsed time=00:01:40, Transfer rate=9.009 M Bytes/second
31-Oct 17:11 bacula-sd JobId 1: Sending spooled attrs to the Director. Despooling 7,368,629 bytes ...
31-Oct 17:11 bacula-dir JobId 1: Bacula bacula-dir 11.0.1 (05Feb20):
Build OS: x86_64-redhat-linux-gnu redhat Beta
JobId: 1
Job: BackupLocalFiles.2023-10-31_17.10.12_03
Backup Level: Full (upgraded from Incremental)
Client: "bacula-fd" 11.0.1 (05Feb20) x86_64-redhat-linux-gnu,redhat,Beta
FileSet: "Full Set" 2023-10-31 17:10:12
Pool: "File" (From Job resource)
Catalog: "MyCatalog" (From Client resource)
Storage: "File1" (From Job resource)
Scheduled time: 31-Oct-2023 17:10:04
Start time: 31-Oct-2023 17:10:14
End time: 31-Oct-2023 17:11:55
Elapsed time: 1 min 41 secs
Priority: 10
FD Files Written: 30,338
SD Files Written: 30,338
FD Bytes Written: 896,381,618 (896.3 MB)
SD Bytes Written: 900,921,943 (900.9 MB)
Rate: 8875.1 KB/s
Software Compression: 47.0% 1.9:1
Comm Line Compression: None
Snapshot/VSS: no
Encryption: no
Accurate: no
Volume name(s): Vol-2023103001
Volume Session Id: 1
Volume Session Time: 1698743281
Last Volume Bytes: 902,557,818 (902.5 MB)
Non-fatal FD errors: 0
SD Errors: 0
FD termination status: OK
SD termination status: OK
Termination: Backup OK

# 查看备份文件
[root@backup ~]# tree /bacula/
/bacula/
├── backup
│   └── Vol-2023103001
└── restore

2 directories, 1 file
[root@backup ~]# du -h /bacula/backup/Vol-2023103001
861M /bacula/backup/Vol-2023103001

# 删除测试文件
[root@backup ~]# ls
anaconda-ks.cfg systemprep.sh
[root@backup ~]# rm anaconda-ks.cfg systemprep.sh
rm: remove regular file 'anaconda-ks.cfg'? y
rm: remove regular file 'systemprep.sh'? y

本地恢复

[root@backup ~]# bconsole 
Connecting to Director localhost:9101
1000 OK: 10002 bacula-dir Version: 11.0.1 (05 February 2020)
Enter a period to cancel a command.
# 执行还原操作
*restore all
Automatically selected Catalog: MyCatalog
Using Catalog "MyCatalog"

First you select one or more JobIds that contain files
to be restored. You will be presented several methods
of specifying the JobIds. Then you will be allowed to
select which files from those JobIds are to be restored.

To select the JobIds, you have the following choices:
1: List last 20 Jobs run
2: List Jobs where a given File is saved
3: Enter list of comma separated JobIds to select
4: Enter SQL list command
5: Select the most recent backup for a client
6: Select backup for a client before a specified time
7: Enter a list of files to restore
8: Enter a list of files to restore before a specified time
9: Find the JobIds of the most recent backup for a client
10: Find the JobIds for a backup for a client before a specified time
11: Enter a list of directories to restore for found JobIds
12: Select full restore to a specified Job date
13: Cancel
# 选择执行已经备份过的文件进行还原
Select item: (1-13): 5
Automatically selected Client: bacula-fd
Automatically selected FileSet: Full Set
+-------+-------+----------+-------------+---------------------+----------------+
| JobId | Level | JobFiles | JobBytes | StartTime | VolumeName |
+-------+-------+----------+-------------+---------------------+----------------+
| 1 | F | 30,338 | 896,381,618 | 2023-10-31 17:10:14 | Vol-2023103001 |
+-------+-------+----------+-------------+---------------------+----------------+
You have selected the following JobId: 1

Building directory tree for JobId(s) 1 ... ++++++++++++++++++++++++++++++++++++++++++++
26,941 files inserted into the tree and marked for extraction.

You are now entering file selection mode where you add (mark) and
remove (unmark) files to be restored. No files are initially added, unless
you used the "all" keyword on the command line.
Enter "done" to leave this mode.
# 因为打了all的参数,默认选择所有已备份文件,以下为备份文件的虚拟目录,因为备份了根分区,所以会显示整个系统目录。
cwd is: /
$ ls
*
*.autorelabel
*afs
*bin
*boot
*dev
*etc/
*home/
*lib
*lib64
*media
*mnt/
*opt
*root/
*run
*sbin
*srv
*usr/
*var/
# 使用umark标记不还原var/目录
$ unmark var/
2,349 files unmarked.
# 使用通配符*来表示取消全部
$ unmark *
30,338 files unmarked.
# 标记还原home/目录
$ mark root/
5 files marked.
# 标记完成之后,使用done来表示执行任务
$ done
Bootstrap records written to /var/spool/bacula/bacula-dir.restore.1.bsr

The Job will require the following (*=>InChanger):
Volume(s) Storage(s) SD Device(s)
===========================================================================

Vol-2023103001 File1 FileChgr1

Volumes marked with "*" are in the Autochanger.


5 files selected to be restored.

Using Catalog "MyCatalog"
Run Restore job
JobName: RestoreLocalFiles
Bootstrap: /var/spool/bacula/bacula-dir.restore.1.bsr
Where: /bacula/restore
Replace: Always
FileSet: Full Set
Backup Client: bacula-fd
Restore Client: bacula-fd
Storage: File1
When: 2023-10-31 17:23:18
Catalog: MyCatalog
Priority: 10
Plugin Options: *None*
OK to run? (yes/mod/no): yes
Job queued. JobId=2
# 查看任务执行情况
*status director

Terminated Jobs:
JobId Level Files Bytes Status Finished Name
====================================================================
1 Full 30,338 896.3 M OK 31-Oct-23 17:11 BackupLocalFiles
2 Restore 5 651 OK 31-Oct-23 17:23 RestoreLocalFiles

====
# 退出
*exit
# 恢复的文件存储在/bacula/restore目录下
[root@backup ~]# tree /bacula/
/bacula/
├── backup
│   └── Vol-2023103001
└── restore
└── root
├── anaconda-ks.cfg
└── systemprep.sh

3 directories, 3 files

远程备份

[root@infra ~]# bconsole 
# 连接到远程备份服务器 bak.contoso.com
Connecting to Director bak.contoso.com:9101
1000 OK: 10002 bacula-dir Version: 11.0.1 (05 February 2020)
Enter a period to cancel a command.
*label
Automatically selected Catalog: MyCatalog
Using Catalog "MyCatalog"
The defined Storage resources are:
1: File1
2: File2
Select Storage resource (1-2): 2
Connecting to Storage daemon File2 at bak.contoso.com:9103 ...
Enter new Volume name: Vol-remote-2023103002
Defined Pools:or Enter for none):
1: Default
2: File
3: Scratch
Select the Pool (1-3): 2
Connecting to Storage daemon File2 at bak.contoso.com:9103 ...
Sending label command for Volume "Vol-remote-2023103002" Slot 0 ...
3000 OK label. VolBytes=230 VolABytes=0 VolType=1 Volume="Vol-remote-2023103002" Device="FileChgr2-Dev1" (/bacula/backup)
Catalog record for Volume "Vol-remote-2023103002", Slot 0 successfully created.
Requesting to mount FileChgr2 ...
3906 File device ""FileChgr2-Dev1" (/bacula/backup)" is always mounted.
*run
A job name must be specified.
The defined Job resources are:
1: BackupLocalFiles
2: BackupCatalog
3: RestoreLocalFiles
Select Job resource (1-3): 1
Run Backup job
JobName: BackupLocalFiles
Level: Incremental
Client: bacula-fd
FileSet: Full Set
Pool: File (From Job resource)
Storage: File1 (From Job resource)
When: 2023-10-31 18:29:36
Priority: 10
OK to run? (yes/mod/no): yes
Job queued. JobId=4
*messages
31-Oct 18:29 bacula-dir JobId 4: Start Backup JobId 4, Job=BackupLocalFiles.2023-10-31_18.29.39_11
31-Oct 18:29 bacula-dir JobId 4: Using Device "FileChgr1-Dev2" to write.
31-Oct 18:29 bacula-sd JobId 4: Volume "Vol-2023103001" previously written, moving to end of data.
31-Oct 18:29 bacula-sd JobId 4: Ready to append to end of Volume "Vol-2023103001" size=902,557,818
31-Oct 18:29 bacula-fd JobId 4: /boot is a different filesystem. Will not descend from / into it.
31-Oct 18:29 bacula-fd JobId 4: /dev is a different filesystem. Will not descend from / into it.
31-Oct 18:29 bacula-fd JobId 4: /run is a different filesystem. Will not descend from / into it.
*status director
bacula-dir Version: 11.0.1 (05 February 2020) x86_64-redhat-linux-gnu redhat Beta
Daemon started 31-Oct-23 17:08, conf reloaded 31-Oct-2023 17:08:00
Jobs: run=4, running=0 mode=0,0
Crypto: fips=N/A crypto=OpenSSL
Heap: heap=409,600 smbytes=378,239 max_bytes=5,760,315 bufs=437 max_bufs=475
Res: njobs=3 nclients=1 nstores=2 npools=3 ncats=1 nfsets=3 nscheds=2

Scheduled Jobs:
Level Type Pri Scheduled Job Name Volume
===================================================================================
Incremental Backup 10 31-Oct-23 23:05 BackupLocalFiles Vol-2023103001
Full Backup 11 31-Oct-23 23:10 BackupCatalog Vol-2023103001
====

Running Jobs:
Console connected at 31-Oct-23 18:28
No Jobs running.
====

Terminated Jobs:
JobId Level Files Bytes Status Finished Name
====================================================================
1 Full 30,338 896.3 M OK 31-Oct-23 17:11 BackupLocalFiles
2 Restore 5 651 OK 31-Oct-23 17:23 RestoreLocalFiles
3 Restore 13 8.099 K OK 31-Oct-23 17:31 RestoreLocalFiles
4 Incr 40 10.46 M OK 31-Oct-23 18:29 BackupLocalFiles

====
*exit
# 查看远程服务器备份目录,可见备份文件已经上传。
[root@backup ~]# !tree
tree /bacula/
/bacula/
├── backup
│   ├── Vol-2023103001
│   └── Vol-remote-2023103002
└── restore
└── root
├── anaconda-ks.cfg
└── systemprep.sh