Git學習-->如何通過Shell腳本自動定時將Gitlab備份文件復制到遠程服務器?
一、背景
在我之前的博客 git學習——> Gitlab如何進行備份恢復與遷移? (地址:http://blog.csdn.net/ouyang_peng/article/details/77070977) 裏面已經寫清楚了如何使用Gitlab自動備份功能。
但是之前的備份功能只是備份到Gitlab服務運行的那臺服務器上,如果哪一天那臺服務器的磁盤損壞了的話,數據無法取出,那麽對於公司來說是一匹無法想象的損失,因為
代碼是公司的重要資產,需要以防萬一。
代碼是公司的重要資產,需要以防萬一。
代碼是公司的重要資產,需要以防萬一。
因此我們得做好代碼的備份工作,因此除了每天在Gitlab那臺服務器上自動備份之外,還需要將每天的備份文件copy到另外一臺文件備份服務器上,已達到雙保險的要求。
二、服務器密鑰配對,取消scp傳輸密碼限制
遠程手動備份數據費時費力且不及時。最好的方法就是通過腳本實現遠程自動互備。但遠程無論是通過SSH登陸,還是通過scp拷貝文件都需要輸入密碼。為了克服這個問題,首先需要實現不需要密碼的SSH登陸,這樣就可以使用 rsync,scp,rexec等命令來做的遠程備份了。
前提:本地服務器:A, 遠程服務器:B
2.1 生成密鑰對
假設A,B兩服務器,現在需要在A機上用root登陸B機,而不需要輸入密碼。那我們可按照下面的步驟來做:
2.1.1 在本地服務器A上生成rsa證書
在本地服務器A上生成rsa證書,運行命令:
ssh-keygen -t rsa
完整運行如下所示:
root@ubuntu4146:/data/gitlabData/backups# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
50:75:d3:53:d7:d8:98:1f:e7:9f:43:19:31:0d:e1:c4 root@ubuntu4146
The key‘s randomart image is:
+--[ RSA 2048]----+
| ... oo+@*|
| . . +EoB|
| . .+=|
| . oo|
| S . o|
| o.|
| .|
| |
| |
+-----------------+
root@ubuntu4146:/data/gitlabData/backups#
1、生成的過程中提示輸入密鑰對保存位置,直接回車,接受默認值就行了。
2、因為之前已經有/root/.ssh/id_rsa 文件存在,因此提示你是否覆蓋,輸入y表示覆蓋
3、接著會提示輸入一個密碼,直接回車,讓它空著。當然,也可以輸入一個密碼。
4、接著輸入確認密碼,輸入完之後,回車密鑰對就生成完了。
在/root/.ssh下生成id_rsa 和 id_rsa.pub 兩個文件,
其中公共密鑰保存在 /root/.ssh/id_rsa.pub,私有密鑰保存在/root/.ssh/id_rsa。
2.1.2 在本地服務器A上cp生成rsa公鑰證書
然後在/root/.ssh下復制備份一份id_rsa.pub 命名為 id_rsa.pub.A,以便拷貝到遠程服務器B。
執行cp命令復制
cp id_rsa.pub id_rsa.pub.A
2.2 cp生成rsa公鑰證書到遠程服務器B
使用scp命令進行遠程復制,將A機生成的id_rsa.pub.A拷貝到遠程服務器B的/root/.ssh目錄下
root@ubuntu4146:~/.ssh# scp /root/.ssh/id_rsa.pub.A root@遠程服務器ip:/root/.ssh/
root@遠程服務器ip‘s password:
id_rsa.pub.A
這裏使用scp命令需要輸入密碼,當我們把下面的第三步執行完畢之後,以後本地服務器A使用scp命令復制文件到遠程服務器B的話,就不需要再次輸入密碼。
三、密鑰配對
3.1 創建authorized_keys文件
當第二步將服務器A上的id_rsa.pub.A 文件copy到了服務器B的目錄/root/.ssh下之後截圖如下:
現在我們在 B 的/root/.ssh下創建authorized_keys文件,使用如下命令
touch authorized_keys
3.2 將id_rsa.pub.A文件內容追加到authorized_keys 文件中
通過 cat 命令 把id_rsa.pub.A 追寫到 authorized_keys 文件中,命令依次如下:
cat id_rsa.pub.A >> authorized_keys
3.3 修改authorized_keys文件的權限
執行如下命令,修改authorized_keys文件的權限
chmod 400 authorized_keys
authorized_keys文件的權限很重要,如果設置為777,那麽登錄的時候,還是需要提供密碼的。
3.4 測試
測試服務器A使用scp命令復制文件到服務器B是否還需要密碼
在服務A上,再次使用剛才的命令,發現已經可以不需要輸入密碼,如下所示:
四、創建Shell定時遠程備份腳本
4.1 在本地服務器A上創建定時遠程備份腳本
本地服務器A上創建定期備份腳本auto_backup_to_remote.sh,腳本內容如下
#!/bin/bash
# gitlab 機房備份路徑
LocalBackDir=/data/gitlabData/backups
# 遠程備份服務器 gitlab備份文件存放路徑
RemoteBackDir=/root/gitlabDataBackup
# 遠程備份服務器 登錄賬戶
RemoteUser=root
# 遠程備份服務器 IP地址
RemoteIP=(你的遠程服務器地址)請自己修改
#當前系統日期
DATE=`date +"%Y-%m-%d"`
#Log存放路徑
LogFile=$LocalBackDir/log/$DATE.log
# 查找 本地備份目錄下 時間為60分鐘之內的,並且後綴為.tar的gitlab備份文件
BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -60 -name ‘*.tar*‘)
#新建日誌文件
touch $LogFile
#追加日誌到日誌文件
echo "Gitlab auto backup to remote server, start at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile
echo "---------------------------------------------------------------------------" >> $LogFile
# 輸出日誌,打印出每次scp的文件名
echo "---------------------The file to scp to remote server is: $BACKUPFILE_SEND_TO_REMOTE-------------------------------" >> $LogFile
#備份到遠程服務器
scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP:$RemoteBackDir
#追加日誌到日誌文件
echo "---------------------------------------------------------------------------" >> $LogFile
因為到時候,我們會將該定時遠程備份腳本auto_backup_to_remote.sh執行的時間,放到Gitlab自動備份腳本auto_backup.sh之後的一小時之內,因此我們只需要每次執行遠程備份腳本auto_backup_to_remote.sh的時候,只需要cp一個小時之內的生成的新的Gitlab備份文件。
4.2 修改定時遠程備份腳本auto_backup_to_remote.sh的權限
要執行腳本文件,需要修改定時遠程備份腳本auto_backup_to_remote.sh的權限
chmod 777 auto_backup_to_remote.sh
4.3 手動執行腳本
現在為了驗證腳本是否可以正常運行,我們需要手動執行腳本。
如上圖所示,因為最後一次Gitlab備份時間為淩晨2點,而現在已經是下午3點半左右,因此我們需要修改腳本的查詢條件。
將查詢條件從 本地備份目錄下 時間為60分鐘之內的,並且後綴為.tar的gitlab備份文件
# 查找 本地備份目錄下 時間為60分鐘之內的,並且後綴為.tar的gitlab備份文件
BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -1000 -name ‘*.tar*‘)
修改為 本地備份目錄下 時間為1000分鐘之內的,並且後綴為.tar的gitlab備份文件
# 查找 本地備份目錄下 時間為1000分鐘之內的,並且後綴為.tar的gitlab備份文件
BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -1000 -name ‘*.tar*‘)
先在終端執行find命令,看是否能夠正常查找出我們要scp到遠程服務器的Gitlab備份文件
root@ubuntu4146:/data/gitlabData/backups# find /data/gitlabData/backups -type f -mmin -1000 -name ‘*.tar*‘
/data/gitlabData/backups/1502906429_2017_08_17_9.4.3_gitlab_backup.tar
將定時遠程備份腳本auto_backup_to_remote.sh修改完畢之後,我們試著手動執行該腳本,看是否能夠正常運行。
執行命令
root@ubuntu4146:/data/gitlabData/backups# ./auto_backup_to_remote.sh
執行該腳本文件,在2分鐘之內就將最後一次的Gitlab備份文件scp到了遠程服務器B
root@ubuntu4146:/data/gitlabData/backups# ./auto_backup_to_remote.sh
1502906429_2017_08_17_9.4.3_gitlab_backup.tar 100% 1337MB 11.2MB/s 01:59
我們切換到遠程服務器B,查看剛才從服務器A 通過scp命令復制過來的Gitlab備份文件,如下所示:
[root@xtgl207940 .ssh]# cd /root/gitlabDataBackup/
[root@xtgl207940 gitlabDataBackup]# ll
總用量 1369100
-rw-------. 1 root root 1401958400 8月 17 15:36 1502906429_2017_08_17_9.4.3_gitlab_backup.tar
[root@xtgl207940 gitlabDataBackup]#
至此,從服務器A復制備份文件到服務器B的腳本正常運行,但是如果每次都這樣來手動觸發腳本的話,太麻煩,因此我們需要定時執行腳本。
五、定時執行腳本
5.1 編輯/etc/crontab 文件
即vi /etc/crontab,然後添加相應的任務。
#編輯 /etc/crontab
vi /etc/crontab
可以看到,這裏有我們之前寫好的定期淩晨2點執行Gitlab本機備份的定時任務
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don‘t have to run the `crontab‘
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
# edited by ouyang 2017-8-11 添加定時任務,每天淩晨兩點,執行gitlab備份
0 2 * * * root /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1
#也可以按照如下所示的方法,定時執行 auto_backup.sh腳本,腳本內容就填寫: /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1
#0 2 * * * root /data/gitlabData/backups/auto_backup.sh -D 1
現在我們在上面的定時任務後面,再添加一個執行復制剛備份好的Gitlab備份文件到服務器B的腳本任務。如下所示:
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨三點,執行gitlab備份到遠程服務器
0 3 * * * root /data/gitlabData/backups/auto_backup_to_remote.sh
5.2 重啟cron服務
編寫完 /etc/crontab 文件之後,需要重新啟動cron服務
#重新加載cron配置文件
sudo /usr/sbin/service cron reload
#重啟cron服務
sudo /usr/sbin/service cron restart
實際運行如下:
root@ubuntu4146:/data/gitlabData/backups# sudo /usr/sbin/service cron reload
root@ubuntu4146:/data/gitlabData/backups# sudo /usr/sbin/service cron restart
cron stop/waiting
cron start/running, process 47631
5.3 測試自動化腳本
為了能夠測試,該腳本是否能夠在指定時間的時候,真的能夠自動執行,我們將時間修改為15:55分。修改如下:
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨三點,執行gitlab備份到遠程服務器
55 15 * * * root /data/gitlabData/backups/auto_backup_to_remote.sh
然後重啟cron服務
#重新加載cron配置文件
sudo /usr/sbin/service cron reload
#重啟cron服務
sudo /usr/sbin/service cron restart
現在時間是15:58分,我們去查看生成的log文件,可以看到在15:55分的時候,腳本正常定時執行了
Gitlab auto backup to remote server, start at 2017-08-17 15:55:01
---------------------------------------------------------------------------
---------------------The file to scp to remote server is: /data/gitlabData/backups/1502906429_2017_08_17_9.4.3_gitlab_backup.tar-------------------------------
---------------------------------------------------------------------------
Gitlab auto backup to remote server, end at 2017-08-17 15:57:00
切換到遠程服務器B,查看從服務器Acopy過來的Gitlab備份文件
通過測試,可以發現定時任務也正常執行了,因此我們可以將時間改為淩晨3點來復制Gitlab備份文件到遠程服務器B。
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨三點,執行gitlab備份到遠程服務器
0 3 * * * root /data/gitlabData/backups/auto_backup_to_remote.sh
六、定時刪除遠程服務器上的備份文件
通過如上圖所示,每個Gitlab備份文件都很大,都有1G左右的大小。因此每天備份一次,過不了多久的話,備份服務器B上的磁盤空間可能就會被Gitlab備份文件占用完。
因此我們需要定期清理備份文件,清理的時候我們可以自己定義,這裏我們規定:
備份文件超過30天的都自動刪除掉。
為了實現這個功能,我們需要在遠程服務器B上編寫腳本來清理過期的備份文件。
6.1 創建定期刪除過期的備份文件的腳本
創建定期刪除過期的備份文件的腳本auto_remove_old_backup.sh
[root@xtgl207940 gitlabDataBackup]# touch auto_remove_old_backup.sh
6.2 編寫腳本auto_remove_old_backup.sh
vi auto_remove_old_backup.sh
腳本內容如下 :
#!/bin/bash
# 遠程備份服務器 gitlab備份文件存放路徑
GitlabBackDir=/root/gitlabDataBackup
# 查找遠程備份路徑下,超過30天 且文件後綴為.tar 的 Gitlab備份文件 然後刪除
find $GitlabBackDir -type f -mtime +30 -name ‘*.tar*‘ -exec rm {} \;
6.3 手動執行auto_remove_old_backup.sh腳本
修改auto_remove_old_backup.sh腳本權限為777
chmod 777 auto_remove_old_backup.sh
- 1
如上圖所示,目前備份服務器上,只有一個8月17日15:56分copy過來的Gitlab備份文件,為了能夠測試我們的腳本是否正常運行,我們新建幾個7月份的文件,如下所示:
使用touch命令,創建指定時間的 test.tar 文件
[root@xtgl207940 gitlabDataBackup]# touch -t 201707011230 test1.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707021230 test2.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707031230 test3.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707041230 test4.tar
[root@xtgl207940 gitlabDataBackup]# ll
總用量 1369104
-rw-------. 1 root root 1401958400 8月 17 15:56 1502906429_2017_08_17_9.4.3_gitlab_backup.tar
-rwxrwxrwx. 1 root root 279 8月 17 16:24 auto_remove_old_backup.sh
-rw-r--r--. 1 root root 0 7月 1 12:30 test1.tar
-rw-r--r--. 1 root root 0 7月 2 12:30 test2.tar
-rw-r--r--. 1 root root 0 7月 3 12:30 test3.tar
-rw-r--r--. 1 root root 0 7月 4 12:30 test4.tar
[root@xtgl207940 gitlabDataBackup]#
這樣我們就創建了4個7月1日到7月4日的的test1.tar、test2.tar、test3.tar、test4.tar
現在我們手動來執行我們的auto_remove_old_backup.sh腳本
[root@xtgl207940 gitlabDataBackup]# ./auto_remove_old_backup.sh
[root@xtgl207940 gitlabDataBackup]# ll
總用量 1369104
-rw-------. 1 root root 1401958400 8月 17 15:56 1502906429_2017_08_17_9.4.3_gitlab_backup.tar
-rwxrwxrwx. 1 root root 279 8月 17 16:24 auto_remove_old_backup.sh
[root@xtgl207940 gitlabDataBackup]#
對比執行auto_remove_old_backup.sh腳本前後,我們發現超過30天的,並且以.tar後綴結尾的文件都被刪除了,腳本正常。
七、定時執行刪除腳本
7.1 編輯/etc/crontab 文件
即vi /etc/crontab,然後添加相應的任務。
#編輯 /etc/crontab
vi /etc/crontab
然後編寫定時任務
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# 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
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨4點,執行刪除過期的Gitlab備份文件
0 4 * * * root /root/gitlabDataBackup/auto_remove_old_backup.sh
7.2 重啟crond服務
寫完 /etc/crontab 文件之後,需要重新啟動cron服務,因為遠程備份服務器是Center OS 和之前的Gitlab服務器 Ubuntu 有點不一樣,所以重啟cron命令有所不同。
#重新加載cron配置文件
sudo service crond reload
#重啟cron服務
sudo service crond restart
7.3 測試定期刪除任務
為了測試定期刪除任務,現在時間是16:35,我們將腳本執行時間設置為16:40分,如下所示
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨4點,執行刪除過期的Gitlab備份文件
40 16 * * * root /root/gitlabDataBackup/auto_remove_old_backup.sh
然後重啟cron服務,超過16點40分之後我們再查看過期的.tar文件是否被刪除
[root@xtgl207940 gitlabDataBackup]# touch -t 201707011230 test1.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707021230 test2.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707031230 test3.tar
[root@xtgl207940 gitlabDataBackup]# touch -t 201707041230 test4.tar
[root@xtgl207940 gitlabDataBackup]# ll
總用量 1369104
-rw-------. 1 root root 1401958400 8月 17 15:56 1502906429_2017_08_17_9.4.3_gitlab_backup.tar
-rwxrwxrwx. 1 root root 279 8月 17 16:24 auto_remove_old_backup.sh
-rw-r--r--. 1 root root 0 7月 1 12:30 test1.tar
-rw-r--r--. 1 root root 0 7月 2 12:30 test2.tar
-rw-r--r--. 1 root root 0 7月 3 12:30 test3.tar
-rw-r--r--. 1 root root 0 7月 4 12:30 test4.tar
[root@xtgl207940 gitlabDataBackup]# vi /etc/
[root@xtgl207940 gitlabDataBackup]# vi /etc/crontab
[root@xtgl207940 gitlabDataBackup]# sudo service crond reload
Redirecting to /bin/systemctl reload crond.service
[root@xtgl207940 gitlabDataBackup]# sudo service crond restart
Redirecting to /bin/systemctl restart crond.service
[root@xtgl207940 gitlabDataBackup]# ll
總用量 1369104
-rw-------. 1 root root 1401958400 8月 17 15:56 1502906429_2017_08_17_9.4.3_gitlab_backup.tar
-rwxrwxrwx. 1 root root 279 8月 17 16:24 auto_remove_old_backup.sh
[root@xtgl207940 gitlabDataBackup]#
如上所示,我們修改定時執行任務的時間後,刪除任務正常執行,因此我們時間修改回淩晨4點刪除過期備份文件。
# edited by ouyang 2017-8-17 添加定時任務,每天淩晨4點,執行刪除過期的Gitlab備份文件
0 4 * * * root /root/gitlabDataBackup/auto_remove_old_backup.sh
Git學習-->如何通過Shell腳本自動定時將Gitlab備份文件復制到遠程服務器?