GitLabのバックアップ
LAN内で利用しているGitLabサーバを自動バックアップしたい。
0. 要件整理
(1) バックアップ方法
gitlab 12.2以降はgitlab-rakeではなく、gitlab-backupコマンドを利用する。
出力されたバックアップデータを同じLAN内のSynology NASに転送して保管することにする。
(2) 頻度・タイミング
個人利用なので、1週間に1度フルバックアップを取ることにする。cronによるgitlab-backupコマンドを実行する。
タイミングは月曜早朝(AM4時)とする。
(3) バックアップ先容量
10GB程度を確保する。仮に1回のバックアップで1GB利用するとしても2ヶ月は保管できることになる。
(4) 転送方法
一般的なファイル転送方法としては以下が挙げられる。
| 方法 | NFS | SMB | rsync |
|---|---|---|---|
| 速度 | 速い | 中程度 | 高速(差分同期) |
| 用途 | ファイル共有 | 異OS間のファイル共有 | バックアップや同期 |
| 設定の簡単さ | 普通 | 簡単(GUIあり) | 簡単(CLIのみ) |
| セキュリティ | 弱め(要設定) | 強力(ユーザ認証) | 強力(SSH利用) |
| リアルタイム性 | あり | あり | なし |
| 対応OS | Linux/Unix | Windows/Linux | 全て |
| WAN超え | 不安定 | SMB3以上なら可 | SSH経由で安定 |
| ファイルロック | 弱い | 強力 | なし |
| 使い方 | マウント | マウント | CLIでコマンド実行 |
今回は、マウント処理を入れると挙動が複雑になり運用が大変そうなので、マウント処理が不要なrsyncを採用する。
1. NAS側の設定
1-1. [Synology NAS] 共有フォルダの作成
コントロールパネル > 共有フォルダ > 作成 > 共有フォルダの作成から新規フォルダを作成

特に暗号化は不要

1-2. [Synology NAS] rsyncサービスの有効化
コントロールパネル > ファイルサービス > rsyncからrsyncサービスを有効にする

1-3. [Synology NAS] gitlab_backupユーザの作成
コントロールパネル > ユーザーとグループ > 作成から新規ユーザを作成する。
共有フォルダは「gitlab_backup」のみアクセス権限を付与する。

各設定項目は以下のように、基本デフォルトで、アプリケーション権限の割り当てにおいてrsysncのみ許可する。

1-4. [Synology NAS] SSH接続の有効化
rsyncは独自のネットワーク転送用プロトコルを持っているが、セキュリティと利便性の観点から、SSHを使って転送することとする。(SSHキー使えばGitLabサーバからパスワードなしで自動接続が可能)
そのため、SSH接続を受け付けるNAS側でもSSHを有効化しておく必要がある。

