CentOS7 下使用 rsync+sersync 配置檔案自動同步

fivenull發表於2019-11-09

我們平時上傳程式碼,可以通過ftpsftp等將檔案上傳至伺服器,耗時耗力,而且很容易出錯。如果伺服器數量少還好,一但伺服器數量增加,壓力可想而知。

這個時候我們可以使用各種工具進行檔案同步,方法很多,這裡推薦大家使用rsync+sersync進行檔案同步,使用git進行版本控制,本地開發好後提交程式碼到線上環境,然後通過git提供的鉤子自動推送程式碼,rsync+sersync自動監聽差異化檔案,同步至各個伺服器(git可以使用私有git伺服器、gogs、gitlab等,gogs搭建將單獨寫一篇部落格)。

這裡使用伺服器A和伺服器B進行介紹,我們的目的是將A伺服器指定的目錄自動同步到B伺服器指定的目錄。

使用rsync+sersync的背景故事
擼了快 3 年的 Laravel 了,儘量這周分享本人使用的多臺伺服器叢集部署方案

配合gogos,使用 Docker 部署版本控制工具 Gogs
,實現自動化部署。

rsynclinux下同步檔案的一個高效演算法,用於同步更新兩處計算機的檔案和目錄,並適當利用查詢檔案中的不同塊以減少資料傳輸。rsync的主要特點就是增量傳輸,只對變更的部分進行傳輸。

sersync利用inotifyrsync對伺服器進行實時同步,其中inotify用於監控檔案系統事件,其優點是隻對檔案不同的部分進行操作,所以其優勢大大超過使用掛接檔案系統的方式進行映象同步。

關閉伺服器selinux

$ vi /etc/selinux/config #編輯防火牆配置檔案
#SELINUX=enforcing #註釋掉  
#SELINUXTYPE=targeted #註釋掉 
SELINUX=disabled #增加  
:wq!  #儲存,退出

然後重啟伺服器生效

B伺服器安裝rsync

$ yum -y install rsync
$ systemctl start rsyncd.service #啟動rsync服務
$ systemctl enable rsyncd.service #將rsync服務 加入開機自啟

檢查是否已經成功啟動,使用ps命令

$ ps -ef | grep rsync

編輯B伺服器rsync配置檔案

$ vim /etc/rsyncd.conf
log file = /var/log/rsyncd.log #日誌檔案位置,啟動rsync後自動產生這個檔案,無需提前建立
#pid file = /var/run/rsyncd.pid #pid檔案的存放位置
lock file = /var/run/rsync.lock #支援max connections引數的鎖檔案
secrets file = /etc/rsync.pass #使用者認證配置檔案,裡面儲存使用者名稱稱和密碼,後面會建立這個檔案
uid = root #設定rsync執行許可權為root
gid = root #設定rsync執行許可權為root
use chroot = no #預設為true,修改為no,增加對目錄檔案軟連線的備份
max connections = 1200 #最大連線數
timeout = 600 #設定超時時間

[book]   #自定義名稱
path = /data/book/  #rsync服務端資料目錄路徑
comment = book  #模組名稱與[book]自定義名稱相同
port=873  #預設埠
read only = no  #設定rsync服務端檔案為讀寫許可權
list = no #不顯示rsync服務端資源列表
auth users = bookuser  #執行資料同步的使用者名稱,可以設定多個,用英文狀態下逗號隔開
hosts allow = A伺服器IP  #允許進行資料同步的客戶端IP地址,可以設定多個,用英文狀態下逗號隔開
hosts deny = 192.168.0.1 #禁止資料同步的客戶端IP地址,可以設定多個,用英文狀態下逗號隔開

建立使用者認證檔案

 $ vi /etc/rsync.pass

設定使用者名稱和密碼,使用者名稱和密碼之間以英文冒號分隔

bookuser:123456

設定檔案許可權

$ chmod 600 /etc/rsyncd.conf  #設定檔案所有者讀取、寫入許可權
$ chmod 600 /etc/rsync.pass  #設定檔案所有者讀取、寫入許可權

重啟rsync

$ systemctl restart rsyncd

防火牆開啟873埠

centos7預設是firewall,如果防火牆是iptable,對應更換即可

$ firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="A伺服器IP" port protocol="tcp" port="873" accept" #開放埠 
$ systemctl restart firewalld #重啟防火牆
$ firewall-cmd --list-all #檢視規則是否生效

A伺服器安裝rsync

參照B伺服器安裝rsync

A伺服器建立密碼認證檔案

$ vi /etc/passwd.txt  #編輯檔案,新增以下內容

