GitLab幕后故事——备份恢复篇

1,391 阅读6分钟

本文的 GitLab 备份恢复包括日常运行场景和实例迁移部署场景

参考: archives.docs.gitlab.com/14.10/ee/ra…

非 Omnibus GitLab 软件包安装方式,需要 Rsync:

  • yum install -y rsync
  • apt-get install rsync

一、GitLab 备份

1、文件备份

文件清单

(1) GitLab 文件:
  • 查找authorized_keys:
    • getent passwd git | cut -d: -f6 | awk '{print $1"/.ssh/authorized_keys"}'
  • 备份项:
    • # 配置文件
      /etc/gitlab/gitlab.rb
      # 敏感信息文件(数据库加密密钥、 CI/CD 变量以及用于双因素身份验证的变量)
      /etc/gitlab/gitlab-secrets.json
      # 公钥文件
      /var/opt/gitlab/.ssh/authorized_keys
      # 邮件服务器配置
      /etc/postfix/main.cfpostfix
      
(2) nginx相关文件:
  • 检查默认nginx配置文件,并迁移至新Nginx服务
  • 备份项:
    • # nginx配置文件,包含gitlab-http.conf文件
      /var/opt/gitlab/nginx/conf/nginx.conf 
      # gitlab核心nginx配置文件
      /var/opt/gitlab/nginx/conf/gitlab-http.conf
      /etc/nginx/conf.d/test-betawm-com.conf
      

文件打包

  • mkdir gitlab_backup-files
  • cd gitlab_backup-files/
  • cp /var/opt/gitlab/.ssh/authorized_keys .
  • cp /etc/gitlab/gitlab.rb .
  • cp /etc/gitlab/gitlab-secrets.json .
  • 生成压缩包:
    • tar -zcvf gitlab_backup-files.tar.gz ./

2、数据备份

相关配置

  • gitlab.rb文件:
    • # 备份存档目录
      gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
      # 备份存档权限
      gitlab_rails['backup_archive_permissions'] = 0644
      # 备份生命周期为7天(604800 seconds)
      gitlab_rails['backup_keep_time'] = 604800
      

备份命令

  • 默认备份目录:/var/opt/gitlab/backups/
(1) Linux安装(Omnibus 包)
  • GitLab 12.1 及之前版本:
    • gitlab-rake gitlab:backup:create
  • GitLab 12.2 及之后版本:
    • gitlab-backup create
(2) Docker安装
  • GitLab 12.1 及之前版本:
    • docker exec -t <container name> gitlab-rake gitlab:backup:create
  • GitLab 12.2 及之后版本:
    • docker exec -t <container name> gitlab-backup create

gitlab-backup 备份说明

可选参数:
  • BACKUP: 备份文件名为[TIMESTAMP]_gitlab_backup.tar,该参数可以自定义[TIMESTAMP]部分的名称
  • STRATEGY=copy: 添加此参数不需要停止服务,但是需要增加一倍存储空间
  • SKIP: 备份中排除特定目录
  • GITLAB_BACKUP_MAX_CONCURRENCY: 同时备份的最大项目数。默认为逻辑CPU的数量(在GitLab14.1及之前版本中,默认为1)
  • GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY: 每个存储上同时备份的最大项目数。默认为2(在GitLab14.1及更早版本中,默认为1)
  • INCREMENTAL=yes: 增量备份
执行备份:
  • sudo gitlab-backup create STRATEGY=copy GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=2
针对数据量较大的情况:
  • 场景:
    • ssh连接服务器都会有会话时长的限制,备份大文件可能会出现由于ssh远程连接时超时而备份中断的情况
  • 方案一、服务端更改配置:
    • 修改配置文件/etc/ssh/sshd_config
      • # 如果客户端长时间没有操作,断开的时间为:ClientAliveInterval * ClientAliveCountMax
        # 指定了服务器端向客户端发送消息的间隔,单位为s
        ClientAliveInterval 0 
        # 服务器端发送消息后客户端没有响应的次数限制,达到自动断开
        ClientAliveCountMax 3
        
    • 生效:
      • service sshd restart
  • 方案二、命令后台执行:
    • nohup gitlab-backup create STRATEGY=copy GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=2 > /log/gitlab-backup_log.txt 2>&1 &

image.png

备份说明

目录名称备份文件说明
db数据库备份,主要为PostgreSQL数据内容
uploads附件数据备份
repositoriesGit仓库数据备份
buildsCI Job输入日志等数据备份
artifactsCI Job构件数据备份
lfsLFS对象数据备份
registry容器镜像备份
pagesGitLab Pages content数据备份

3、停止GitLab服务

  • 为保障数据一致性和数据完整性,停止GitLab服务防止用户操作
  • gitlab-ctl stop
  • gitlab-ctl status

二、GitLab 恢复

Linux安装(Omnibus 包)

1、文件准备

  • 传送备份文件包
  • 解压压缩包:
    • tar -zxvf gitlab_backup-files.tar.gz ./
  • 恢复配置文件:
    • mv /etc/gitlab/gitlab.rb /etc/gitlab/gitlab.rb.bak
    • mv gitlab_backup-files/gitlab.rb /etc/gitlab/
  • 恢复db secret信息:
    • cp gitlab_backup-files/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json
    • chown git.git /etc/gitlab/gitlab-secrets.json
  • 恢复公钥文件:
    • cp gitlab_backup-files/authorized_keys /var/opt/gitlab/.ssh/authorized_keys
    • chown git.git /var/opt/gitlab/.ssh/authorized_keys
  • 其他文件根据使用情况恢复

