1. 程式人生 > >Git學習-->如何通過Shell腳本自動定時將Gitlab備份文件復制到遠程服務器?

Git學習-->如何通過Shell腳本自動定時將Gitlab備份文件復制到遠程服務器?

-c res git學習 number ssp 磁盤空間 symbol ask ger

一、背景

在我之前的博客 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備份文件復制到遠程服務器?