V tomto článku si na příkladu Gitlabu ukážeme, jak se zálohují systémy, které vyžadují spuštění nějakého skriptu před zálohou samotnou. V tomto případě se bude jednat o Rake skript pro zálohování Gitlab-CE. Tento článek předpokládá funkční instalaci Baculy.

Jak zálohovat

Gitlab-CE má na zálohu speciální rake skript, který v adresáři /var/opt/gitlab/backups vytvoří archiv se zálohou. Tuto zálohu musíme dostat do Baculy. Současně také nechceme, aby se v tomto adresáři hromadily zálohy a ubíraly tak místo na disku.

Musíme tedy vyřešit několik problémů:

  • Spustit konkrétní skript před pořízením zálohy
  • Zálohovat soubory
  • Promazat staré soubory se zálohou

Začneme s tím posledním, protože na to má Gitlab přímo konfigurační volbu. V souboru /etc/gitlab/gitlab.rb:

gitlab_rails['backup_keep_time'] = 604800

A přenastavíme gitlab:

gitlab-ctl reconfigure

Čas je uveden v sekundách. Já mám nastaveno, aby se zálohy na disku gitlabu udržovaly jeden týden.

Staré soubory se zálohou maže rake skript pro pořízení zálohy a maže je až po doběhnutí zálohy.

Teď nám zbývá vytvořit FileSet a Job pro zálohování.

FileSet

FileSet {
  Name = "GitLabFileSet"

  Include {
    File = "/etc"
    File = "/var/opt/gitlab/backups"

    Options {
      signature = SHA1
    }
  }
}

Potřebujeme určitě zálohovat /etc, protože ten není součástí zálohy gitlabu a obsahuje jeho konfiguraci (tj doménu, ssl klíče, časová zóna apod.). Dále zálohujeme adresář se zálohou gitlabu, tedy /var/opt/gitlab/backups.

Nastavovat kompresi není nutné, záloha gitlabu již komprimovaná je.

Job

V jobu, kromě již známých věcí jako Client apod., musíme definovat také skript, který se bude volat před zálohou souborů. K tomu slouží direktiva ClientRunBeforeJob.

Z dokumentace ke gitlabu víme, že skript se volá:

/opt/gitlab/bin/gitlab-rake gitlab:backup:create

Pokud chceme, můžeme přidat i parametr CRON=1, který skript umlčí a bude vypisovat pouze případné chyby.

Definice jobu tedy bude vypadat následovně:

Job {
  Name = "GitLabBackup"
  Type = Backup
  Level = Incremental
  Client = gitlab-fd
  FileSet = "GitLabFileSet"
  Schedule = "GitLabSchedule"
  Storage = MyBackupStorage
  Messages = Standard
  Pool = File
  SpoolAttributes = yes
  Priority = 10
  Write Bootstrap = "/var/db/bacula/%c.bsr"
  ClientRunBeforeJob = "/opt/gitlab/bin/gitlab-rake gitlab:backup:create"

}

Spuštění jobu

Teď už se můžeme nalogovat do bconsole a spustit:

reload
run job=GitLabBackup

v message uvidíme průběh zálohy a také výpisy ze skriptu (pokud jsme nezadali parametr CRON=1, alespoň pro prvních pár záloh se hodí mít vypisy zapnuté). Pokud je vše v pořádku, výpis bude vypadat nějak takto:

29-Apr 14:00 MyBaculaDirector JobId 206: No prior Full backup Job record found.
29-Apr 14:00 MyBaculaDirector JobId 206: No prior or suitable Full backup found in catalog. Doing FULL backup.
29-Apr 14:00 MyBaculaDirector JobId 206: Start Backup JobId 206, Job=GitLabBackup.2017-04-29_14.00.36_53
29-Apr 14:00 MyBaculaDirector JobId 206: Using Device "BackupDevice" to write.
29-Apr 14:00 gitlab-fd JobId 206: shell command: run ClientRunBeforeJob "/opt/gitlab/bin/gitlab-rake gitlab:backup:create"
29-Apr 14:01 gitlab-fd JobId 206: ClientRunBeforeJob: Dumping database ...
29-Apr 14:01 gitlab-fd JobId 206: ClientRunBeforeJob: Dumping PostgreSQL database gitlabhq_production ... [DONE]
29-Apr 14:01 gitlab-fd JobId 206: ClientRunBeforeJob: done
29-Apr 14:01 gitlab-fd JobId 206: ClientRunBeforeJob: Dumping repositories ...
...
29-Apr 14:07 gitlab-fd JobId 206: ClientRunBeforeJob: Deleting old backups ... done. (0 removed)
29-Apr 14:07 bsd-sd JobId 206: Volume "Vol-0002" previously written, moving to end of data.
29-Apr 14:07 bsd-sd JobId 206: Ready to append to end of Volume "Vol-0002" size=35,151,269,660
29-Apr 14:09 bsd-sd JobId 206: Elapsed time=00:02:49, Transfer rate=105.2 M Bytes/second
29-Apr 14:09 bsd-sd JobId 206: Sending spooled attrs to the Director. Despooling 289,044 bytes ...
29-Apr 14:09 MyBaculaDirector JobId 206: Bacula MyBaculaDirector 7.4.7 (16Mar17):
  Build OS:               amd64-portbld-freebsd11.0 freebsd 11.0-RELEASE-p8
  JobId:                  206
  Job:                    GitLabBackup.2017-04-29_14.00.36_53
  Backup Level:           Full (upgraded from Incremental)
  Client:                 "gitlab-fd" 7.4.4 (202Sep16) x86_64-pc-linux-gnu,debian,9.0
  FileSet:                "GitLabFileSet" 2017-04-29 13:30:03
  Pool:                   "File" (From Job resource)
  Catalog:                "MyCatalog" (From Client resource)
  Storage:                "MyBackupStorage" (From Job resource)
  Scheduled time:         29-Apr-2017 14:00:35
  Start time:             29-Apr-2017 14:07:06
  End time:               29-Apr-2017 14:09:57
  Elapsed time:           2 mins 51 secs
  Priority:               10
  FD Files Written:       1,236
  SD Files Written:       1,236
  FD Bytes Written:       17,786,227,287 (17.78 GB)
  SD Bytes Written:       17,786,379,333 (17.78 GB)
  Rate:                   104013.0 KB/s
  Software Compression:   None
  Snapshot/VSS:           no
  Encryption:             no
  Accurate:               no
  Volume name(s):         Vol-0002
  Volume Session Id:      29
  Volume Session Time:    1493117850
  Last Volume Bytes:      52,950,861,627 (52.95 GB)
  Non-fatal FD errors:    0
  SD Errors:              0
  FD termination status:  OK
  SD termination status:  OK
  Termination:            Backup OK

29-Apr 14:09 MyBaculaDirector JobId 206: Begin pruning Jobs older than 1 month .
29-Apr 14:09 MyBaculaDirector JobId 206: No Jobs found to prune.
29-Apr 14:09 MyBaculaDirector JobId 206: Begin pruning Files.
29-Apr 14:09 MyBaculaDirector JobId 206: No Files found to prune.
29-Apr 14:09 MyBaculaDirector JobId 206: End auto prune.

Výstup ze skriptu vidíme ve výpisu pod označením ClientRunBeforeJob.