123456 #密碼 ,B伺服器裡設定的密碼

:wq! #儲存退出

$ chmod 600 /etc/passwd.txt #設定檔案許可權,只設定檔案所有者具有讀取、寫入許可權即可

到此,rsync已經配置完畢

測試A、B伺服器之間同步

$ rsync -avH --port=873 --progress --delete  /www/data/  bookuser@B伺服器IP::book --password-file=/etc/passwd.txt  #在A伺服器下執行

如果出現連線失敗,基本是埠問題,檢查阿里雲安全組埠是否開啟\
成功的話,見下圖

evernotecid://97CFF20F-9983-4C0A-BC5A-6B2E3E6658E1/appyinxiangcom/15428497/ENResource/p438
centos7下使用rsync+sersync配置檔案自動同步

安裝sersync

連結:https://pan.baidu.com/s/1GcIlOIsyM8-E1INpQ...

提取碼:p0df

解壓檔案

$ tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz  #解壓
$ mv GNU-Linux-x86  /usr/local/sersync  #移動目錄到/usr/local/sersync

修改inotify預設引數(inotify預設核心引數值太小)

$ vi /etc/sysctl.conf #新增以下程式碼

fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535

:wq! #儲存退出

配置sersync

$ cd  /usr/local/sersync #進入sersync安裝目錄
$ cp confxml.xml confxml.xml-back  #備份原檔案
$ vi confxml.xml  #編輯,修改下面的程式碼
<?xml version="1.0" encoding="ISO-8859-1"?>
    <head version="2.5">
        <host hostip="localhost" port="8008"></host>
        <debug start="false"/>
        <fileSystem xfs="false"/>
        <filter start="false">
            <exclude expression="(.*)\.svn"></exclude>
            <exclude expression="(.*)\.gz"></exclude>
            <exclude expression="^info/*"></exclude>
            <exclude expression="^static/*"></exclude>
        </filter>
        <inotify>
            <delete start="true"/>
            <createFolder start="true"/>
            <createFile start="false"/>
            <closeWrite start="true"/>
            <moveFrom start="true"/>
            <moveTo start="true"/>
            <attrib start="false"/>
            <modify start="false"/>
        </inotify>
        <sersync>
            <localpath watch="/data/book">
                <remote ip="192.168.1.200" name="book"/>
                <!--<remote ip="192.168.8.40" name="tongbu"/>-->
            </localpath>
            <rsync>
                <commonParams params="-artuz"/>
                <auth start="true" users="bookuser" passwordfile="/etc/passwd.txt"/>
                <userDefinedPort start="false" port="873"/><!-- port=873 -->
                <timeout start="false" time="100"/><!-- timeout=100 -->
                <ssh start="false"/>
            </rsync>
            <failLog path="/tmp/rsync_fail_log.sh"timeToExecute="60"/><!--default every 60mins execute once-->
            <crontab start="true" schedule="600"><!--600mins-->
                <crontabfilter start="false">
                    <exclude expression="*.php"></exclude>
                    <exclude expression="info/*"></exclude>
                </crontabfilter>
            </crontab>
            <plugin start="false" name="command"/>
        </sersync>
        <plugin name="command">
            <param prefix="/bin/sh" suffix="" ignoreError="true"/>  <!--prefix /opt/tongbu/mmm.sh suffix-->
            <filter start="false">
                <include expression="(.*)\.php"/>
                <include expression="(.*)\.sh"/>
            </filter>
        </plugin>
        <plugin name="socket">
            <localpath watch="/data/book">
                <deshost ip="192.168.138.20" port="8009"/>
            </localpath>
        </plugin>
        <plugin name="refreshCDN">
            <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
                <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
                <sendurl base="http://pic.xoyo.com/cms"/>
                <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
            </localpath>
        </plugin>
    </head>

引數說明:

<localpath watch="/data/book">  #源伺服器同步目錄
<remote ip="192.168.1.200" name="book"/> 
remote ip="23.225.218.182":  #目標伺服器ip,每行一個 
name="book":   #目標伺服器rsync同步目錄模組名稱
<auth start="true" users="bookuser" passwordfile="/etc/passwd.txt"/>
start="true"  #設定為true,每隔600分鐘執行一次全盤同步
users="bookuser": #目標伺服器rsync同步使用者名稱
passwordfile="/etc/passwd.txt": #目標伺服器rsync同步使用者的密碼在源伺服器的存放路徑
failLog path="/tmp/rsync_fail_log.sh"  #指令碼執行失敗日誌記錄

手動測試執行同步命令

/usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/confxml.xml

