恢复极狐GitLab 安装实例
如果要恢复从另一个实例获取的备份,则必须在进行备份之前将现有实例迁移到使用对象存储。
建议您将备份还原到创建它的相同版本的极狐GitLab 实例。
极狐GitLab 备份恢复是通过在 chart 中提供的 Toolbox pod 上运行 backup-utility
命令来进行的。
在第一次运行恢复之前,您应该确保访问对象存储,确保 Toolbox 已正确配置
极狐GitLab Helm chart 提供的备份实用程序支持从以下任何位置恢复 tarball:
- 默认情况下,实例关联的对象存储服务中的
gitlab-backups
bucket。 - 一个可以从 pod 访问的公共 URL。
- 可以使用
kubectl cp
复制到 Toolbox pod 的本地文件
恢复 secrets
恢复 rails secrets
极狐GitLab chart 期望 Rails secret 以 Kubernetes Secret 的形式提供,内容以 YAML 格式提供。如果您要从 Linux 软件包实例恢复 rails secret,则 secret 以 JSON 格式存储在 /etc/gitlab/gitlab-secrets.json
文件中。要转换文件并以 YAML 格式创建密钥:
-
将文件
/etc/gitlab/gitlab-secrets.json
复制到运行kubectl
命令的工作站。 -
在您的工作站上安装 yq 工具(4.21.1 或更高版本)。
-
运行以下命令将您的
gitlab-secrets.json
转换为 YAML 格式:yq -P '{"production": .gitlab_rails}' gitlab-secrets.json -o yaml >> gitlab-secrets.yaml
-
检查新的
gitlab-secrets.yaml
文件是否包含以下内容:production: db_key_base: <your key base value> secret_key_base: <your secret key base value> otp_key_base: <your otp key base value> openid_connect_signing_key: <your openid signing key> ci_jwt_signing_key: <your ci jwt signing key>
从 YAML 文件恢复 rails secrets:
-
查找 rails secrets 的对象名称:
kubectl get secrets | grep rails-secret
-
删除已有的 secret:
kubectl delete secret <rails-secret-name>
-
使用与旧 secret 相同的名称创建新 secret,并传入您的本地 YAML 文件:
kubectl create secret generic <rails-secret-name> --from-file=secrets.yml=gitlab-secrets.yaml
重启 pods
为了使用新的 secret,需要重新启动 Webservice、Sidekiq 和 Toolbox pod。重新启动这些 Pod 的最安全方法是运行:
kubectl delete pods -lapp=sidekiq,release=<helm release name>
kubectl delete pods -lapp=webservice,release=<helm release name>
kubectl delete pods -lapp=toolbox,release=<helm release name>
恢复备份文件
恢复极狐GitLab 安装实例是:
-
通过部署 chart 确保您有一个正在运行的极狐GitLab 实例。 通过执行以下命令确保 Toolbox pod 已启用并正在运行
kubectl get pods -lrelease=RELEASE_NAME,app=toolbox
-
在上述任何位置准备好 tarball。 确保它以
<timestamp>_<version>_gitlab_backup.tar
格式命名。 -
记下数据库客户端的当前副本数,供后续重启使用:
kubectl get deploy -n <namespace> -lapp=sidekiq,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}' kubectl get deploy -n <namespace> -lapp=webservice,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}' kubectl get deploy -n <namespace> -lapp=prometheus,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}'
-
停止数据库的客户端,防止锁干扰恢复过程:
kubectl scale deploy -lapp=sidekiq,release=<helm release name> -n <namespace> --replicas=0 kubectl scale deploy -lapp=webservice,release=<helm release name> -n <namespace> --replicas=0 kubectl scale deploy -lapp=prometheus,release=<helm release name> -n <namespace> --replicas=0
-
运行备份实用程序以恢复 tarball
kubectl exec <Toolbox pod name> -it -- backup-utility --restore -t <timestamp>_<version>
这里,<timestamp>_<version>
来自存储在 gitlab-backups
存储桶中的 tarball 的名称。 如果要提供公共 URL,请使用以下命令
kubectl exec <Toolbox pod name> -it -- backup-utility --restore -f <URL>
您可以提供本地路径作为 URL,只要它采用以下格式:file:///<path>
- 此过程将花费时间,具体取决于 tarball 的大小。
-
恢复过程将删除数据库的现有内容,将现有仓库移动到临时位置并提取 tarball 的内容。仓库将被移动到磁盘上的相应位置,其它数据如产物、上传、LFS 等,将被上传到对象存储中的相应存储区。
-
重启应用:
kubectl scale deploy -lapp=sidekiq,release=<helm release name> -n <namespace> --replicas=<value> kubectl scale deploy -lapp=webservice,release=<helm release name> -n <namespace> --replicas=<value> kubectl scale deploy -lapp=prometheus,release=<helm release name> -n <namespace> --replicas=<value>
恢复 runner 注册令牌
恢复后,包含的 Runner 将无法注册到实例,因为它不再具有正确的注册令牌。
启用 Kubernetes 关联设置
如果恢复的备份不是来自 chart 的现有安装实例,您还需要在恢复后启用某些 Kubernetes 特定功能。
-
通过执行以下命令找到您的 Toolbox pod
kubectl get pods -lrelease=RELEASE_NAME,app=toolbox
-
运行实例设置脚本以启用必要的功能
kubectl exec <Toolbox pod name> -it -- gitlab-rails runner -e production /scripts/custom-instance-setup
重启 pods
为了使用新的更改,需要重新启动 Webservice 和 Sidekiq pod。 重新启动这些 Pod 的最安全方法是运行:
kubectl delete pods -lapp=sidekiq,release=<helm release name>
kubectl delete pods -lapp=webservice,release=<helm release name>
(可选)重置 root 用户密码
恢复过程不会使用备份中的值更新 gitlab-initial-root-password
secret。要以 root
身份登录,请使用备份中包含的原始密码。 如果无法再访问密码,请按照以下步骤重置密码。
-
通过执行命令进入到 Webservice pod
kubectl exec <Webservice pod name> -it -- bash
-
运行以下命令重置 root 用户的密码。用您选择的密码替换
#{password}
/srv/gitlab/bin/rails runner "user = User.first; user.password='#{password}'; user.password_confirmation='#{password}'; user.save!"