【AWS】サーバ間でファイルのリアルタイム同期を行う【rsync + xinetd + lsyncd】

概要

サーバを運用してきた人なら分かると思いますが、サーバとは突然死ぬものです。

例えサーバの稼働率が 99.99% のクラウドサービスを使っていたとしても、何かあった時のためにサーバは冗長化して構築するのが好ましいです。

今回、サーバにファイルを保存する(アップロードする)システムを作ることになりました。

サーバが死んでも、ファイルが見れなくならないようにしっかり冗長化したいと考えています。

ただし、複数のサーバにファイルをアップロードすると時間がかかってしまうので、1 つのサーバにファイルをアップロードして裏側で同期を取るシステムを作ろうと思います。

サーバ間ではファイルをリアルタイムで同期できるように rsync, xinetd, lsyncd と言うコマンドやデーモンプロセスを利用しました。

その時対応した内容をまとめます。

 

はじめに

rsync とは?

リモート・ローカルに関わらずディレクトリやファイルを高速にコピーできるプログラムです。

ローカルとリモート間のディレクトリ同期やバックアップによく使われます。

xinetd とは?

スーパーサーバと呼ばれるポート監視用のデーモンプログラムです。

あるポートに対してアクセスがあった場合、設定ファイルを元にポートに対応したサービスを起動することができます。

lsyncd とは?

あるディレクトリ以下のファイルにイベント(作成・更新・削除)が発生した場合、それを検知して即時にファイルの同期(デフォルトは rsync を使う)を行うことができるプログラムです。

 

対応手順

パッケージのインストール

標準レポジトリでは提供されていないパッケージ(lsyncd)もあるので、EPEL レポジトリを指定してインストールします。

$ sudo yum --enablerepo=epel install rsync xinetd lsyncd

rsync の設定

設定ファイル(rsyncd.conf)を作成します。

オプション参考:rsyncd.conf

$ sudo vim /etc/rsyncd.conf
#------------------
# GLOBAL PARAMETERS
#------------------
uid           = root
gid           = root
log file      = /var/log/rsyncd.log
pid file      = /var/run/rsyncd.pid
hosts allow   = (IPv4 パブリック IP)/32 # 複数指定する場合はカンマ区切り
hosts deny    = *
read only     = false # クライアントからのアップロードを許可
exclude       = *
include       = *.txt # txt ファイルだけの転送を許可
dont compress = *.gz *.tgz *.zip *.pdf *.sit *.sitx *.lzh *.bz2 *.jpg *.gif *.png

#------------------
# MODULE PARAMETERS
#------------------
[module1]
    comment = rsync test dir1
    path    = /tmp/rsync/test1/ # 同期を取りたいディレクトリ

[module2]
    comment = rsync test dir2
    path    = /tmp/rsync/test2/ # 同期を取りたいディレクトリ

ポート解放

AWS でインバウンドのルールの編集を行います。

サーバ間でファイル転送ができるように、rsync 用のポート873 番 を解放します。

f:id:kyamanak83:20170919134722p:plain

rsync の起動

rsync はデーモンモードで起動し、rsync サーバとして利用します。

# デーモンモードで起動します
$ sudo rsync --daemon --config /etc/rsyncd.conf

# 873 番ポートが rsync で動いていることを確認します
$ sudo lsof -i:873
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rsync   3049 root    4u  IPv4  13778      0t0  TCP *:rsync (LISTEN)
rsync   3049 root    5u  IPv6  13779      0t0  TCP *:rsync (LISTEN)

# rsync が起動したことを確認します
$ ps `cat /var/run/rsyncd.pid`
  PID TTY      STAT   TIME COMMAND
 3049 ?        Ss     0:00 rsync --daemon --config /etc/rsyncd.conf

xinetd の設定

xinetd で rsync 用のポート 873 番を監視するための設定変更を行います。

$ sudo vim /etc/xinetd.d/rsync
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#       allows crc checksumming etc.
service rsync
{
        disable = no # no に変更する
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}

xinetd の起動

システム起動時に自動起動するように chkconfig の設定を行います。

設定が完了したら xinetd を起動します。

$ sudo chkconfig xinetd on
$ sudo service xinetd start
xinetd を起動中:                                           [  OK  ]

rsync の動作確認

ファイルの同期を取りたい双方のサーバでここまでの作業が完了したら、ファイル転送の動作確認をします。

はじめに、同期を取りたいディレクトリに適当なファイルを作成して下さい。

ファイルを作成したら、以下のコマンドを実行して、ファイルが転送できるか確認して下さい。

# (IPv4 パブリック IP)は自分の転送先のサーバの IP を指定して下さい
$ sudo rsync -ahv --contimeout=5 /tmp/rsync/test1/* (IPv4 パブリック IP)::module1
sending incremental file list
file.txt # /tmp/rsync/test1 以下に作成した file.txt が転送された

sent 89 bytes  received 27 bytes  232.00 bytes/sec
total size is 0  speedup is 0.00 # 転送成功

lsyncd の設定

設定ファイル(lsyncd.conf)を作成します。

$ sudo vim /etc/lsyncd.conf
settings {
    logfile 	   = "/var/log/lsyncd.log",
    pidfile 	   = "/var/run/lsyncd.pid",
    statusFile 	   = "/var/log/lsyncd-status.log",
    statusInterval = 1, # ステータスの更新頻度(秒)
    delay          = 0, # rsync を呼び出す時間差
    nodaemon 	   = false # デーモンモードで起動する
}

sync {
    default.rsync,
    source = "/tmp/rsync/test1/",
    target = "(IPv4 パブリック IP)::module1",
    rsync = { # ファイルの Permission を引き継ぐ
	owner = true,
	group = true
    }
}

sync {
    default.rsync,
    source = "/tmp/rsync/test2/",
    target = "(IPv4 パブリック IP)::module2",
    rsync = { # ファイルの Permission を引き継ぐ
	owner = true,
	group = true
    }
}

lsyncd の起動

システム起動時に自動起動するように chkconfig の設定を行います。

設定が完了したら lsyncd を起動します。

$ sudo chkconfig lsyncd on
$ sudo service lsyncd start
lsyncd を起動中:                                           [  OK  ]

リアルタイム同期の動作確認

ファイル作成の同期

サーバ1 でファイルを作成します。

$ touch /tmp/rsync/test1/file.txt /tmp/rsync/test2/file.txt

サーバ2 で同期されたことを確認します。

$ tree /tmp/rsync/
/tmp/rsync/
├── test1
│   └── file.txt
└── test2
    └── file.txt

2 directories, 2 files

ファイル削除の同期

サーバ1 でファイルを削除します。

$ rm /tmp/rsync/test1/file.txt

サーバ2 で同期されたことを確認します。

$ tree /tmp/rsync/
/tmp/rsync/
├── test1
└── test2
    └── file.txt

2 directories, 1 file

双方向なので逆のパターンでも大丈夫です。

 

まとめ

サーバ間でファイルのリアルタイム同期を行う方法をまとめました。

以下の3ステップで簡単に導入することができます。

  1. rsync の設定・起動
  2. xinetd の設定・起動
  3. lsyncd の設定・起動

ちなみに『rsync の設定・起動』と『xinetd の設定・起動』が完了していれば、クーロンを起動して定期的にサーバ間でファイルをバックアップする仕組みにも使えます。

利用方法はたくさんあると思うので、是非、参考にしてみて下さい。