執行後,命令列輸出:
centos7下使用rsync+sersync配置檔案自動同步

檢視execute,複製程式碼 cd xxxx .txt 手動執行一遍,無誤後,基本可以確定成功
如果修改了配置檔案,需要殺掉之前的近程再執行上述程式碼

$ killall sersync2 #殺掉全部近程

設定sersync監控開機自動執行

$ vi /etc/rc.d/rc.local  #編輯,在最後新增一行

/usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/confxml.xml  #設定開機自動執行指令碼

:wq!  #儲存退出

如果不起作用的話\
進入 /etc/init.d 目錄,建立指令碼sercync.sh\
編輯內容

#!/bin/bash
 # chkconfig: 2345 10 90
 # description: resind
 /usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/confxml.xml 

然後賦予執行許可權

$ chmod  +x  sersync.sh

將指令碼新增到系統服務

$ chkconfig --add  sersync.sh

設定開機自啟動:

$ chkconfig  sersync.sh

至此,檔案自動同步部署完成

附錄:rsync常見問題及解決辦法(IP以10.10.10.10代替)

錯誤一:
password file must not be other-accessible
continuing without password file
Password:
rsync客戶端路徑是否寫錯,許可權設定不對,需要再次輸入密碼,客戶端和服務端的密碼檔案都應該是600的許可權才可以

錯誤二:
@ERROR: Unknown module ‘bak’
rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver= 3.0.3]
服務端server的配置中的[bak]名字和客戶端client的10.10.10.10::bak不符

錯誤三:
rsync: failed to connect to 10.10.10.10: Connection timed out (110)
rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.6]
檢查服務端server服務是否正常啟動,檢查埠防火牆,iptables開啟873埠
如果服務端是windows server則在防火牆入站規則中增加873埠
如果服務端是Linux則先檢查服務是否啟動#ps aux | grep rsync
然後開啟873埠#iptables -A INPUT -p tcp --dport 873 -j ACCEPT開啟873埠
附:
安裝rsync yum install rsync
啟動服務/usr/bin/rsync --daemon
啟動服務錯誤failed to create pid file /var/rsyncd.pid: File exists
看看提示服務錯誤的路徑(這個路徑不一定就是這個,看自己的報錯路徑)這裡是/var/rsyncd.pid所以
rm -rf /var/rsyncd.pid;再重新啟動Rsync服務
此時在看一下ps aux | grep rsync啟動成功

錯誤四:
@ERROR: access denied to gmz88down from unknown (10.10.10.10)
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]
看看是不是服務端server hosts allow限制了IP,把這裡的IP加入到服務端server的hosts allow白名單中,windows rsync不能寫多個allow,可以在一個allow中加多個IP,例:hosts allow=10.10.10.10 20.20.20.20

錯誤五:
@ERROR: chdir failed
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]
服務端server的目錄不存在或者沒有許可權(要同步的那個檔案路徑),安裝windows rsync時候會建立一個SvcCWRSYNC使用者,這個使用者對要拷貝的目錄沒有許可權,方法一,將這個使用者給許可權加入到目錄中,方法二,修改這個使用者隸屬於的組,修改後要在管理中重啟服務

錯誤六:
rsync error: error starting clie
nt-server protocol (code 5) at main.c(1524) [Receiver= 3.0.7 ]
/etc/rsyncd.conf配置檔案內容有錯誤,檢查下配置檔案

錯誤七:
rsync: ch
own "" failed: Invalid argument (22)
許可權無法複製,去掉同步許可權的引數即可

錯誤八:
@ERROR: auth failed on module bak
rsync error: error starting client-server protocol (code 5) at main.c(1530) [receiver=3.0.6]
密碼錯誤或伺服器上是否有bak模組

錯誤九:
rsync: connection unexpectedly closed (5 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]
模組read only = no設定為no false

錯誤十:
@ERROR: invalid uid nobody
rsync error: error starting client-server protocol (code 5) at main.c(1503) [sender=3.0.6]
設定
uid =0
gid = 0

錯誤十一:
rsync: failed to connect to 10.10.10.10: No route to host (113)
rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.6]
防火牆原因

錯誤十二:
rsync: read error: Connection reset by peer (104)
rsync error: error in rsync protocol data stream (code 12) at io.c(759) [receiver=3.0.6]
/etc/rsyncd.conf配置檔案不存在

錯誤十三:
rsync: Failed to exec ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(84) [receiver=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in IPC code (code 14) at io.c(600) [receiver=3.0.6]
需要在客戶端安裝yum install -y openssh-clients即可

相關文章