---
# System prepended metadata

title: Gitlab BackUp設置
tags: [Gitlab, Install]

---

###### tags: `Install` `Gitlab`

# Gitlab BackUp設置

Gitlab安裝完後，因部門為全球設備部門，資料很重要，所以一定要做備援機制。稍微研究紀錄一下備援設置。此為簡易版本...進階版要做Auto Fault需要好幾台虛擬機，結尾會稍微提一下。

我有兩台Ubnutu VM，一台IP是192.168.100.101，這台是Gitlab Server，另一台是192.168.100.102，這台做Gitlab Server的Backup。因為是做測試，我直接用vagrant去啟兩台VM User都是vagrant。

## 一、打通SSH

第一步先做SSH設置，讓101這台可以透過scp將檔案丟到102這台做備份。

### 生成密鑰

GitLab Server VM（192.168.100.101），生成SSH Key

```bash=
ssh-keygen -t ed25519 -C "GitLab Server VM"
```

> ed25519 指定要生成的 SSH 金鑰類型為 ed25519

在GitLab Backup VM（192.168.100.102）
```bash=
ssh-keygen -t ed25519 -C "GitLab Backup VM"
```
SSH Key會在下述路徑(username根據你的account name去修正) 

/home/username/.ssh

### 設定密鑰

將GitLab Server VM的公鑰添加到GitLab Backup VM的authorized_keys文件中。

首先，在GitLab Server VM上顯示公鑰內容：

```bash=
cat /home/username/.ssh/id_ed25519.pub
```

將顯示的公鑰內容複製到GitLab Backup VM上/home/username/.ssh/authorized_keys文件中(直接Append在後面)

接著，將GitLab Backup VM的公鑰添加到GitLab Server VM的authorized_keys文件中。

首先，在GitLab Backup VM上顯示公鑰內容：

```bash=
cat /home/username/.ssh/id_ed25519.pub
```

將顯示的公鑰內容複製到GitLab Server VM上/home/username/.ssh/authorized_keys文件中(直接Append在後面)

### 測試

```bash=
ssh username@192.168.100.102
```

```bash=
ssh username@192.168.100.101
```

### Double Check

確保SSH連接正常後，請檢查兩台VM上的目錄權限。在GitLab Server VM與GitLab Backup VM上，確保.ssh目錄及其內容的權限正確：

```bash=
chmod 700 /home/username/.ssh
chmod 600 /home/username/.ssh/id_ed25519
chmod 600 /home/username/.ssh/authorized_keys
```
## 二、寫備份腳本

### Backup Server建立資料夾路徑 (192.168.100.102)

這邊我直接在user路徑下建置一個gitlab_backups資料夾

> /home/vagrant/gitlab_backups

### Gitlab Server建立備份腳本 (192.168.100.101)

定時備份這件事情需透過crontab去執行，我們需要寫一個執行腳本，參考如下

```bash=
#!/bin/bash

SSH_KEY="/home/vagrant/.ssh/id_ed25519"
REMOTE_USER="vagrant"
REMOTE_IP="192.168.100.102"
REMOTE_PATH="/home/vagrant/gitlab_backups"

# 創建GitLab數據備份
sudo gitlab-rake gitlab:backup:create

# 修改權限
sudo chmod -R 755 /var/opt/gitlab/backups

# 獲取當前備份文件名
BACKUP_FILENAME=$(ls -1tr /var/opt/gitlab/backups | tail -n 1)

# 將備份文件傳輸到GitLab Backup VM
rsync -avz -e "ssh -i $SSH_KEY" "/var/opt/gitlab/backups/${BACKUP_FILENAME}" "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PATH}"

# 備份gitlab.rb和gitlab-secrets.json文件
rsync -avz -e "ssh -i $SSH_KEY" /etc/gitlab/gitlab.rb "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PATH}"
rsync -avz -e "ssh -i $SSH_KEY" /etc/gitlab/gitlab-secrets.json "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PATH}"
```

內容大致是

 - Gitlab備份，會在/var/opt/gitlab/backups 路徑下產生備份檔案
 - 改變路徑權限 (這做法比較快，但安全度較低，比較好的做法是建置使用者Group，根據Group做權限管理)
 - 傳送備份檔案
 - 傳送gitlab.rb
 - 傳送gitlab-secrets.json

因為gitlab.rb與gitlab-secrets.json有敏感資料，所以在下備份指令時，這兩個檔案需手動備份。

> 另外需注意一點，sh檔案建置好後記得使用chmod +x gitlab_backup.sh去修改檔案權限，否則crontab無法正確執行

