lsyncdでサーバ間のファイルを双方向に同期させる

ブログ

目次

はじめに

こんにちは。

最近サーバ構築系の案件がありまして、そちらでlsyncdを使ってファイルを同期させました。

分散型のサーバ構成でシステムを組む必要がありまして、それらの分散されたサーバで同一のファイルを同期させました。
今まで同期が必要な場面ではNFSを使っていました。NFSもすごく便利で好きなのですが、今回は色々と諸事情がありlsyncを使って同期しました。

(ちなみにlsyncの公式ってどこなんでしょうね。)

GitHub - lsyncd/lsyncd: Lsyncd (Live Syncing Daemon) synchronizes local directories with remote targets
Lsyncd (Live Syncing Daemon) synchronizes local directories with remote targets - lsyncd/lsyncd

lsyncについて基本的なこと

lsyncは”Live Sync daemon”という名前がついています。ただ恐らく、ファイル同期プログラムとして有名なrsyncのオマージュとして、「r」に対しての「l」を冠しているとおもいます。
「Copyright」と「Copy left」、「more」と「less」などは有名ですね。

lsync自体ではファイルの同期機能を使いません。実際の同期はrsyncなどのファイル転送のプログラムに任せ、lsyncではファイルの変更を検知しrsyncなどを呼び出します。
rsyncはファイル同士に更新があったかどうか、圧縮をどうするか、転送のスピードアップはどうするかなど、転送自体の多くの機能があります。
ただlsyncのオプションには「direct」という項目もありますので、lsync同士での通信も可能かと思います。

Page not found · GitHub Pages

今回採用した方法ではありませんが、最も基本的な使い方としてはlsyncはlsyncdが立っているサーバ側からファイルを転送します。
受け側から引き出すのではなく、送信側から送ります。
というのもファイル送信側のOSの機能を冠しして変更を検出するのでそういった形になっています。
ファイルを取り出すポーリング型ではなくて、ファイルを送り出すプッシュ型なモデルですね。

rsyncとsshとinetd

lsyncdのファイル転送で利用されるrsyncには、ssh越しに動作するモードとrsync自体がデーモンとして動作するモードがあります。
lsyncdは情報が豊富なため、このrsyncについての記述ではrsyncをデーモンとして動作させる紹介記事が多かったです。

http://saba.omnioo.com/note/1258/lsyncd-rsyncd%E3%81%A7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E5%90%8C%E6%9C%9F%E3%81%99%E3%82%8B-centos6/
lsyncd と rsync を使ってリアルタイムなサーバー間ファイル同期を実現する | レンタルサーバー・自宅サーバー設定・構築のヒント

ですが最近ではrsyncをデーモンとして動作させることは一般的ではなく、ssh越しにrsyncを動作させる方が一般的です。
rsyncはinet(xinet)と呼ばれるデーモン化ツールを使って動作させていました。
しかし10年ほど前からこのinetはあまり使わないようにしましょう、という風潮が広まって以降、特にrsyncはssh越しで使われることが多くなりました。
(ちょうど僕はそのころFreeBSD5あたりを使っていて、inetd関連が減ってきていました。もしかすると最近はxinetdが復権していたのかもしれませんが…)

lsyncdとrsync、sshでファイルの同期(rsyncdサーバは立てない) - There's an echo in my head
lsyncdはlinux上で動くファイルの更新を検知して処理を走らせるデーモンで、これとrsyncを組み合わせればファイルの更新があったときにリモートサーバとファイルを同期できる。 lsyncdとrsyncでぐぐるとrsyncdサーバを立て...

不要にrsyncのポートを待ち受ける必要もありませんし、sshは脆弱性のメンテナンスも多く信頼されたプロトコルです。
今回はssh+rsyncをlsyncdに使わせる、という方針で行きました。

インストールと設定など

環境はCentos7です。

コンフィグファイルなどを調整するので、lsyncdのインストール前に/etcのGit化(VCS化)ができるetckeeperを入れておくと便利です。

サーバの/etcを自動的にGitとかにコミットとかプッシュしてくれるetckeeperを使う - Qiita
はじめに インフラを担当しています。 一人が管理できるホストには限りがあるなと思っていて、補助ツールがなければ10台ぐらいが精一杯かと思っています。 補助ツールを使うことで100台ぐらいまでは行けるんじゃないかと思っていて、そのためのツール...

今回は双方向で同期させるので両方に同じような設定を行います。
ここでは一台だけの設定を紹介します。

$ sudo yum install -y lsyncd rsync

設定ファイルはデフォルトで/etc/lsyncd.confに入ります。
こちらを編集します。