2、数据恢复前置条件

  • 安装了与创建备份的 GitLab Omnibus 完全相同的版本和类型 (CE/EE) 。
  • 至少执行过一次:gitlab-ctl reconfigure
  • GitLab正在运行(sudo gitlab-ctl start
  • 备份的数据tar文件位于配置文件(gitlab.rb)中描述的备份目录(gitlab_rails['backup_path'])中,默认值为/var/opt/gitlab/backups,它需要归git用户所有:
    • cp xxxxx-ce_gitlab_backup.tar /var/opt/gitlab/backups/
    • chown git:root /var/opt/gitlab/backups
    • chown git.git /var/opt/gitlab/backups/xxxxx-ce_gitlab_backup.tar
    • chmod -R 755 /var/opt/gitlab/backups
  • 停止连接到数据库的进程。让GitLab的其余部分保持运行:
    • gitlab-ctl stop puma
    • gitlab-ctl stop sidekiq
  • 检查状态:
    • gitlab-ctl status

3、gitlab-backup 备份说明

可选参数:
  • BACKUP=timestamp_of_backup:如果存在多个备份,则需要(_gitlab_backup.tar之前的部分)
  • force=yes:不询问是否应重新生成authorized_keys 文件,并假定“是”以警告有关数据库表被删除、启用“写入authorized_keys 文件”设置以及更新LDAP 提供程序
恢复备份:
  • GitLab 12.1 及之前版本:
    • gitlab-rake gitlab:backup:restore
  • GitLab 12.2 及之后版本:
    • gitlab-backup restore BACKUP=xxxx-ce
  • 手动恢复期间需要多次输入yes
报错解决:
  • Unpacking backup ..rake aborted! 
    Errno:EBADF:Bad file descriptor Q io_fillbuf fd:0 <STDIN> 
    

image.png

  • 为备份文件赋权:
    • chown git.git /var/opt/gitlab/backups/xxxxx-ce_gitlab_backup.tar
针对数据量较大的情况:
  • 后台执行:
    • nohup gitlab-backup restore force=yes BACKUP=xxxx-ce > /log/gitlab-backup_restore.log 2>&1 &

image.png

  • 直接使用gitlab-backup restore BACKUP=xxxx-ce,导致恢复备份会中断

image.png

  • 解决方案 ———— GitLab非交互恢复的方法:
    • ① 命令中指定force=yes
    • ② HereDocument的方式:(不适用于后台执行)
      • gitlab-rake gitlab:backup:restore BACKUP=1597188417 <<EOF
        > yes
        > yes
        > EOF
        

image.png

4、后续操作

(示例为GitLab 12.2 及之后版本,GitLab 12.1 及之前版本使用gitlab-rake gitlab:backup:restore命令替换)

  • 重新配置、重启 GitLab:
    • gitlab-ctl reconfigure
    • gitlab-ctl restart
  • 检查数据库值可以被解密(13.1版本以上):
    • gitlab-rake gitlab:doctor:secrets
  • 完整性检查:
    • gitlab-rake gitlab:check SANITIZE=true
    • gitlab-rake gitlab:artifacts:check
    • gitlab-rake gitlab:lfs:check
    • gitlab-rake gitlab:uploads:check

Docker安装

1、停止连接到数据库的进程

  • docker exec -it <name of container> gitlab-ctl stop puma
  • docker exec -it <name of container> gitlab-ctl stop sidekiq

2、检查状态

  • docker exec -it <name of container> gitlab-ctl status

3、恢复备份

  • docker exec -it <name of container> gitlab-backup restore BACKUP=xxxx-ce

4、重新启动

  • docker restart <name of container>

5、完整性检查

  • docker exec -it <name of container> gitlab-rake gitlab:check SANITIZE=true

三、GitLab 定期备份

前置准备

  • yum install vixie-cron
  • yum install crontabs

crontab 说明

  • 定期备份需要借助 crond 服务工具
  • crontab定时调度任务指令说明:
    • # Example of job definition:
      # .---------------- minute (0 - 59) 分钟
      # |  .------------- hour (0 - 23)  小时
      # |  |  .---------- day of month (1 - 31)  日期
      # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...  月份
      # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat  星期
      # |  |  |  |  |
      # *  *  *  *  * user-name command to be executed
      

配置定期备份

定期备份计划:

  • 每天增量备份,每周全量备份,备份生命周期 8 天(691200 秒)

配置定时任务:

  • root用户下操作
  • crontab -e
    • GitLab 12.2 及之后版本:
    • # CRON=1 备份脚本隐藏报错外的所有进度输出
      # 周一至周六23点增量备份一次
      0 23 * * 1-6 /opt/gitlab/bin/gitlab-backup create STRATEGY=copy GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=2 CRON=1 INCREMENTAL=yes > /log/gitlab-backup-regular-increment_log.txt 2>&1 &
      # 每周日23点全量备份一次
      0 23 * * 0 /opt/gitlab/bin/gitlab-backup create STRATEGY=copy GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=2 CRON=1 > /log/gitlab-backup-regular-full_log.txt 2>&1 &
      
    • GitLab 12.1 及之前版本:
    • # 周一至周六23点增量备份一次
      0 2 * * 1-6 root /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1 INCREMENTAL=yes INCREMENTAL=yes > /log/gitlab-backup-regular-increment_log.txt 2>&1 &
      # 每周日23点全量备份一次
      0 23 * * 0 root /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1 > /log/gitlab-backup-regular-full_log.txt 2>&1 &
      

重新加载配置:

  • service crond reload

重启cron服务:

  • service crond restart