### 測試

 腳本寫完可以自行嘗試用bash執行看看，是否能正常Work

![](https://i.imgur.com/7MxwXZK.png)


## 三、Crontab設置

### 排程設置

腳本建置測試完成後，接下來做排程設置，使用root打開crontab

```bash=
sudo crontab -e
```

選擇1，編輯，在crontab文件中，添加以下行以定期執行備份。例如，每天凌晨2點運行備份和傳輸：

0 2 * * * /home/vagrant/gitlab_backup.sh

就可以讓Gitlab Server定期備份了。

### Crontab查詢是否Work

如果要看排程是否有順利執行，可下

```bash=
grep CRON /var/log/syslog
```

如果顯示

```
Apr 27 12:10:00 your_hostname CRON[12345]: (your_username) CMD (sleep 5 && /path/to/your/bash/script.sh)
```

那代表排程有正確執行，自動備份即啟動

## 四、Recovery

如果要還原Gitlab資料，請照下敘步驟操作

### 停止Gitlab服務

```bash=
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
```

### 下Recovery指令 

如果你的檔名是1682575488_2023_04_27_15.11.0_gitlab_backup，你需要下

```bash=
sudo gitlab-rake gitlab:backup:restore BACKUP=1682575488_2023_04_27_15.11
```
### 恢復Gitlab服務

```bash=
sudo gitlab-ctl start
```

### 注意點


#### 注意點一

你在Recovery過程中會跑出下述錯誤

```
Restoring PostgreSQL database gitlabhq_production ... ERROR:  must be owner of extension pg_trgm
ERROR:  must be owner of extension btree_gist
ERROR:  must be owner of extension btree_gist
ERROR:  must be owner of extension pg_trgm
```

根據GitLab的官方文件和網上許多用戶的經驗，這錯誤通常可以忽略，因為它們不太可能對GitLab實例的正常運行產生影響。該錯誤是因為在恢復過程中，備份腳本嘗試為已經存在的擴展重設所有者，而這些擴展的所有者已經是正確的。

因此，如果在恢復過程中看到這些錯誤，應該可以繼續使用GitLab，而不必擔心它們對實例的功能產生任何負面影響。但是，但為了確保一切正常運行，建議您在恢復後對GitLab實例進行徹底檢查，以確保所有項目、用戶和配置都已成功恢復。[參考](https://gitlab.com/gitlab-org/gitlab/-/issues/266988)

#### 注意點二

還原過程中，你會遇到詢問

```
You will lose any data stored in the authorized_keys file.
Do you want to continue (yes/no)? 
```

要注意你的authorized_keys，因為他會被清掉，需要做手動備份

```bash=
#備份
sudo cp /var/opt/gitlab/.ssh/authorized_keys /path/to/backup/location/
```

```bash=
# 還原
sudo cp /path/to/backup/location/authorized_keys /var/opt/gitlab/.ssh/
```

## 五、HA理想做法

基本上如果要做到HA，需要Linux LVS 3台，Nginx 2台，gitlab 2台，不過因部門短期就要使用...只能先用最簡單架構先架起來使用


 - Linux LVS (3台)：LVS（Linux Virtual Server）是一個基於Linux內核的負載均衡解決方案。它可以將流量分配到多台後端伺服器，以達到負載平衡和故障切換的目的。部署3台 LVS 是為了消除單點故障（Single Point of Failure, SPOF），並提供一定程度的冗餘。可以配置 LVS 使用 Keepalived 來實現高可用性和自動故障切換。

- Nginx (2台)：Nginx 是一個高性能的 HTTP 伺服器和反向代理伺服器。在此架構中，Nginx 主要用於 SSL 終止和將流量轉發到後端的 GitLab 伺服器。部署2台 Nginx 是為了提供冗餘，以確保在一台 Nginx 伺服器出現故障時，系統仍然可以運行。

 - GitLab (2台)：部署2台 GitLab 伺服器是為了實現高可用性和負載平衡。當其中一台 GitLab 伺服器出現故障時，另一台伺服器可以繼續運行，以確保系統不會因單點故障而中斷。此外，兩台 GitLab 伺服器可以共享工作負載，提高整體性能。

這個架構的目的是確保 GitLab Server 在可能的硬體回復和軟體回復方面能夠立即恢復運行。通過實現高可用性、冗餘和負載平衡，這個架構可以確保 GitLab Server 在面臨故障時仍具有良好的運行狀態。這對於需要保證業務連續性和最小停機時間的企業和組織尤為重要。