1-5. [Synology NAS] SSH関連フォルダパーミッション設定
SSHに関連したフォルダは厳格なパーミッション設定が求められる。具体的には、
- 「/home/(ユーザー名)/」のフォルダのパーミッションが「755」より厳しいこと
- 「/home/(ユーザー名)/.ssh」のフォルダのパーミッションが「700」であること
- 「/home/(ユーザー名)/.ssh/authorized_keys」のファイルのパーミッションが「600」であること
Synology NASはデフォルトでこのような権限にはなっていないので、変更してあげる必要がある。
なお、上記のルールはsshdのソースコードレベルで実装されているので、SSH設定ファイル(/etc/ssh/sshd_config)には直接「ディレクトリやファイルの権限」を指定する項目はないので、ハマりやすい。
設定方法としては、Synology NASの管理者権限を持つユーザでSSH接続して設定する。
# GitLabサーバ等 -> NAS へSSH
ssh <NAS管理者権限ユーザ>@<NASのIPアドレス>
# rootユーザへ昇格
sudo su -
# 作業ディレクトリ移動
cd /var/services/homes
# 作業前権限確認
ll | grep gitlab_backup
# -> drwx--x--x+ 2 gitlab_backup users 4096 Dec 30 17:57 gitlab_backup
# NAS上のユーザホームディレクトリの権限を700へ
chmod 700 /var/services/homes/gitlab_backup/
# 作業後権限確認
ll | grep gitlab_backup
# -> drwx------ 2 gitlab_backup users 4096 Dec 30 17:57 gitlab_backup次に、.sshディレクトリの作成を行う
# 作業ディレクトリ移動
cd /var/services/homes/gitlab_backup/
# .sshディレクトリ作成
mkdir -m 700 .ssh
# .ssh所有者変更
chown gitlab_backup:users .ssh
# 作業後確認
ll | grep ssh
# -> drwx------ 2 gitlab_backup users 4096 Dec 31 00:49 .ssh次に、authorized_keysファイルの作成を行う
# 作業ディレクトリ移動
cd /var/services/homes/gitlab_backup/.ssh
# authorized_keys作成
touch authorized_keys
# 権限変更
chmod 600 authorized_keys
# 所有者変更
chown gitlab_backup:users authorized_keys
# 作業後確認
ll
# -> -rw------- 1 gitlab_backup users 0 Dec 31 00:55 authorized_keys1-6. [Synology NAS] gitlab_backupユーザのSSH接続許可設定
NASで/etc/passwdを確認すると、
# cat /etc/passwd | grep gitlab
gitlab_backup:x:1044:100:gitlabバックアップ用ユーザ:/var/services/homes/gitlab_backup:/sbin/nologinのように、ユーザログインシェルがnologinとなっており、SSH接続でのユーザログインが拒否されています。なので、gitlab_backupユーザのシェルを/bin/shに変更してあげます。
# vimで編集
vim /etc/passwd
# (編集前)
# gitlab_backup:x:1044:100:gitlabバックアップ用ユーザ:/var/services/homes/gitlab_backup:/sbin/nologin
# (編集後)
# gitlab_backup:x:1044:100:gitlabバックアップ用ユーザ:/var/services/homes/gitlab_backup:/bin/sh1-7. 動作確認
ここまでの設定で、外部からNASへgitlab_backupユーザでSSH接続が可能となるはずなので、GitLabサーバ等から接続確認を実施する。
ssh gitlab_backup@<NASのIPアドレス>2. GitLabサーバのrsync設定
2-1. [GitLab] gitlab_backupユーザの作成
GitLabが動作するLinuxにも、バックアップ用のユーザgitlab_backupユーザを作成する。(名前はNASで作成したユーザ名と合わせる必要は無い)
adduser gitlab_backup
passwd gitlab_backup2-2. [GitLab] SSHキー生成
NASへはSSHキーによるrsync接続を実施するため、作成したgitlab_backupユーザでログインしてSSHキーを生成する
su - gitlab_backup
ssh-keygen -t rsa -b 4096 -C "gitlab_backup@synologynas"2-3. [GitLab] SSH公開鍵を登録
作成したSSH公開鍵を登録する。GitLabサーバから、ssh-copy-idコマンドで登録を実施する
ssh-copy-id -i ~/.ssh/id_rsa.pub gitlab_backup@<NASのIPアドレス>- 初回はパスワードを求められるので、nasで作成した
gitlab_backupユーザのパスワードを入力 - 成功すると、nasの
gitlab_backupユーザのホームディレクトリ配下の.ssh/authorized_keysに公開鍵が追加される
ここまできたら、GitLabサーバからNASへ、SSHキーによるSSH接続が可能となるので、動作確認する。
ssh -i ~/.ssh/id_rsa gitlab_backup@<NASのIPアドレス>2-4. [GitLab] rsyncの動作確認
(sshキーを用いた)SSH接続ができるようになると、sshキーを用いたrsyncが利用できるようになるということなので、動作確認を実施する。
rsync -avz --dry-run -e "ssh -i ~/.ssh/id_rsa" <転送元ファイル> gitlab_backup@<NASのIPアドレス>:/volume1/gitlab_backup/-a: アーカイブモード(パーミッションやタイムスタンプを保持)-v: 詳細表示モード-z: 転送時にデータを圧縮-e: リモートシェル(SSHなど)を指定--dry-run: 実際に転送せずシミュレーション
3. GitLabサーバのバックアップ設定
さて、ここまででGitLabサーバ->NASへのrsyncによるファイル転送が可能となったので、ここからはGitLabのバックアップ設定をしていく。
3-1. GitLabバックアップ設定
GitLabの設定ファイル/etc/gitlab/gitlab.rbを編集し、バックアップ設定を行う。
# バックアップの保存場所
gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
# バックアップ保持期間(7日間)
gitlab_rails['backup_keep_time'] = 604800 # 7日 = 604800秒変更を反映する。
gitlab-ctl reconfigure3-2. crontab編集
crontabを編集
crontab -e以下を追加
0 12 * * * /opt/gitlab/bin/gitlab-backup create && tar -czf /var/opt/gitlab/backups/gitlab-config-$(date +\%Y\%m\%d).tar.gz /etc/gitlab /etc/ssl /etc/gitlab/trusted-certs && rsync -avz -e "ssh -i /home/gitlab_backup/.ssh/id_rsa" /var/opt/gitlab/backups/ [email protected]:/volume1/gitlab_backup/ && rm -f /var/opt/gitlab/backups/*記載できたら、内容を確認する。
crontab -lこれで、「毎日PM12時にgitlabのバックアップを取得してNASに転送する」というのが実現された。
4. NASのgitlab_backupディレクトリのバージョン管理
このままだと、永遠にバックアップデータが溜まり続けてしまうので、世代管理を行う。
4-1. [Synology NAS] スクリプト作成
gitlab_backupユーザディレクトリにスクリプトを作成する。
# ディレクトリ作成
mkdir /var/services/homes/gitlab_backup/Scripts
# スクリプト作成
touch /var/services/homes/gitlab_backup/Scripts/clean_old_backups.shスクリプト内容は
#!/bin/bash
BACKUP_DIR="/volume1/gitlab_backup"
MAX_FILES=7
# バックアップファイルを古い順にリストアップし、指定数以上なら削除
ls -t $BACKUP_DIR | grep 'gitlab_backup' | tail -n +$(($MAX_FILES + 1)) | while read FILE; do
echo "Deleting old backup: $FILE"
rm -f $BACKUP_DIR/$FILE
done
# configバックアップファイルを古い順にリストアップし、指定数以上なら削除
ls -t $BACKUP_DIR | grep 'gitlab-config' | tail -n +$(($MAX_FILES + 1)) | while read FILE; do
echo "Deleting old backup config: $FILE"
rm -f $BACKUP_DIR/$FILE
doneスクリプトの実行権限付与
chmod +x clean_old_backups.sh4-2. [Synology NAS] タスクスケジューラへ登録
コントロールパネル > タスクスケジューラ > 作成 > 予約タスク > ユーザー指定のスクリプト から、作成したスクリプトを登録する。
実行ユーザはgitlab_backup

開始時刻はバックアップ開始が12時なので13時とか。

作成したスクリプトを指定する。

終わり
自動でバックアップが取れ始められて嬉しい。NASのIPアドレスが変更されたらGitLabサーバのcron設定変えないといけないのは忘れそう。ホスト名でアクセスできるようにした方がいいんかな?けれど、自宅でDNSサーバ立てるのも運用が面倒だしみんなどうしてるんだろう。