背景
2台のLinuxサーバーでファイル同期させて冗長化やバックアップに利用するメモです。
動作環境
- OS:Ubuntu Server 16.04LTS
- OS:Ubuntu Server 18.04LTS
- sshd
- rsync
- lsyncd
同期設定のポリシー
2台のサーバー間を双方向で同期する方法と、バックアップの様に片側同期する方法があります。
今回は後者の片側同期に設定します。
双方向同期の場合はファイル削除時の動作を設計時に考慮しないと思わぬデータ消失に繋がり注意が必要です。
rsyncサービスデーモン(rsyncd)
ネットで検索するとrsyncdを使用するページが出てきますが、その場合はサービスポートTCP 873番を経由します。
しかし昔ながらのIPアドレス範囲をallow/denyで制限したり、暗号化無しの平文パスワード利用と今時のセキュリティ的にはよくありません。
閉域網のセキュリティが確保された内部のサブネットで、転送速度のパフォーマンス重視の場合などで検討しましょう。今回は使用しません。
rsyncコマンドをsshd経由で暗号化して公開鍵認証した安全な経路が利用できますので、外部のインターネット経由したサーバー間でも安全な同期が可能です。
sshサービスデーモン(sshd)経由を利用するので一般的なsshd設定が利用可能です。
sshユーザー設定
各サーバーに適当なアカウント「rsync」を作成します。
ユーザーアカウントでシステムファイル操作のパーミッション権限はsudoで対応します。
$ sudo adduser rsync
sudoグループに追加します。
$ sudo gpasswd -a rsync sudo
「rsync」ユーザーに切り替えてパスフレーズ無しのssh鍵ペアを作成します。
コメントの-Cオプションにサーバーホスト名も付けておくと区別し易いね。
$ su rsync
$ ssh-keygen -t ed25519 -C "rsync@node1" -N ""
$ su rsync
$ ssh-keygen -t ed25519 -C "rsync@node2" -N ""
ssh鍵を互いのサーバーへ登録します。
方法は色々ありますがssh-copy-idコマンドが簡単。
$ ssh-copy-id -i .ssh/id_ed25519 rsync@node2
$ ssh-copy-id -i .ssh/id_ed25519 rsync@node1
実際にパスフレーズ無しの公開鍵認証で接続出来るか、互いのサーバーで確認します。
$ ssh -i .ssh/id_ed25519 rsync@node2
$ ssh -i .ssh/id_ed25519 rsync@node1
rsyncコマンドをsudo経由でパスワード入力無しで実行する設定(サーバー2 node2側)
$ sudo visudo
rsync ALL=(ALL) NOPASSWD: /usr/bin/rsync
パスフレーズ無しのssh鍵であってもsudoコマンド実行時にはアカウントのパスワード入力を要求されますので、特定コマンド(この場合はrsync)だけパスワード要求を無効化します。
これでrsyncコマンドをsudo経由で実行出来るので、ファイルの書き換え時にパーミッション制限でのエラーを回避出来ます。
lsyncサービスデーモン(lsyncd)設定
同期元サーバー1(node1)側へインストールして設定する。ちなみに双方向で同期する場合は両方へインストールします。
$ sudo apt-get install lsyncd
設定ファイルを作成します。
サンプルファイルが、「/usr/share/doc/lsyncd/examples/lsyncd.conf.lua」とかにありますので参考に。
settings = {
logfile = "/var/log/lsyncd.log",
statusFile = "/tmp/lsyncd.stat",
insist = 1,
statusInterval = 10
}
sync_base = {
default.rsync,
delete = running,
init = false,
rsync = {
archive = true,
rsync_path = "sudo /usr/bin/rsync",
rsh = "/usr/bin/ssh -i /home/rsync/.ssh/id_ed25519 -o StrictHostKeyChecking=no"
}
}
sync{ sync_base, source="/home/rsync/test1/", target="rsync@node2:/home/rsync/test1/"}
sync{ sync_base, source="/etc/test2/", target="rsync@node2:/etc/test2/"}
設定オプションは以下の様になります。
- statusInterval:インターバル・デフォルト10秒
- delete = running:同期時のみ削除可
- init = false:起動時は同期を反映しない
- archive = true:rsyncの-aオプションと同等
- rsync_path = "sudo /usr/bin/rsync":rsyncコマンドをsudo経由で実行
最後のsyncの2行で監視するディレクトリと同期先を2箇所指定しています。複数ある場合は同じ様に追加設定します。
lsyncサービスデーモン(lsyncd)の再起動
$ sudo systemctl restart lsyncd
動作確認
適当な空ファイルを作成して、サーバー2(node2)側に反映するか確認してみます。
$ touch /home/rsync/test1/test1.txt
$ ls -l /home/rsync/test1/
sudo経由なのでシステムファイルも同期出来ます。
$ sudo touch /etc/test2/test2.txt
$ ls -l /etc/test2/
動作検証にログファイルが確認出来ます。
$ sudo tail /var/log/lsyncd.log