EC2 に Lsyncd を設定して、 Concrete CMS の Config ファイルを片方同期


1台目 (A) の EC2 から 2台目 (B) の EC2 にほぼリアルタイムでファイルを同期することができる lsyncd の設定手順をメモりました。

SSH を介して使う方法です。

Concrete CMS では設定ファイル、言語ファイル、 ORM Proxies ファイルをサーバー側で生成します。冗長化構成にしたときに、それらを他のサーバーにも飛ばさないといけないので、Lsyncd で解決するようにしました。

双方向同期はリスクが高いので今回はやめておきました。

(ちなみに、コードのデプロイは [Deployer](https://deployer.org/) を使っているので一気にデプロイできます。)


# 設定ステップ

## A -> B に SSH 接続する準備

1台の root ユーザーの SSH 鍵を生成。
Lsyncd は systemctl = root で起動するためです。
（ root ユーザーだというのに気づくのにハマっちゃいました。）

example.com をサーバーのホスト名に置き換えて実行してください。

```
$ sudo ssh-keygen -t ecdsa -b 521 -C root@example.com
```

公開鍵をゲット

```
$ sudo cat /root/.ssh/id_ecdsa.pub
```

2台目の EC2 に SSH 公開鍵を登録する。
2台目の受けは ec2-user とします。

```
$ echo "公開鍵" >> ~/.ssh/authorized_keys
```

1台目から2台目に SSH でログインできるか動作確認します。

2台目のローカルIPアドレス or DNS アドレスを取得して、SSHでつながるか確認します。繋がらない場合は、VPC の設定を確認しましょう。

```
$ sudo su -
$ ssh ec2-user@2台目のIP
```

これで接続の準備はできました。


## Lsyncd のインストール

以下はすべて、同期元の1台目での作業です。

### Epel のインストール

1台目（A) に
Amazon Linux Extras から epel をインストール（していない場合）

```
$ sudo amazon-linux-extras install epel
```


### Lsyncd をインストール

```
$ sudo yum install -y lsyncd
```

### Lsyncd の初期設定

lsyncd で初期設定、各同期の設定を記述します。

```
$ sudo vi /etc/lsyncd.conf
```

### Lsyncd config サンプル

Concrete CMS で冗長化構成をしているケースです。

1台目は管理者編集用、2台目は一般ユーザー向けとします。

1台目で、Concrete CMS の設定変更やアップデートをするときに生成される設定ファイルを2台目に同期するためのサンプルです。

2台目のIPを 10.0.0.2 、ユーザーを ec2-user と仮定します。同期するディレクトリは3つとします。

この設定は双方向同期を考慮していない設定ですので注意してください。


```
----
-- 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/
-- 
settings{
    -- Log location
    logfile = "/var/log/lsyncd/lsyncd.log",
    -- Status location
    statusFile = "/tmp/lsyncd.stat",
    -- Status update interval
    statusInterval = 1,
    -- Keep re-trying if failed connection
    insist         = 1,
}
sync{
    default.rsyncssh,
    -- source path
    source = "/var/www/vhosts/example.com/shared/application/config/doctrine/",
    -- target path
    host="ec2-user@10.0.0.2",
    targetdir="/var/www/vhosts/example.com/shared/application/config/doctrine/",
    -- Refrain from deletion upon startup
    delete = true,
    rsync = {
        archive = true,
        compress = true,
    }
}
sync{
    default.rsyncssh,
    -- source path
    source = "/var/www/vhosts/example.com/shared/application/config/generated_overrides/",
    -- target path
    host="ec2-user@10.0.0.2",
    targetdir="/var/www/vhosts/example.com/shared/application/config/generated_overrides/",
    -- Refrain from deletion upon startup
    delete = true,
    rsync = {
        archive = true,
        compress = true,
    }
}
sync{
    default.rsyncssh,
    -- source path
    source = "/var/www/vhosts/example.com/shared/application/languages/",
    -- target path
    host="ec2-user@10.0.0.2",
    targetdir="/var/www/vhosts/example.com/shared/application/languages/",
    -- Refrain from deletion upon startup
    delete = true,
    rsync = {
        archive = true,
        compress = true,
    }
}
sync {
    default.rsyncssh,
    -- source path
    source = "/var/www/vhosts/example.com/shared/",
    -- target path
    host="ec2-user@10.0.0.2",
    targetdir="/var/www/vhosts/example.com/shared/",
    -- Refraing deletion upon startup
    delete = true,
    rsync = {
        archive = true,
        compress = true,
		 _extra    = {
            "--include=sitemap.xml",
            "--exclude=*"
        }
    }
}
```

### Lsyncd を起動 & スタートアップ登録

```
$ sudo systemctl restart lsyncd
$ sudo systemctl enable lsyncd
$ sudo systemctl is-enabled lsyncd
$ sudo systemctl status lsyncd
```

別ウインドウでターミナルを開いて、tail コマンドで log ファイルを連続監視してみましょう。

```
$ tail -f /var/log/lsyncd/lsyncd.log
```

同期フォルダごとに以下のような「finished」という表示があれば成功しているはずです。

```
Thu Oct 27 16:00:00 2022 Normal: Startup of "/var/www/vhosts/example.com/shared/application/config/generated_overrides/" finished: 0
```


## 動作確認

前述の `$ tail -f /var/log/lsyncd/lsyncd.log` コマンドを走らせ続けながら、
空のテキストファイルを作成したり削除したりしましょう。


```
$ cd [同期元フォルダ]
$ touch synctest.txt
# 2台目を確認し、できていることを確認
$ rm synctest.txt
# 2台目を確認し、ファイルが削除されていることを確認。
```


## Logrotate を設定

放っておくとログファイルが肥大化しちゃうので、logrotate で定期的によろしく整理します。

```
$ sudo vi /etc/logrotate.d/lsyncd
```

週間で log rotate & 圧縮して、半年間保持

```
/var/log/lsyncd/*log {
        weekly
        rotate 26
        missingok
        notifempty
        compress
        sharedscripts
}
```

以上が、Lsyncd の設定方法手順でした。

最終的には、下記の公式マニュアルをみて各オプションを理解＆調整してくださいね。

-- 

# 参考

- [Lsyncd 公式マニュアル](https://lsyncd.github.io/lsyncd/) (英語)
- [lsyncdを使って2台のEC2間のファイルを双方向同期する](https://www.geekfeed.co.jp/geekblog/ec2-lsyncd/)