gitlab备份与恢复【翻译】
一个应用数据的备份会产生一个归档文件,它包含database,所有的repositories ,以及所有的附件。
您只能在完全相同的版本和类型的(gitlab CE/EE)间进行备份还原,这是从一台gitlab往另一台gitlab迁移repositories的最佳方法。
环境要求
为了能够备份和恢复,您需要两个基本工具
安装在您的系统上。
Rsync
如果你安装GitLab:
- 使用Omnibus包,你什么都不用做
- 从源码安装,确认你的
rsync
已经安装
# Debian/Ubuntu
sudo apt-get install rsync
# RHEL/CentOS
sudo yum install rsync
Tar
备份和恢复任务在后台使用tar来创建和提取
档案。确保您的tar版本为1.30或更高版本
系统。要检查版本,请运行:
tar --version
Backup timestamp
NOTE: 在GitLab 9.2中,时间戳格式从EPOCH_YYYY_MM_DD
更改为
EPOCH_YYYY_MM_DD_GitLab_version
,例如1493107454_2018_04_25
将成为1493107454 _2018_04_25_10.6.4-ce
。
归档文件将被保存在backup_path
中,这个路径可以在config/gitlab.yml
中定义。文件名将是[TIMESTAMP]_gitlab_backup.tar
,TIMESTAMP
定义了一个备份文件的创建时间加上gitlab的版本号。时间戳在你恢复gitlab并且有多个备份文件时被需要。
例如,如果备份文件名为1493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar
,时间戳指的就是1493107454_2018_04_25_10.6.4-ce
基于Gitlab创建一个备份
GitLab提供了一个简单的命令行接口来备份整个实例。它备份如下几个东西
- Database
- Attachments
- Git repositories data
- CI/CD job output logs
- CI/CD job artifacts
- LFS objects
- Container Registry images
- GitLab Pages content
注意:Warning GitLab不备份任何配置文件、SSL证书或系统文件,强烈建议您阅读有关存储配置文件的章节。
如果你已经使用Omnibus包安装了GitLab,请使用这个命令:
sudo gitlab-backup create
NOTE: 对于GitLab 12.1和更早版本,使用gitlab-rake gitlab:backup:create
。
如果你已经从源代码安装GitLab,请使用此选项:
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
如果你在Docker容器中运行GitLab,你可以从主机上运行备份:
docker exec -t <container name> gitlab-backup create
对于GitLab 12.1和更早版本,使用gitlab-rake gitlab:backup:create
如果你在k8s集群上使用GitLab helm chart,
您可以通过kubectl找到GitLab任务运行器pod,使用 backup-utility
脚本运行备份任务
。有关更多细节,请参阅备份GitLab安装:
kubectl exec -it <gitlab task-runner pod> backup-utility
和k8s的例子类似,如果你把GitLab水平扩展
到多个应用服务器,您应该选择一个特定节点(不会自动缩放)
来运行backup rake任务。因为backup rake任务是与
主Rails应用程序紧耦合的,这通常是你的一个特殊节点上面运行着Unicorn/Puma and/or Sidekiq。
Example output:
Dumping database tables:
- Dumping table events... [DONE]
- Dumping table issues... [DONE]
- Dumping table keys... [DONE]
- Dumping table merge_requests... [DONE]
- Dumping table milestones... [DONE]
- Dumping table namespaces... [DONE]
- Dumping table notes... [DONE]
- Dumping table projects... [DONE]
- Dumping table protected_branches... [DONE]
- Dumping table schema_migrations... [DONE]
- Dumping table services... [DONE]
- Dumping table snippets... [DONE]
- Dumping table taggings... [DONE]
- Dumping table tags... [DONE]
- Dumping table users... [DONE]
- Dumping table users_projects... [DONE]
- Dumping table web_hooks... [DONE]
- Dumping table wikis... [DONE]
Dumping repositories:
- Dumping repository abcd... [DONE]
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
Deleting tmp directories...[DONE]
Deleting old backups... [SKIPPING]
保存配置文件
通过raketask命令进行备份的任务不会保存配置文件,最主要的原因是你的数据库包含
用于双因素身份验证的加密信息,以及CI/CD
“secure variables”,等等。将加密信息及其密钥存储在同一个位置违背了只在第一个地方使用加密的目的。
注意:Warning 加密文件对于保存数据库加密密钥是必不可少的。
至少,你必须备份:
对于Omnibus:
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
从源代码安装:
/home/git/gitlab/config/secrets.yml
/home/git/gitlab/config/gitlab.yml
对于Docker安装,您必须
备份存储配置文件的卷。如果你根据gitlab文档创建了GitLab container,应该在/srv/gitlab/config
目录下。
您可能还想备份任何TLS密钥和证书,以及您的SSH主机密钥。
如果您使用Omnibus GitLab,请参阅一些额外的文章以备份你的配置。
万一加密文件丢失,请参阅troubleshooting章节。
备份配置
GitLab提供的用于备份实例的命令行工具可以提供更多配置项。
(Backup strategy option)备份策略
默认的备份策略本质上是,使用Linux命令tar和gzip命令从各自的目录进行备份。在大多数情况下没问题,但在数据快速变化时可能会导致问题。
当tar读取数据时数据发生变化时,变化导致备份文件出错,从而导致备份失败。为了解决这个问题,8.17引入了一种名为copy
的新备份策略。该策略在tar和gzip命令执行前,将备份文件copy到一个新的临时目录。
一个副作用是备份过程将占用额外的1倍磁盘
空间。该进程在每个阶段都会尽力清理临时文件,他并不复杂,但对于大型安装来说,这可能是一个相当大的变化。这就是为什么copy
策略在8.17中不是默认的。
若要使用copy
策略而不是默认的streaming策略,请在Rake task 命令中指定STRATEGY=copy
。例如:
sudo gitlab-backup create STRATEGY=copy
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
Backup 文件名称
默认情况下,一个备份文件会按照上面Backup timestamp
章节的配置进行创建。但是,您可以通过设置BACKUP
环境变量覆盖文件名的[TIMESTAMP]
部分。例如:
sudo gitlab-backup create BACKUP=dump
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
备份结果将是dump_gitlab_backup.tar
,这对于使用rsync和增量备份的系统是很有用的,并且可以大大加快传输速度。
Rsyncable
为了确保生成的归档文件可以通过rsync自动转移,可以设置GZIP_RSYNCABLE=yes
,他会在进行gizp
时设置--rsyncable
,这只在与上一章节(Backup 文件名称)结合使用。
注意在gizp
时设置--rsyncable
不保证在所有系统上都可用,可以使用gzip --help
进行验证
sudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
在备份中排除指定目录
你可以通过环境变量SKIP
来指定什么文件被排除,可选项如下:
db (database)
uploads (attachments)
repositories (Git repositories data)
builds (CI job output logs)
artifacts (CI job artifacts)
lfs (LFS objects)
registry (Container Registry images)
pages (Pages content)
使用逗号同时指定几个选项:
所有wiki都将作为repositories
组的一部分进行备份。不存在的wiki将在备份期间跳过。
Omnibus 版本
sudo gitlab-backup create SKIP=db,uploads
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
源码安装版本
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=db,uploads RAILS_ENV=production
上传备份文件到云存储
从GitLab 7.4开始,你可以让备份脚本自动上传.tar
文件,他使用Fog library进行上传。在下面的示例中,我们使用Amazon S3进行存储,但Fog也允许您使用其他存储提供商。GItlab 从aws,Google,Openstack Swift import 云驱动。Rackspace和阿里云也是如此,本地驱动也可行。
使用Amazon S3
Omnibus 安装方式
- 将以下配置加入
/etc/gitlab/gitlab.rb
gitlab_rails['backup_upload_connection'] = {
'provider' => 'AWS',
'region' => 'eu-west-1',
'aws_access_key_id' => 'AKIAKIAKI',
'aws_secret_access_key' => 'secret123'
# If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
# 'use_iam_profile' => true
}
gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
- reconfigure gitlab 让配置生效
其他云厂商,略。。。。
指定用于备份的自定义目录
注意: 此选项仅适用于远程存储。如果您想要对备份进行分组,您可以传递一个DIRECTORY
环境变量:
sudo gitlab-backup create DIRECTORY=daily
sudo gitlab-backup create DIRECTORY=weekly
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
上载到本地挂载的共享 略。。。。
备份档案的权限
GitLab创建的备份文件(1393513186_2014_02_27_gitlab_backup.tar
)默认将会有git/git
这一用户和用户组以及0600
权限。这是为了避免其他系统用户读取GitLab的数据。如果您需要备份归档具有不同的权限,您可以使用“archive_permissions”设置。
Omnibus 安装方式:
- 编辑
/etc/gitlab/gitlab.rb
gitlab_rails['backup_archive_permissions'] = 0644 # Makes the backup archives world-readable
- reconfigure gitlab
源码安装方式
- 编辑
/home/git/gitlab/config/gitlab.yml
backup:
archive_permissions: 0644 # Makes the backup archives world-readable
- restart gitlab
配置corn进行周期备份
注意:corn jobs不会备份你的gitlab configuration file以及SSH host keys
Omnibus 版本
- 编辑
/etc/gitlab/gitlab.rb
## Limit backup lifetime to 7 days - 604800 seconds
gitlab_rails['backup_keep_time'] = 604800
- reconfigure gitlab
注意backup_keep_time
只作用于本地文件,gitlab不会删除第三方对象存储上的备份文件,因为用户可能不允许这么做。我们建议您配置适当的保留率
对象存储的策略。例如你可以按如下方式配置s3的备份策略
the S3 backup policy.
要调度一个cron作业来备份你的存储库和GitLab元数据,请使用root用户:
sudo su -
crontab -e
在这里,添加以下代码行来安排每天凌晨2点的备份:
0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:create
您可能还希望为备份设置一个有限的生存期,以防止定期备份使用所有磁盘空间。
源码安装版本:
- 编辑
home/git/gitlab/config/gitlab.yml
backup:
## Limit backup lifetime to 7 days - 604800 seconds
keep_time: 604800
- 重启gitlab
sudo -u git crontab -e # Edit the crontab for the git user
在底部加入
# Create a full backup of the GitLab repositories and SQL database every day at 4am
0 4 * * * cd /home/git/gitlab && PATH=/usr/local/bin:/usr/bin:/bin bundle exec rake gitlab:backup:create RAILS_ENV=production CRON=1
CRON=1
环境设置告诉备份脚本,如果没有错误,就禁止所有的进度输出。建议这样做以减少cron spam。
恢复(Restore)
GitLab提供了一个简单的命令行界面来恢复您的整个安装,并且足够灵活以满足您的需求。
下一章节包含重要信息
,确保至少阅读并测试整个恢复过程一次然后才尝试在生产环境中执行它。
备份和恢复必须保证是同一个gitlab版本号。
恢复的前置要求
在恢复前请确保目标gitlab运行正常,这主要是因为系统用户执行恢复命令(git
)通常不具备SQL 数据库(gitlabhq_production
)的增删权限。所有已存在数据将被清楚(SQL)或被转移到另一个目录(repositories, uploads)
为了恢复一个备份,你要恢复/etc/gitlab/gitlab-secrets.json
(Omnibus方式)或/home/git/gitlab/.secret
(源码安装方式),这个文件包含数据库加密key,CI/CD 变量,双因素登陆的变量,如果你无法恢复这个加密key文件,用户双因素登陆,GitLab runner的接入权限将会失去。
你可能也需要恢复任何TLS keys, certificates, or SSH host keys.
根据您的情况,您可能希望使用一个或来运行恢复命令:
-
BACKUP=timestamp_of_backup
- 如果存在多个备份,则是必需的。用于指定具体时间戳 -
force=yes
- 让authorized_keys 的操作选择yes,以及数据库删除的警告也被设置成yes,启用“Write to authorized_keys文件”设置,并更新LDAP提供程序。
如果您正在还原到作为挂载点的目录中,在尝试恢复之前,确定这些目录为空。
否则gitlab 将会在恢复前尝试移动这些目录,并且这个操作可能引发error。
Read more on configuring NFS mounts
源码安装方式的恢复
# Stop processes that are connected to the database
sudo service gitlab stop
bundle exec rake gitlab:backup:restore RAILS_ENV=production
输出样例
Unpacking backup... [DONE]
Restoring database tables:
-- create_table("events", {:force=>true})
-> 0.2231s
[...]
- Loading fixture events...[DONE]
- Loading fixture issues...[DONE]
- Loading fixture keys...[SKIPPING]
- Loading fixture merge_requests...[DONE]
- Loading fixture milestones...[DONE]
- Loading fixture namespaces...[DONE]
- Loading fixture notes...[DONE]
- Loading fixture projects...[DONE]
- Loading fixture protected_branches...[SKIPPING]
- Loading fixture schema_migrations...[DONE]
- Loading fixture services...[SKIPPING]
- Loading fixture snippets...[SKIPPING]
- Loading fixture taggings...[SKIPPING]
- Loading fixture tags...[SKIPPING]
- Loading fixture users...[DONE]
- Loading fixture users_projects...[DONE]
- Loading fixture web_hooks...[SKIPPING]
- Loading fixture wikis...[SKIPPING]
Restoring repositories:
- Restoring repository abcd... [DONE]
- Object pool 1 ...
Deleting tmp directories...[DONE]
下一步,恢复上文提到的/home/git/gitlab/.secret
目录。
重启gitlab
sudo service gitlab restart
Omnibus 方式恢复
本程序假定:
- 你的备份和恢复gitlab版本一致
- 你至少执行过一次
sudo gitlab-ctl reconfigure
- gitlab运行正常
第一步,确保用于恢复的tar文件在gitlab.rb
配置项中定义的gitlab_rails['backup_path']
目录中。默认是/var/opt/gitlab/backups
。并且文件的owner是git
用户。
sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git.git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar
停止连接到数据库的进程。关闭gitlab的其他组件:
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status
下一步恢复备份,指定你需要恢复的时间戳
# This command will overwrite the contents of your GitLab database!
sudo gitlab-backup restore BACKUP=1493107454_2018_04_25_10.6.4-ce
Note 对于gitlab12.1或者更老版本,使用gitlab-rake gitlab:backup:restore
警告 Warning:gitlab-rake gitlab:backup:restore
没有在注册表目录上设置正确的文件系统权限。这是一个已知 issue。 GitLab 12.2 或者更新,可以用gitlab-backup restore
去解决这个问题。
下一步,恢复上文提到的/etc/gitlab/gitlab-secrets.json
文件
reconfigure 让配置生效
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
sudo gitlab-rake gitlab:check SANITIZE=true
如果备份和恢复的gitlab版本不同可能会报错,请安装正确版本。
Docker 方式恢复(略)
选择备份策略
如果您的GitLab服务器包含大量Git存储库数据,您可能会发现GitLab备份脚本太慢。
在这种情况下,您可以考虑使用文件系统快照作为备份策略的一部分。
例如Amazon EBS
,LVM snapshots + rsync
如果您在一个虚拟服务器上运行GitLab,那么您也可以创建整个GitLab服务器的VM快照。但是,VM快照可能需要关闭VM,所以这种做法不通用。
其他需要注意的地方
本文档适用于GitLab社区和企业版,我们的备份
GitLab.com并确保你的数据是安全的,但你不能使用这些方法从GitLab.com导出/备份您的数据。
Issues 存储在数据库中。它们不能存储在Git本身中。
要将存储库从一台服务器迁移到另一台服务器,并使用最新版本的GitLab,你可以使用[import rake task](import.md)
来做大规模导入repository。注意,如果您执行 import rake 任务,而不是备份恢复,你必须有所有的repositories,并且没有其他数据
Troubleshooting
使用Omnibus包恢复数据库备份输出的警告
如果您正在使用备份还原过程,您可能会遇到以下警告:
psql:/var/opt/gitlab/backups/db/database.sql:22: ERROR: must be owner of extension plpgsql
psql:/var/opt/gitlab/backups/db/database.sql:2931: WARNING: no privileges could be revoked for "public" (two occurrences)
psql:/var/opt/gitlab/backups/db/database.sql:2933: WARNING: no privileges were granted for "public" (two occurrences)
请注意,尽管有这些警告,但备份已成功恢复。
rake task 使用gitlab
用户运行,他并没有超级用户对于数据库的访问权限。恢复完成初始化时,它也将以gitlab用户的身份运行,但它还将尝试更改它不能访问的对象。这些对象对数据库备份/恢复没有影响,但它们会发出这种烦人的警告。
要了解更多信息,请参阅postgresql问题trackerhere和here以及堆栈溢出类似的问题。
当机密文件丢失的时候
如果你没有备份秘钥文件,使用双因素登陆的用户将无法登录gitlab,你必须停止双因素登陆。
秘钥文件还负责存储另外几个包含敏感信息字段的秘钥,如果秘钥丢了,gitlab就不能解密这些字段,这会破坏很多功能,包括(但不限于):
- CI/CD variables* Kubernetes / GCP integration
- Custom Pages domains
- Project error tracking
- Runner authentication
- Project mirroring
- Web hooks
在CICD变量,以及running鉴权是,你可能会遇到一些奇怪的报错,比如
- Stuck jobs.
- 500 errors.
在这种情况下,您需要重置CI/CD变量的所有令牌
以及Runner身份验证,这将在下面更详细地描述。重置令牌后,您应该能够访问您的项目,作业
将重新开始运行。
** 警告warning **:使用以下命令的风险自负,并确保您已经采取了事先备份。
Reset CI/CD variables
略
Reset Runner registration tokens
略
Reset pending pipeline jobs
略
Container Registry push failures after restoring from a backup
略
Backup fails to complete with Gzip error
运行备份,会遇到gizp error
sudo /opt/gitlab/bin/gitlab-backup create
...
Dumping ...
...
gzip: stdout: Input/output error
Backup failed
如果出现请检查
- 确认有足够的磁盘空间来执行gzip操作。
- 如果正在使用NFS,检查是否设置了挂载选项timeout。默认值是600,将其更改为更小的值将导致此错误。