デフォルトではこんな感じで入っています。

----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync, but executing moves through on the target.
--
-- For more examples, see /usr/share/doc/lsyncd*/examples/
--
-- sync{default.rsyncssh, source="/var/www/html", host="localhost", targetdir="/tmp/htmlcopy/"}

コメントはSQLとかと同じ--のようですね。
Luaとして書けるようです。

Lua - Wikipedia

今回は srv1.example.comというホストの /var/html から srv2の同じ場所に送ります。

settings {
        logfile    = "/var/log/lsyncd.log",
        statusFile = "/tmp/lsyncd.stat",
        statusInterval = 1,
    insist         = 1,
}
sync{
        default.rsync,
        delay = 0,
        source="/var/html",
        target="srv2.example.com:/var/html",
        delete="running",
        rsync  = {
                archive = true,
                links   = true,
                update  = true,
                verbose = true,
        rsh = "/bin/ssh -l www -i /home/www/.ssh/id_rsa"
        }
}

settingsブロックとsyncブロックに分かれています。
settingsではlsyncdの基本的な設定を、syncでは行いたい動作を記述します。
syncは複数の記述が可能です。

sync.rsync.rsh のところでrsyncを行うユーザ、秘密鍵を指定しています。
デフォルトではlsyncdをrootで動かしますので、そのままだとrsyncを動作させるユーザもrootになってしまいます。
これを上書きします。

テスト動作など

コンフィグファイルの記述が正しいかチェックを行います。
通常のlsyncdはデーモンとして動作させるのでCentOSではsystemctlを使って起動しますが、まずは手動で動作させてコンフィグチェックを行います。
lsyncdコマンドが存在しますのでそちらを呼び出します。

$ sudo lsyncd -nodaemon -log scarce /etc/lsyncd.conf

-nodaemonで対話モードとして、-log scarceでログを出力します。
最後の引数でコンフィグファイルの指定が必要です。

うまく行けばrsyncの同期ログが流れます。
だめな場合にはエラーが出ます。
特に初回起動時にはsshのフィンガープリント受け入れの対話が出るかもしれないです。

その場合には一度rootになってknown_hostsに追加しておきます。

$ sudo su
# ssh srv2.example.com
yes

ちなみにこのフィンガープリントを無視するオプションを昔から探しているのですが、未だに見つけられていません…。

うまく動作するようでしたらデーモンとして起動します。

$ sudo systemctl start lsyncd.service

また自動起動するようにしておきます。

$ sudo systemctl enable lsyncd.service

エラーが出ていないかチェックしておきます。

$ sudo systemctl status lsyncd.service

CentOS7からはsystemctlで発生したエラーはjournalという仕組みで保存されるようになりました。
以前は/var/log/messagesに書かれることが多かったですが、それを集約したようですね。
journalはjournalctlというコマンドで行います。
詳細オプションのxe、tail -fと同じ順次表示モードを付けて別ターミナルで表示しておくと便利です。

$ sudo journalctl -xef

思った以上にlsyncdが動かなくてログ表示が助かりました。

トラブルなど

監視するファイルが多すぎてエラーが発生していました。

$  sudo lsyncd -log scarce -nodaemon /etc/lsyncd.conf
10:06:59 Error: Terminating since out of inotify watches.
Consider increasing /proc/sys/fs/inotify/max_user_watches

max_user_watchesというシステム環境変数の値が足りないようでした。

下記の記事を参考に値を変更しておきます。

lsyncdで上限ファイル数を超えた時の対処策 - UNIX的なアレ
lsyncdで監視できる対象のファイル数は制限されています。lsyncdのlogに以下のようなlogが吐き出されていたら要注意です。 Fri Jan 22 14:11:51 2010: ERROR: Cannot add watch /fo...
$ cat /proc/sys/fs/inotify/max_user_watches
8192

$ sudo sh -c 'echo "fs.inotify.max_user_watches=1024000" >> /etc/sysctl.conf'

$ sudo sysctl -p
net.ipv4.conf.all.arp_notify = 1
net.ipv6.conf.all.disable_ipv6 = 1
fs.inotify.max_user_watches = 1024000

$ cat /proc/sys/fs/inotify/max_user_watches
1024000

まとめ

以上がlsyncを使った双方向ファイル同期についてでした。
nfsもv4が出てから高速化、安定化したかなと思いますが、もっと上のレイヤーで動くlsyncdはお手軽ですね。
ただちょっとパッケージが古い感があり、オプション周りでは苦労しました。
良い同期生活を送れると良いですね。

コメント

タイトルとURLをコピーしました